Index: trunk/CONTRIBUTION
===================================================================
--- trunk/CONTRIBUTION	(revision 6755)
+++ trunk/CONTRIBUTION	(revision 6756)
@@ -54,7 +54,7 @@
 is from Johan Montagnat and licensed with GPL.
 
-The JSON code (https://github.com/douglascrockford/JSON-java)
-is from Douglas Crockford and licensed as follows:
-"The Software shall be used for Good, not Evil."
+The JSON code (https://java.net/projects/jsonp/)
+is from Oracle (RI for JSR 353: Java API for JSON Processing) 
+and licensed with GPL / classpath exception.
 
 The opening hour validation uses code from opening_hour.js
@@ -67,6 +67,4 @@
 Some are originally LGPL but redistributed here under GPL. 
 
-The world image is from onearth.pl.
-
 The keyboard icon comes fom:
 - source: http://www.iconfinder.net/index.php?q=key&page=icondetails&iconid=8553&size=128&q=key&s12=on&s16=on&s22=on&s32=on&s48=on&s64=on&s128=on
Index: trunk/build.xml
===================================================================
--- trunk/build.xml	(revision 6755)
+++ trunk/build.xml	(revision 6756)
@@ -210,4 +210,7 @@
             <compilerarg value="-Xlint:unchecked"/>
         </javac>
+        <copy todir="build" failonerror="no" includeemptydirs="no">
+            <fileset dir="resources"/>
+        </copy>
     </target>
     <target name="init">
Index: trunk/resources/org/glassfish/json/messages.properties
===================================================================
--- trunk/resources/org/glassfish/json/messages.properties	(revision 6756)
+++ trunk/resources/org/glassfish/json/messages.properties	(revision 6756)
@@ -0,0 +1,41 @@
+parser.getString.err=JsonParser#getString() is valid only KEY_NAME, VALUE_STRING, VALUE_NUMBER parser states. \
+  But current parser state is {0}
+parser.isIntegralNumber.err=JsonParser#isIntegralNumber() is valid only VALUE_NUMBER parser state. \
+  But current parser state is {0}
+parser.getInt.err=JsonParser#getInt() is valid only VALUE_NUMBER parser state. \
+  But current parser state is {0}
+parser.getLong.err=JsonParser#getLong() is valid only VALUE_NUMBER parser state. \
+  But current parser state is {0}
+parser.getBigDecimal.err=JsonParser#getBigDecimal() is valid only VALUE_NUMBER parser state. \
+  But current parser state is {0}
+parser.expected.eof=Expected EOF token, but got {0}
+parser.tokenizer.close.io=I/O error while closing JSON tokenizer
+parser.invalid.token=Invalid token={0} at {1}. Expected tokens are: {2}
+
+generator.flush.io.err=I/O error while flushing generated JSON
+generator.close.io.err=I/O error while closing JsonGenerator
+generator.write.io.err=I/O error while writing in JsonGenerator
+generator.illegal.method=Illegal method during JSON generation, \
+  not valid in current context {0}
+generator.double.infinite.nan=double value cannot be Infinite or NaN
+generator.incomplete.json=Generating incomplete JSON
+generator.illegal.multiple.text=Cannot generate more than one JSON text
+
+writer.write.already.called=write/writeObject/writeArray/close method is already called
+
+reader.read.already.called=read/readObject/readArray/close method is already called
+reader.expected.array.got.object=Cannot read JSON array, found JSON object
+reader.expected.object.got.array=Cannot read JSON object, found JSON array
+
+objbuilder.name.null=Name in JsonObject's name/value pair cannot be null
+objbuilder.value.null=Value in JsonObject's name/value pair cannot be null
+objbuilder.object.builder.null=Object builder that is used to create a value in JsonObject's name/value pair cannot be null
+objbuilder.array.builder.null=Array builder that is used to create a value in JsonObject's name/value pair cannot be null
+
+arrbuilder.value.null=Cannot invoke add(null) while building JsonArray.
+arrbuilder.object.builder.null=Object builder that is used to add a value to JSON array cannot be null
+arrbuilder.array.builder.null=Array builder that is used to add a value to JSON array cannot be null
+
+tokenizer.unexpected.char=Unexpected char {0} at {1}
+tokenizer.expected.char=Unexpected char {0} at {1}, expecting ''{2}''
+tokenizer.io.err=I/O error while parsing JSON
Index: trunk/src/javax/json/Json.java
===================================================================
--- trunk/src/javax/json/Json.java	(revision 6756)
+++ trunk/src/javax/json/Json.java	(revision 6756)
@@ -0,0 +1,285 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import javax.json.spi.JsonProvider;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.*;
+import java.util.Map;
+
+/**
+ * Factory class for creating JSON processing objects.
+ * This class provides the most commonly used methods for creating these
+ * objects and their corresponding factories. The factory classes provide
+ * all the various ways to create these objects.
+ *
+ * <p>
+ * The methods in this class locate a provider instance using the method
+ * {@link JsonProvider#provider()}. This class uses the provider instance
+ * to create JSON processing objects.
+ *
+ * <p>
+ * The following example shows how to create a JSON parser to parse
+ * an empty array:
+ * <pre>
+ * <code>
+ * StringReader reader = new StringReader("[]");
+ * JsonParser parser = Json.createParser(reader);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public class Json {
+
+    private Json() {
+    }
+
+    /**
+     * Creates a JSON parser from a character stream.
+     *
+     * @param reader i/o reader from which JSON is to be read
+     * @return a JSON parser
+     */
+    public static JsonParser createParser(Reader reader) {
+        return JsonProvider.provider().createParser(reader);
+    }
+
+    /**
+     * Creates a JSON parser from a byte stream.
+     * The character encoding of the stream is determined as specified in 
+     * <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+     *
+     * @param in i/o stream from which JSON is to be read
+     * @throws JsonException if encoding cannot be determined
+     *         or i/o error (IOException would be cause of JsonException)
+     * @return a JSON parser
+     */
+    public static JsonParser createParser(InputStream in) {
+        return JsonProvider.provider().createParser(in);
+    }
+
+    /**
+     * Creates a JSON generator for writing JSON to a character stream.
+     *
+     * @param writer a i/o writer to which JSON is written
+     * @return a JSON generator
+     */
+    public static JsonGenerator createGenerator(Writer writer) {
+        return JsonProvider.provider().createGenerator(writer);
+    }
+
+    /**
+     * Creates a JSON generator for writing JSON to a byte stream.
+     *
+     * @param out i/o stream to which JSON is written
+     * @return a JSON generator
+     */
+    public static JsonGenerator createGenerator(OutputStream out) {
+        return JsonProvider.provider().createGenerator(out);
+    }
+
+    /**
+     * Creates a parser factory for creating {@link JsonParser} objects.
+     *
+     * @return JSON parser factory.
+     *
+    public static JsonParserFactory createParserFactory() {
+        return JsonProvider.provider().createParserFactory();
+    }
+     */
+
+    /**
+     * Creates a parser factory for creating {@link JsonParser} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON parsers. The map may be empty or null
+     * @return JSON parser factory
+     */
+    public static JsonParserFactory createParserFactory(Map<String, ?> config) {
+        return JsonProvider.provider().createParserFactory(config);
+    }
+
+    /**
+     * Creates a generator factory for creating {@link JsonGenerator} objects.
+     *
+     * @return JSON generator factory
+     *
+    public static JsonGeneratorFactory createGeneratorFactory() {
+        return JsonProvider.provider().createGeneratorFactory();
+    }
+    */
+
+    /**
+     * Creates a generator factory for creating {@link JsonGenerator} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON generators. The map may be empty or null
+     * @return JSON generator factory
+     */
+    public static JsonGeneratorFactory createGeneratorFactory(
+            Map<String, ?> config) {
+        return JsonProvider.provider().createGeneratorFactory(config);
+    }
+
+    /**
+     * Creates a JSON writer to write a
+     * JSON {@link JsonObject object} or {@link JsonArray array}
+     * structure to the specified character stream.
+     *
+     * @param writer to which JSON object or array is written
+     * @return a JSON writer
+     */
+    public static JsonWriter createWriter(Writer writer) {
+        return JsonProvider.provider().createWriter(writer);
+    }
+
+    /**
+     * Creates a JSON writer to write a
+     * JSON {@link JsonObject object} or {@link JsonArray array}
+     * structure to the specified byte stream. Characters written to
+     * the stream are encoded into bytes using UTF-8 encoding.
+     *
+     * @param out to which JSON object or array is written
+     * @return a JSON writer
+     */
+    public static JsonWriter createWriter(OutputStream out) {
+        return JsonProvider.provider().createWriter(out);
+    }
+
+    /**
+     * Creates a JSON reader from a character stream.
+     *
+     * @param reader a reader from which JSON is to be read
+     * @return a JSON reader
+     */
+    public static JsonReader createReader(Reader reader) {
+        return JsonProvider.provider().createReader(reader);
+    }
+
+    /**
+     * Creates a JSON reader from a byte stream. The character encoding of
+     * the stream is determined as described in
+     * <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+     *
+     * @param in a byte stream from which JSON is to be read
+     * @return a JSON reader
+     */
+    public static JsonReader createReader(InputStream in) {
+        return JsonProvider.provider().createReader(in);
+    }
+
+    /**
+     * Creates a reader factory for creating {@link JsonReader} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON readers. The map may be empty or null
+     * @return a JSON reader factory
+     */
+    public static JsonReaderFactory createReaderFactory(Map<String, ?> config) {
+        return JsonProvider.provider().createReaderFactory(config);
+    }
+
+    /**
+     * Creates a writer factory for creating {@link JsonWriter} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON writers. The map may be empty or null
+     * @return a JSON writer factory
+     */
+    public static JsonWriterFactory createWriterFactory(Map<String, ?> config) {
+        return JsonProvider.provider().createWriterFactory(config);
+    }
+
+    /**
+     * Creates a JSON array builder
+     *
+     * @return a JSON array builder
+     */
+    public static JsonArrayBuilder createArrayBuilder() {
+        return JsonProvider.provider().createArrayBuilder();
+    }
+
+    /**
+     * Creates a JSON object builder
+     *
+     * @return a JSON object builder
+     */
+    public static JsonObjectBuilder createObjectBuilder() {
+        return JsonProvider.provider().createObjectBuilder();
+    }
+
+    /**
+     * Creates a builder factory for creating {@link JsonArrayBuilder}
+     * and {@link JsonObjectBuilder} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON builders. The map may be empty or null
+     * @return a JSON builder factory
+     */
+    public static JsonBuilderFactory createBuilderFactory(
+            Map<String, ?> config) {
+        return JsonProvider.provider().createBuilderFactory(config);
+    }
+
+}
Index: trunk/src/javax/json/JsonArray.java
===================================================================
--- trunk/src/javax/json/JsonArray.java	(revision 6756)
+++ trunk/src/javax/json/JsonArray.java	(revision 6756)
@@ -0,0 +1,265 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.List;
+
+/**
+ * {@code JsonArray} represents an immutable JSON array
+ * (an ordered sequence of zero or more values).
+ * It also provides an unmodifiable list view of the values in the array.
+ *
+ * <p>A {@code JsonArray} object can be created by reading JSON data from
+ * an input source or it can be built from scratch using an array builder
+ * object.
+ *
+ * <p>The following example demonstrates how to create a {@code JsonArray}
+ * object from an input source using the method {@link JsonReader#readArray()}:
+ * <pre><code>
+ * JsonReader jsonReader = Json.createReader(...);
+ * JsonArray array = jsonReader.readArray();
+ * jsonReader.close();
+ * </code></pre>
+ *
+ * <p>The following example demonstrates how to build an empty JSON array
+ * using the class {@link JsonArrayBuilder}:
+ * <pre><code>
+ * JsonArray array = Json.createArrayBuilder().build();
+ * </code></pre>
+ *
+ * <p>The example code below demonstrates how to create the following JSON array:
+ * <pre><code>
+ * [
+ *     { "type": "home", "number": "212 555-1234" },
+ *     { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * </code></pre>
+ * <pre><code>
+ * JsonArray value = Json.createArrayBuilder()
+ *     .add(Json.createObjectBuilder()
+ *         .add("type", "home")
+ *         .add("number", "212 555-1234"))
+ *     .add(Json.createObjectBuilder()
+ *         .add("type", "fax")
+ *         .add("number", "646 555-4567"))
+ *     .build();
+ * </code></pre>
+ *
+ * <p>The following example demonstrates how to write a {@code JsonArray} object 
+ * as JSON data:
+ * <pre><code>
+ * JsonArray arr = ...;
+ * JsonWriter writer = Json.createWriter(...)
+ * writer.writeArray(arr);
+ * writer.close();
+ * </code></pre>
+ *
+ * <p>The values in a {@code JsonArray} can be of the following types:
+ * {@link JsonObject}, {@link JsonArray},
+ * {@link JsonString}, {@link JsonNumber}, {@link JsonValue#TRUE},
+ * {@link JsonValue#FALSE}, and {@link JsonValue#NULL}. 
+ * {@code JsonArray} provides various accessor methods to access the values
+ * in an array.
+ * 
+ * <p>The following example shows how to obtain the home phone number 
+ * "212 555-1234" from the array built in the previous example:
+ * <pre><code>
+ * JsonObject home = array.getJsonObject(0);
+ * String number = home.getString("number");
+ * </code></pre>
+ *
+ * <p>{@code JsonArray} instances are list objects that provide read-only 
+ * access to the values in the JSON array. Any attempt to modify the list,
+ * whether directly or using its collection views, results in an 
+ * {@code UnsupportedOperationException}.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonArray extends JsonStructure, List<JsonValue> {
+
+    /**
+     * Returns the object value at the specified position in this array.
+     * This is a convenience method for {@code (JsonObject)get(index)}.
+     *
+     * @param index index of the value to be returned
+     * @return the value at the specified position in this array
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to the JsonObject type
+     */
+    JsonObject getJsonObject(int index);
+
+    /**
+     * Returns the array value at the specified position in this array.
+     * This is a convenience method for {@code (JsonArray)get(index)}.
+     *
+     * @param index index of the value to be returned
+     * @return the value at the specified position in this array
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to the JsonArray type
+     */
+    JsonArray getJsonArray(int index);
+
+    /**
+     * Returns the number value at the specified position in this array.
+     * This is a convenience method for {@code (JsonNumber)get(index)}.
+     *
+     * @param index index of the value to be returned
+     * @return the value at the specified position in this array
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to the JsonNumber type
+     */
+    JsonNumber getJsonNumber(int index);
+
+    /**
+     * Returns the string value at ths specified position in this array.
+     * This is a convenience method for {@code (JsonString)get(index)}.
+     *
+     * @param index index of the value to be returned
+     * @return the value at the specified position in this array
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to the JsonString type
+     */
+    JsonString getJsonString(int index);
+
+    /**
+     * Returns a list a view of the specified type for the array. This method
+     * does not verify if there is a value of wrong type in the array. Providing
+     * this typesafe view dynamically may cause a program fail with a
+     * {@code ClassCastException}, if there is a value of wrong type in this
+     * array. Unfortunately, the exception can occur at any time after this
+     * method returns.
+     *
+     * @param clazz a JsonValue type
+     * @return a list view of the  specified type
+     */
+    <T extends JsonValue> List<T> getValuesAs(Class<T> clazz);
+
+    /**
+     * A convenience method for
+     * {@code getJsonString(index).getString()}.
+     *
+     * @param index index of the {@code JsonString} value
+     * @return the String value at the specified position
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to {@code JsonString}
+     */
+    String getString(int index);
+
+    /**
+     * Returns the {@code String} value of {@code JsonString} at the specified
+     * position in this JSON array values. If {@code JsonString} is found,
+     * its {@link javax.json.JsonString#getString()} is returned. Otherwise,
+     * the specified default value is returned.
+     *
+     * @param index index of the JsonString value
+     * @return the String value at the specified position in this array,
+     * or the specified default value
+     */
+    String getString(int index, String defaultValue);
+
+    /**
+     * A convenience method for
+     * {@code getJsonNumber(index).intValue()}.
+     *
+     * @param index index of the {@code JsonNumber} value
+     * @return the int value at the specified position
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to {@code JsonNumber}
+     */
+    int getInt(int index);
+
+    /**
+     * Returns the int value of the {@code JsonNumber} at the specified position. 
+     * If the value at that position is a {@code JsonNumber},
+     * this method returns {@link javax.json.JsonNumber#intValue()}. Otherwise
+     * this method returns the specified default value.
+     *
+     * @param index index of the {@code JsonNumber} value
+     * @return the int value at the specified position in this array,
+     * or the specified default value
+     */
+    int getInt(int index, int defaultValue);
+
+    /**
+     * Returns the boolean value at the specified position.
+     * If the value at the specified position is {@code JsonValue.TRUE} 
+     * this method returns {@code true}. If the value at the specified position 
+     * is {@code JsonValue.FALSE} this method returns {@code false}.
+     *
+     * @param index index of the JSON boolean value
+     * @return the boolean value at the specified position
+     * @throws IndexOutOfBoundsException if the index is out of range
+     * @throws ClassCastException if the value at the specified position is not
+     * assignable to {@code JsonValue.TRUE} or {@code JsonValue.FALSE}
+     */
+    boolean getBoolean(int index);
+
+    /**
+     * Returns the boolean value at the specified position.
+     * If the value at the specified position is {@code JsonValue.TRUE}
+     * this method returns {@code true}. If the value at the specified position 
+     * is {@code JsonValue.FALSE} this method returns {@code false}. 
+     * Otherwise this method returns the specified default value.
+     *
+     * @param index index of the JSON boolean value
+     * @return the boolean value at the specified position,
+     * or the specified default value
+     */
+    boolean getBoolean(int index, boolean defaultValue);
+
+    /**
+     * Returns {@code true} if the value at the specified location in this
+     * array is {@code JsonValue.NULL}.
+     *
+     * @param index index of the JSON null value
+     * @return return true if the value at the specified location is
+     * {@code JsonValue.NUL}, otherwise false
+     * @throws IndexOutOfBoundsException if the index is out of range
+     */
+    boolean isNull(int index);
+
+}
Index: trunk/src/javax/json/JsonArrayBuilder.java
===================================================================
--- trunk/src/javax/json/JsonArrayBuilder.java	(revision 6756)
+++ trunk/src/javax/json/JsonArrayBuilder.java	(revision 6756)
@@ -0,0 +1,216 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A builder for creating {@link JsonArray} models from scratch. This
+ * interface initializes an empty JSON array model and provides methods to add
+ * values to the array model and to return the resulting array. The methods
+ * in this class can be chained to add multiple values to the array.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create the builder
+ * object. The example code below shows how to build an empty {@code JsonArray}
+ * instance.
+ * <pre>
+ * <code>
+ * JsonArray array = Json.createArrayBuilder().build();
+ * </code>
+ * </pre>
+ *
+ * <p>The class {@link JsonBuilderFactory} also contains methods to create
+ * {@code JsonArrayBuilder} instances. A factory instance can be used to create
+ * multiple builder instances with the same configuration. This the preferred
+ * way to create multiple instances.
+ *
+ * <a id="JsonArrayBuilderExample1"/>
+ * The example code below shows how to build a {@code JsonArray} object
+ * that represents the following JSON array:
+ *
+ * <pre>
+ * <code>
+ * [
+ *     { "type": "home", "number": "212 555-1234" },
+ *     { "type": "fax", "number": "646 555-4567" }
+ * ]
+ * </code>
+ * </pre>
+ *
+ * <p>The following code creates the JSON array above:
+ *
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(config);
+ * JsonArray value = factory.createArrayBuilder()
+ *     .add(factory.createObjectBuilder()
+ *         .add("type", "home")
+ *         .add("number", "212 555-1234"))
+ *     .add(factory.createObjectBuilder()
+ *         .add("type", "fax")
+ *         .add("number", "646 555-4567"))
+ *     .build();
+ * </code>
+ * </pre>
+ *
+ * <p>This class does <em>not</em> allow <tt>null</tt> to be used as a
+ * value while building the JSON array
+ *
+ * @see JsonObjectBuilder
+ */
+public interface JsonArrayBuilder {
+
+    /**
+     * Adds a value to the array.
+     *
+     * @param value the JSON value
+     * @return this array builder
+     * @throws NullPointerException if the specified value is null
+     */
+    JsonArrayBuilder add(JsonValue value);
+
+    /**
+     * Adds a value to the array as a {@link JsonString}.
+     *
+     * @param value the string value
+     * @return this array builder
+     * @throws NullPointerException if the specified value is null
+     */
+    JsonArrayBuilder add(String value);
+
+    /**
+     * Adds a value to the array as a {@link JsonNumber}.
+     *
+     * @param value the number value
+     * @return this array builder
+     * @throws NullPointerException if the specified value is null
+     *
+     * @see JsonNumber
+     */
+    JsonArrayBuilder add(BigDecimal value);
+
+    /**
+     * Adds a value to the array as a {@link JsonNumber}.
+     *
+     * @param value the number value
+     * @return this array builder
+     * @throws NullPointerException if the specified value is null
+     *
+     * @see JsonNumber
+     */
+    JsonArrayBuilder add(BigInteger value);
+
+    /**
+     * Adds a value to the array as a {@link JsonNumber}.
+     *
+     * @param value the number value
+     * @return this array builder
+     *
+     * @see JsonNumber
+     */
+    JsonArrayBuilder add(int value);
+
+    /**
+     * Adds a value to the array as a {@link JsonNumber}.
+     *
+     * @param value the number value
+     * @return this array builder
+     *
+     * @see JsonNumber
+     */
+    JsonArrayBuilder add(long value);
+
+    /**
+     * Adds a value to the array as a {@link JsonNumber}.
+     *
+     * @param value the number value
+     * @return this array builder
+     * @throws NumberFormatException if the value is Not-a-Number(NaN) or 
+     *      infinity
+     *
+     * @see JsonNumber
+     */
+    JsonArrayBuilder add(double value);
+
+    /**
+     * Adds a {@link JsonValue#TRUE}  or {@link JsonValue#FALSE} value to the
+     * array.
+     *
+     * @param value the boolean value
+     * @return this array builder
+     */
+    JsonArrayBuilder add(boolean value);
+
+    /**
+     * Adds a {@link JsonValue#NULL} value to the array.
+     *
+     * @return this array builder
+     */
+    JsonArrayBuilder addNull();
+
+    /**
+     * Adds a {@link JsonObject} from an object builder to the array.
+     *
+     * @param builder the object builder
+     * @return this array builder
+     * @throws NullPointerException if the specified builder is null
+     */
+    JsonArrayBuilder add(JsonObjectBuilder builder);
+
+    /**
+     * Adds a {@link JsonArray} from an array builder to the array.
+     *
+     * @param builder the array builder
+     * @return this array builder
+     * @throws NullPointerException if the specified builder is null
+     */
+    JsonArrayBuilder add(JsonArrayBuilder builder);
+
+    /**
+     * Returns the current array.
+     *
+     * @return the current JSON array
+     */
+    JsonArray build();
+
+}
+
Index: trunk/src/javax/json/JsonBuilderFactory.java
===================================================================
--- trunk/src/javax/json/JsonBuilderFactory.java	(revision 6756)
+++ trunk/src/javax/json/JsonBuilderFactory.java	(revision 6756)
@@ -0,0 +1,105 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.Map;
+
+/**
+ * Factory to create {@link JsonObjectBuilder} and {@link JsonArrayBuilder}
+ * instances. If a factory instance is configured with some configuration,
+ * that would be used to configure the created builder instances.
+ *
+ * <p>
+ * {@code JsonObjectBuilder} and {@code JsonArrayBuilder} can also be created
+ * using {@link Json}'s methods. If multiple builder instances are created,
+ * then creating them using a builder factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(...);
+ * JsonArray value = factory.createArrayBuilder()
+ *     .add(factory.createObjectBuilder()
+ *         .add("type", "home")
+ *         .add("number", "212 555-1234"))
+ *     .add(factory.createObjectBuilder()
+ *         .add("type", "fax")
+ *         .add("number", "646 555-4567"))
+ *     .build();
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonBuilderFactory {
+
+    /**
+     * Creates a {@code JsonObjectBuilder} instance that is used to build
+     * {@link JsonObject}.
+     *
+     * @return a JSON object builder
+     */
+    JsonObjectBuilder createObjectBuilder();
+
+    /**
+     * Creates a {@code JsonArrayBuilder} instance that is used to build
+     * {@link JsonArray}
+     *
+     * @return a JSON array builder
+     */
+    JsonArrayBuilder createArrayBuilder();
+
+    /**
+     * Returns read-only map of supported provider specific configuration
+     * properties that are used to configure the created JSON builders.
+     * If there are any specified configuration properties that are not
+     * supported by the provider, they won't be part of the returned map.
+     *
+     * @return a map of supported provider specific properties that are used
+     * to configure the builders. The map be empty but not null.
+     */
+    Map<String, ?> getConfigInUse();
+
+}
Index: trunk/src/javax/json/JsonException.java
===================================================================
--- trunk/src/javax/json/JsonException.java	(revision 6756)
+++ trunk/src/javax/json/JsonException.java	(revision 6756)
@@ -0,0 +1,81 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * <code>JsonException</code> indicates that some exception happened during
+ * JSON processing.
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonException extends RuntimeException {
+
+    /**
+     * Constructs a new runtime exception with the specified detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     *
+     * @param message the detail message. The detail message is saved for
+     *          later retrieval by the {@link #getMessage()} method.
+     */
+    public JsonException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new runtime exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this runtime exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *         by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *         {@link #getCause()} method). (A <tt>null</tt> value is
+     *         permitted, and indicates that the cause is nonexistent or
+     *         unknown.)
+     */
+    public JsonException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
+
Index: trunk/src/javax/json/JsonNumber.java
===================================================================
--- trunk/src/javax/json/JsonNumber.java	(revision 6756)
+++ trunk/src/javax/json/JsonNumber.java	(revision 6756)
@@ -0,0 +1,201 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * An immutable JSON number value.
+ *
+ * <p>
+ * Implementations may use a {@link BigDecimal} object to store the numeric
+ * value internally.
+ * The {@code BigDecimal} object can be constructed from the following types:
+ * {@link BigDecimal#BigDecimal(int) <code>int</code>},
+ * {@link BigDecimal#BigDecimal(long) <code>long</code>},
+ * {@link BigDecimal#BigDecimal(BigInteger) <code>BigInteger</code>},
+ * {@link BigDecimal#valueOf(double) <code>double</code>}, and
+ * {@link BigDecimal#BigDecimal(String) <code>String</code>}.
+ * Some of the method semantics in this class are defined using the
+ * {@code BigDecimal} semantics.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonNumber extends JsonValue {
+
+    /**
+     * Returns true if this JSON number is a integral number. This method
+     * semantics are defined using {@code bigDecimalValue().scale()}. If the
+     * scale is zero, then it is considered integral type. This integral type
+     * information can be used to invoke an appropriate accessor method to
+     * obtain a numeric value as in the following example:
+     *
+     * <pre>
+     * <code>
+     * JsonNumber num = ...
+     * if (num.isIntegral()) {
+     *     num.longValue();     // or other methods to get integral value
+     * } else {
+     *     num.doubleValue();   // or other methods to get decimal number value
+     * }
+     * </code>
+     * </pre>
+     *
+     * @return true if this number is a integral number, otherwise false
+     */
+    boolean isIntegral();
+
+    /**
+     * Returns this JSON number as an {@code int}. Note that this conversion
+     * can lose information about the overall magnitude and precision of the
+     * number value as well as return a result with the opposite sign.
+     *
+     * @return an {@code int} representation of the JSON number
+     * @see java.math.BigDecimal#intValue()
+     */
+    int intValue();
+
+    /**
+     * Returns this JSON number as an {@code int}.
+     *
+     * @return an {@code int} representation of the JSON number
+     * @throws ArithmeticException if the number has a nonzero fractional
+     *         part or if it does not fit in an {@code int}
+     * @see java.math.BigDecimal#intValueExact()
+     */
+    int intValueExact();
+
+    /**
+     * Returns this JSON number as a {@code long}. Note that this conversion
+     * can lose information about the overall magnitude and precision of the
+     * number value as well as return a result with the opposite sign.
+     *
+     * @return a {@code long} representation of the JSON number.
+     * @see java.math.BigDecimal#longValue()
+     */
+    long longValue();
+
+    /**
+     * Returns this JSON number as a {@code long}.
+     *
+     * @return a {@code long} representation of the JSON number
+     * @throws ArithmeticException if the number has a non-zero fractional
+     *         part or if it does not fit in a {@code long}
+     * @see java.math.BigDecimal#longValueExact()
+     */
+    long longValueExact();
+
+    /**
+     * Returns this JSON number as a {@link BigInteger} object. This is a
+     * a convenience method for {@code bigDecimalValue().toBigInteger()}.
+     * Note that this conversion can lose information about the overall
+     * magnitude and precision of the number value as well as return a result
+     * with the opposite sign.
+     *
+     * @return a {@code BigInteger} representation of the JSON number.
+     * @see java.math.BigDecimal#toBigInteger()
+     */
+    BigInteger bigIntegerValue();
+
+    /**
+     * Returns this JSON number as a {@link BigDecimal} object. This is a
+     * convenience method for {@code bigDecimalValue().toBigIntegerExact()}.
+     *
+     * @return a {@link BigInteger} representation of the JSON number
+     * @throws ArithmeticException if the number has a nonzero fractional part
+     * @see java.math.BigDecimal#toBigIntegerExact()
+     */
+    BigInteger bigIntegerValueExact();
+
+    /**
+     * Returns this JSON number as a {@code double}. This is a
+     * a convenience method for {@code bigDecimalValue().doubleValue()}.
+     * Note that this conversion can lose information about the overall
+     * magnitude and precision of the number value as well as return a result
+     * with the opposite sign.
+     *
+     * @return a {@code double} representation of the JSON number
+     * @see java.math.BigDecimal#doubleValue()
+     */
+    double doubleValue();
+
+    /**
+     * Returns this JSON number as a {@link BigDecimal} object.
+     *
+     * @return a {@link BigDecimal} representation of the JSON number
+     */
+    BigDecimal bigDecimalValue();
+
+    /**
+     * Returns a JSON text representation of the JSON number. The
+     * representation is equivalent to {@link BigDecimal#toString()}.
+     *
+     * @return JSON text representation of the number
+     */
+    @Override
+    String toString();
+
+    /**
+     * Compares the specified object with this {@code JsonNumber} object for
+     * equality. Returns {@code true} if and only if the type of the specified
+     * object is also {@code JsonNumber} and their {@link #bigDecimalValue()}
+     * objects are <i>equal</i>
+     *
+     * @param obj the object to be compared for equality with 
+     *      this {@code JsonNumber}
+     * @return {@code true} if the specified object is equal to this 
+     *      {@code JsonNumber}
+     */
+    @Override
+    boolean equals(Object obj);
+
+    /**
+     * Returns the hash code value for this {@code JsonNumber} object.  The
+     * hash code of a {@code JsonNumber} object is defined as the hash code of
+     * its {@link #bigDecimalValue()} object.
+     *
+     * @return the hash code value for this {@code JsonNumber} object
+     */
+    @Override
+    int hashCode();
+
+}
Index: trunk/src/javax/json/JsonObject.java
===================================================================
--- trunk/src/javax/json/JsonObject.java	(revision 6756)
+++ trunk/src/javax/json/JsonObject.java	(revision 6756)
@@ -0,0 +1,275 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.util.Map;
+
+/**
+ * {@code JsonObject} class represents an immutable JSON object value
+ * (an unordered collection of zero or more name/value pairs).
+ * It also provides unmodifiable map view to the JSON object
+ * name/value mappings.
+ *
+ * <p>A JsonObject instance can be created from an input source using
+ * {@link JsonReader#readObject()}. For example:
+ * <pre><code>
+ * JsonReader jsonReader = Json.createReader(...);
+ * JsonObject object = jsonReader.readObject();
+ * jsonReader.close();
+ * </code></pre>
+ *
+ * It can also be built from scratch using a {@link JsonObjectBuilder}.
+ *
+ * <p>For example 1: An empty JSON object can be built as follows:
+ * <pre><code>
+ * JsonObject object = Json.createObjectBuilder().build();
+ * </code></pre>
+ *
+ * For example 2: The following JSON
+ * <pre><code>
+ * {
+ *     "firstName": "John", "lastName": "Smith", "age": 25,
+ *     "address" : {
+ *         "streetAddress": "21 2nd Street",
+ *         "city": "New York",
+ *         "state": "NY",
+ *         "postalCode": "10021"
+ *     },
+ *     "phoneNumber": [
+ *         { "type": "home", "number": "212 555-1234" },
+ *         { "type": "fax", "number": "646 555-4567" }
+ *     ]
+ * }
+ * </code></pre>
+ * can be built using :
+ * <pre><code>
+ * JsonObject value = Json.createObjectBuilder()
+ *     .add("firstName", "John")
+ *     .add("lastName", "Smith")
+ *     .add("age", 25)
+ *     .add("address", Json.createObjectBuilder()
+ *         .add("streetAddress", "21 2nd Street")
+ *         .add("city", "New York")
+ *         .add("state", "NY")
+ *         .add("postalCode", "10021"))
+ *     .add("phoneNumber", Json.createArrayBuilder()
+ *         .add(Json.createObjectBuilder()
+ *             .add("type", "home")
+ *             .add("number", "212 555-1234"))
+ *         .add(Json.createObjectBuilder()
+ *             .add("type", "fax")
+ *             .add("number", "646 555-4567")))
+ *     .build();
+ * </code></pre>
+ *
+ * {@code JsonObject} can be written to JSON as follows:
+ * <pre><code>
+ * JsonWriter writer = ...
+ * JsonObject obj = ...;
+ * writer.writeObject(obj);
+ * </code></pre>
+ *
+ * {@code JsonObject} values can be {@link JsonObject}, {@link JsonArray},
+ * {@link JsonString}, {@link JsonNumber}, {@link JsonValue#TRUE},
+ * {@link JsonValue#FALSE}, {@link JsonValue#NULL}. These values can be
+ * accessed using various accessor methods.
+ *
+ * <p>In the above example 2, "John" can be got using
+ * <pre><code>
+ * String firstName = object.getString("firstName");
+ * </code></pre>
+ *
+ * This map object provides read-only access to the JSON object data,
+ * and attempts to modify the map, whether direct or via its collection
+ * views, result in an {@code UnsupportedOperationException}.
+ *
+ * <p>The map object's iteration ordering is based on the order in which
+ * name/value pairs are added to the corresponding builder or the order
+ * in which name/value pairs appear in the corresponding stream.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonObject extends JsonStructure, Map<String, JsonValue> {
+
+    /**
+     * Returns the array value to which the specified name is mapped.
+     * This is a convenience method for {@code (JsonArray)get(name)} to
+     * get the value.
+     *
+     * @param name the name whose associated value is to be returned
+     * @return the array value to which the specified name is mapped, or
+     *         {@code null} if this object contains no mapping for the name
+     * @throws ClassCastException if the value to which the specified name
+     * is mapped is not assignable to JsonArray type
+     */
+    JsonArray getJsonArray(String name);
+
+    /**
+     * Returns the object value to which the specified name is mapped.
+     * This is a convenience method for {@code (JsonObject)get(name)} to
+     * get the value.
+     *
+     * @param name the name whose associated value is to be returned
+     * @return the object value to which the specified name is mapped, or
+     *         {@code null} if this object contains no mapping for the name
+     * @throws ClassCastException if the value to which the specified name
+     * is mapped is not assignable to JsonObject type
+     */
+    JsonObject getJsonObject(String name);
+
+    /**
+     * Returns the number value to which the specified name is mapped.
+     * This is a convenience method for {@code (JsonNumber)get(name)} to
+     * get the value.
+     *
+     * @param name the name whose associated value is to be returned
+     * @return the number value to which the specified name is mapped, or
+     *         {@code null} if this object contains no mapping for the name
+     * @throws ClassCastException if the value to which the specified name
+     * is mapped is not assignable to JsonNumber type
+     */
+    JsonNumber getJsonNumber(String name);
+
+    /**
+     * Returns the string value to which the specified name is mapped.
+     * This is a convenience method for {@code (JsonString)get(name)} to
+     * get the value.
+     *
+     * @param name the name whose associated value is to be returned
+     * @return the string value to which the specified name is mapped, or
+     *         {@code null} if this object contains no mapping for the name
+     * @throws ClassCastException if the value to which the specified name
+     * is mapped is not assignable to JsonString type
+     */
+    JsonString getJsonString(String name);
+
+    /**
+     * A convenience method for
+     * {@code getJsonString(name).getString()}
+     *
+     * @param name whose associated value is to be returned as String
+     * @return the String value to which the specified name is mapped
+     * @throws NullPointerException if the specified name doesn't have any
+     * mapping
+     * @throws ClassCastException if the value for specified name mapping
+     * is not assignable to JsonString
+     */
+    String getString(String name);
+
+    /**
+     * Returns the string value of the associated {@code JsonString} mapping
+     * for the specified name. If {@code JsonString} is found, then its
+     * {@link javax.json.JsonString#getString()} is returned. Otherwise,
+     * the specified default value is returned.
+     *
+     * @param name whose associated value is to be returned as String
+     * @param defaultValue a default value to be returned
+     * @return the string value of the associated mapping for the name,
+     * or the default value
+     */
+    String getString(String name, String defaultValue);
+
+    /**
+     * A convenience method for
+     * {@code getJsonNumber(name).intValue()}
+     *
+     * @param name whose associated value is to be returned as int
+     * @return the int value to which the specified name is mapped
+     * @throws NullPointerException if the specified name doesn't have any
+     * mapping
+     * @throws ClassCastException if the value for specified name mapping
+     * is not assignable to JsonNumber
+     */
+    int getInt(String name);
+
+    /**
+     * Returns the int value of the associated {@code JsonNumber} mapping
+     * for the specified name. If {@code JsonNumber} is found, then its
+     * {@link javax.json.JsonNumber#intValue()} is returned. Otherwise,
+     * the specified default value is returned.
+     *
+     * @param name whose associated value is to be returned as int
+     * @param defaultValue a default value to be returned
+     * @return the int value of the associated mapping for the name,
+     * or the default value
+     */
+    int getInt(String name, int defaultValue);
+
+    /**
+     * Returns the boolean value of the associated mapping for the specified
+     * name. If the associated mapping is JsonValue.TRUE, then returns true.
+     * If the associated mapping is JsonValue.FALSE, then returns false.
+     *
+     * @param name whose associated value is to be returned as boolean
+     * @return the boolean value to which the specified name is mapped
+     * @throws NullPointerException if the specified name doesn't have any
+     * mapping
+     * @throws ClassCastException if the value for specified name mapping
+     * is not assignable to JsonValue.TRUE or JsonValue.FALSE
+     */
+    boolean getBoolean(String name);
+
+    /**
+     * Returns the boolean value of the associated mapping for the specified
+     * name. If the associated mapping is JsonValue.TRUE, then returns true.
+     * If the associated mapping is JsonValue.FALSE, then returns false.
+     * Otherwise, the specified default value is returned.
+     *
+     * @param name whose associated value is to be returned as int
+     * @param defaultValue a default value to be returned
+     * @return the boolean value of the associated mapping for the name,
+     * or the default value
+     */
+    boolean getBoolean(String name, boolean defaultValue);
+
+    /**
+     * Returns {@code true} if the associated value for the specified name is
+     * {@code JsonValue.NULL}.
+     *
+     * @param name name whose associated value is checked
+     * @return return true if the associated value is {@code JsonValue.NUL},
+     * otherwise false
+     * @throws NullPointerException if the specified name doesn't have any
+     * mapping
+     */
+    boolean isNull(String name);
+
+}
Index: trunk/src/javax/json/JsonObjectBuilder.java
===================================================================
--- trunk/src/javax/json/JsonObjectBuilder.java	(revision 6756)
+++ trunk/src/javax/json/JsonObjectBuilder.java	(revision 6756)
@@ -0,0 +1,280 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * A builder for creating {@link JsonObject} models from scratch. This
+ * interface initializes an empty JSON object model and provides methods to add
+ * name/value pairs to the object model and to return the resulting object.
+ * The methods in this class can be chained to add multiple name/value pairs
+ * to the object.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create the builder
+ * object. The example code below shows how to build an empty {@code JsonObject}
+ * instance.
+ * <pre>
+ * <code>
+ * JsonObject object = Json.createObjectBuilder().build();
+ * </code>
+ * </pre>
+ *
+ * <p>The class {@link JsonBuilderFactory} also contains methods to create
+ * {@code JsonObjectBuilder} instances. A factory instance can be used to create
+ * multiple builder instances with the same configuration. This the preferred
+ * way to create multiple instances.
+ *
+ * <a id="JsonObjectBuilderExample1"/>
+ * The example code below shows how to build a {@code JsonObject} model that
+ * represents the following JSON object:
+ *
+ * <pre>
+ * <code>
+ * {
+ *     "firstName": "John", "lastName": "Smith", "age": 25,
+ *     "address" : {
+ *         "streetAddress": "21 2nd Street",
+ *         "city": "New York",
+ *         "state": "NY",
+ *         "postalCode": "10021"
+ *     },
+ *     "phoneNumber": [
+ *         { "type": "home", "number": "212 555-1234" },
+ *         { "type": "fax", "number": "646 555-4567" }
+ *     ]
+ * }
+ * </code>
+ * </pre>
+ *
+ * <p>The code to create the object shown above is the following:
+ *
+ * <pre>
+ * <code>
+ * JsonBuilderFactory factory = Json.createBuilderFactory(config);
+ * JsonObject value = factory.createObjectBuilder()
+ *     .add("firstName", "John")
+ *     .add("lastName", "Smith")
+ *     .add("age", 25)
+ *     .add("address", factory.createObjectBuilder()
+ *         .add("streetAddress", "21 2nd Street")
+ *         .add("city", "New York")
+ *         .add("state", "NY")
+ *         .add("postalCode", "10021"))
+ *     .add("phoneNumber", factory.createArrayBuilder()
+ *         .add(factory.createObjectBuilder()
+ *             .add("type", "home")
+ *             .add("number", "212 555-1234"))
+ *         .add(factory.createObjectBuilder()
+ *             .add("type", "fax")
+ *             .add("number", "646 555-4567")))
+ *     .build();
+ * </code>
+ * </pre>
+ *
+ * <p>This class does <em>not</em> allow <tt>null</tt> to be used as a name or
+ * value while building the JSON object
+ *
+ * @see JsonArrayBuilder
+ */
+public interface JsonObjectBuilder {
+
+    /**
+     * Adds a name/{@code JsonValue} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name or value is null
+     */
+    JsonObjectBuilder add(String name, JsonValue value);
+
+    /**
+     * Adds a name/{@code JsonString} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name or value is null
+     */
+    JsonObjectBuilder add(String name, String value);
+
+    /**
+     * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name or value is null
+     *
+     * @see JsonNumber
+     */
+    JsonObjectBuilder add(String name, BigInteger value);
+
+    /**
+     * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name or value is null
+     *
+     * @see JsonNumber
+     */
+    JsonObjectBuilder add(String name, BigDecimal value);
+
+    /**
+     * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name is null
+     *
+     * @see JsonNumber
+     */
+    JsonObjectBuilder add(String name, int value);
+
+    /**
+     * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name is null
+     *
+     * @see JsonNumber
+     */
+    JsonObjectBuilder add(String name, long value);
+
+    /**
+     * Adds a name/{@code JsonNumber} pair to the JSON object associated with
+     * this object builder. If the object contains a mapping for the specified
+     * name, this method replaces the old value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NumberFormatException if the value is Not-a-Number(NaN) or 
+     * infinity
+     * @throws NullPointerException if the specified name is null
+     *
+     * @see JsonNumber
+     */
+    JsonObjectBuilder add(String name, double value);
+
+    /**
+     * Adds a name/{@code JsonValue#TRUE} or name/{@code JsonValue#FALSE} pair
+     * to the JSON object associated with this object builder. If the object
+     * contains a mapping for the specified name, this method replaces the old
+     * value with the specified value.
+     *
+     * @param name name in the name/value pair
+     * @param value value in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name is null
+     */
+    JsonObjectBuilder add(String name, boolean value);
+
+    /**
+     * Adds a name/{@code JsonValue#NULL} pair to the JSON object associated
+     * with this object builder where the value is {@code null}.
+     * If the object contains a mapping for the specified name, this method
+     * replaces the old value with {@code null}.
+     *
+     * @param name name in the name/value pair
+     * @return this object builder
+     * @throws NullPointerException if the specified name is null
+     */
+    JsonObjectBuilder addNull(String name);
+
+    /**
+     * Adds a name/{@code JsonObject} pair to the JSON object associated
+     * with this object builder. The value {@code JsonObject} is built from the
+     * specified object builder. If the object contains a mapping for the
+     * specified name, this method replaces the old value with the
+     * {@code JsonObject} from the specified object builder.
+     *
+     * @param name name in the name/value pair
+     * @param builder the value is the object associated with this builder
+     * @return this object builder
+     * @throws NullPointerException if the specified name or builder is null
+     */
+    JsonObjectBuilder add(String name, JsonObjectBuilder builder);
+
+    /**
+     * Adds a name/{@code JsonArray} pair to the JSON object associated with
+     * this object builder. The value {@code JsonArray} is built from the
+     * specified array builder. If the object contains a mapping for the
+     * specified name, this method replaces the old value with the
+     * {@code JsonArray} from the specified array builder.
+     *
+     * @param name the name in the name/value pair
+     * @param builder the value is the object array with this builder
+     * @return this object builder
+     * @throws NullPointerException if the specified name or builder is null
+     */
+    JsonObjectBuilder add(String name, JsonArrayBuilder builder);
+
+    /**
+     * Returns the JSON object associated with this object builder. 
+     * The iteration order for the {@code JsonObject} is based
+     * on the order in which name/value pairs are added to the object using
+     * this builder.
+     *
+     * @return JSON object that is being built
+     */
+    JsonObject build();
+
+}
Index: trunk/src/javax/json/JsonReader.java
===================================================================
--- trunk/src/javax/json/JsonReader.java	(revision 6756)
+++ trunk/src/javax/json/JsonReader.java	(revision 6756)
@@ -0,0 +1,140 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.Closeable;
+
+/**
+ * Reads a JSON {@link JsonObject object} or an {@link JsonArray array}
+ * structure from an input source.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create readers from
+ * input sources ({@link java.io.InputStream} and {@link java.io.Reader}).
+ *
+ * <p>
+ * <a id="JsonReaderExample1"/>
+ * The following example demonstrates how to read an empty JSON array from
+ * a string:
+ * <pre>
+ * <code>
+ * JsonReader jsonReader = Json.createReader(new StringReader("[]"));
+ * JsonArray array = jsonReader.readArray();
+ * jsonReader.close();
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonReaderFactory} also contains methods to create
+ * {@code JsonReader} instances. A factory instance can be used to create
+ * multiple reader instances with the same configuration. This the preferred
+ * way to create multiple instances. A sample usage is shown in the following
+ * example:
+ * <pre>
+ * <code>
+ * JsonReaderFactory factory = Json.createReaderFactory(config);
+ * JsonReader reader1 = factory.createReader(...);
+ * JsonReader reader2 = factory.createReader(...);
+ * </code>
+ * </pre>
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonReader extends  /*Auto*/Closeable {
+
+    /**
+     * Returns a JSON array or object that is represented in
+     * the input source. This method needs to be called
+     * only once for a reader instance.
+     *
+     * @return a JSON object or array
+     * @throws JsonException if a JSON object or array cannot
+     *     be created due to i/o error (IOException would be
+     * cause of JsonException)
+     * @throws javax.json.stream.JsonParsingException if a JSON object or array
+     *     cannot be created due to incorrect representation
+     * @throws IllegalStateException if read, readObject, readArray or
+     *     close method is already called
+     */
+    JsonStructure read();
+
+    /**
+     * Returns a JSON object that is represented in
+     * the input source. This method needs to be called
+     * only once for a reader instance.
+     *
+     * @return a JSON object
+     * @throws JsonException if a JSON object cannot
+     *     be created due to i/o error (IOException would be
+     *     cause of JsonException)
+     * @throws javax.json.stream.JsonParsingException if a JSON object cannot
+     *     be created due to incorrect representation
+     * @throws IllegalStateException if read, readObject, readArray or
+     *     close method is already called
+     */
+    JsonObject readObject();
+
+    /**
+     * Returns a JSON array that is represented in
+     * the input source. This method needs to be called
+     * only once for a reader instance.
+     *
+     * @return a JSON array
+     * @throws JsonException if a JSON array cannot
+     *     be created due to i/o error (IOException would be
+     *     cause of JsonException)
+     * @throws javax.json.stream.JsonParsingException if a JSON array cannot
+     *     be created due to incorrect representation
+     * @throws IllegalStateException if read, readObject, readArray or
+     *     close method is already called
+     */
+    JsonArray readArray();
+
+    /**
+     * Closes this reader and frees any resources associated with the
+     * reader. This method closes the underlying input source.
+     *
+     * @throws JsonException if an i/o error occurs (IOException would be
+     * cause of JsonException)
+     */
+    @Override
+    void close();
+
+}
Index: trunk/src/javax/json/JsonReaderFactory.java
===================================================================
--- trunk/src/javax/json/JsonReaderFactory.java	(revision 6756)
+++ trunk/src/javax/json/JsonReaderFactory.java	(revision 6756)
@@ -0,0 +1,117 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link javax.json.JsonReader} instances. If a factory
+ * instance is configured with some configuration, that would be
+ * used to configure the created reader instances.
+ *
+ * <p>
+ * {@link javax.json.JsonReader} can also be created using {@link Json}'s
+ * {@code createReader} methods. If multiple reader instances are created,
+ * then creating them using a reader factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonReaderFactory factory = Json.createReaderFactory(...);
+ * JsonReader reader1 = factory.createReader(...);
+ * JsonReader reader2 = factory.createReader(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonReaderFactory {
+
+    /**
+     * Creates a JSON reader from a character stream. The reader is configured
+     * with the factory configuration.
+     *
+     * @param reader a reader from which JSON is to be read
+     * @return a JSON reader
+     */
+    JsonReader createReader(Reader reader);
+
+    /**
+     * Creates a JSON reader from a byte stream. The character encoding of
+     * the stream is determined as described in
+     * <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+     * The reader is configured with the factory configuration.
+     *
+     * @param in a byte stream from which JSON is to be read
+     * @return a JSON reader
+     */
+    JsonReader createReader(InputStream in);
+
+    /**
+     * Creates a JSON reader from a byte stream. The bytes of the stream
+     * are decoded to characters using the specified charset. The reader is
+     * configured with the factory configuration.
+     *
+     * @param in a byte stream from which JSON is to be read
+     * @param charset a charset
+     * @return a JSON reader
+     */
+    JsonReader createReader(InputStream in, Charset charset);
+
+    /**
+     * Returns read-only map of supported provider specific configuration
+     * properties that are used to configure the created JSON readers.
+     * If there are any specified configuration properties that are not
+     * supported by the provider, they won't be part of the returned map.
+     *
+     * @return a map of supported provider specific properties that are used
+     * to configure the readers. The map be empty but not null.
+     */
+    Map<String, ?> getConfigInUse();
+
+}
Index: trunk/src/javax/json/JsonString.java
===================================================================
--- trunk/src/javax/json/JsonString.java	(revision 6756)
+++ trunk/src/javax/json/JsonString.java	(revision 6756)
@@ -0,0 +1,89 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * An immutable JSON string value.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonString extends JsonValue {
+
+    /**
+     * Returns the JSON string value.
+     *
+     * @return a JSON string value
+     */
+    String getString();
+
+
+    /**
+     * Returns the char sequence for the JSON String value
+     *
+     * @return a char sequence for the JSON String value
+     */
+    CharSequence getChars();
+
+    /**
+     * Compares the specified object with this {@code JsonString} for equality.
+     * Returns {@code true} if and only if the specified object is also a
+     * {@code JsonString}, and their {@link #getString()} objects are
+     * <i>equal</i>.
+     *
+     * @param obj the object to be compared for equality with this 
+     *      {@code JsonString}
+     * @return {@code true} if the specified object is equal to this 
+     *      {@code JsonString}
+     */
+    @Override
+    boolean equals(Object obj);
+
+    /**
+     * Returns the hash code value for this {@code JsonString} object.  
+     * The hash code of a {@code JsonString} object is defined to be its 
+     * {@link #getString()} object's hash code.
+     *
+     * @return the hash code value for this {@code JsonString} object
+     */
+    @Override
+    int hashCode();
+
+}
Index: trunk/src/javax/json/JsonStructure.java
===================================================================
--- trunk/src/javax/json/JsonStructure.java	(revision 6756)
+++ trunk/src/javax/json/JsonStructure.java	(revision 6756)
@@ -0,0 +1,50 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * Super type for the two structured types in JSON ({@link JsonObject object}s
+ * and {@link JsonArray array}s).
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonStructure extends JsonValue {
+}
Index: trunk/src/javax/json/JsonValue.java
===================================================================
--- trunk/src/javax/json/JsonValue.java	(revision 6756)
+++ trunk/src/javax/json/JsonValue.java	(revision 6756)
@@ -0,0 +1,262 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+/**
+ * <code>JsonValue</code> represents an immutable JSON value.
+ *
+ * 
+ * <p>A JSON value is one of the following:
+ * an object ({@link JsonObject}), an array ({@link JsonArray}),
+ * a number ({@link JsonNumber}), a string ({@link JsonString}),
+ * {@code true} ({@link JsonValue#TRUE JsonValue.TRUE}), {@code false} 
+ * ({@link JsonValue#FALSE JsonValue.FALSE}),
+ * or {@code null} ({@link JsonValue#NULL JsonValue.NULL}).
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonValue {
+
+    /**
+     * Indicates the type of a {@link JsonValue} object.
+     */
+    enum ValueType {
+        /**
+         * JSON array.
+         */
+        ARRAY,
+
+        /**
+         * JSON object.
+         */
+        OBJECT,
+
+        /**
+         * JSON string.
+         */
+        STRING,
+
+        /**
+         * JSON number.
+         */
+        NUMBER,
+
+        /**
+         * JSON true.
+         */
+        TRUE,
+
+        /**
+         * JSON false.
+         */
+        FALSE,
+
+        /**
+         * JSON null.
+         */
+        NULL
+    }
+
+    /**
+     * JSON null value.
+     */
+    static final JsonValue NULL = new JsonValue() {
+        @Override
+        public ValueType getValueType() {
+            return ValueType.NULL;
+        }
+
+        /**
+         * Compares the specified object with this {@link JsonValue#NULL}
+         * object for equality. Returns {@code true} if and only if the
+         * specified object is also a {@code JsonValue}, and their
+         * {@link #getValueType()} objects are <i>equal</i>.
+         *
+         * @param obj the object to be compared for equality with this 
+         *      {@code JsonValue}
+         * @return {@code true} if the specified object is equal to this 
+         *      {@code JsonValue}
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof JsonValue) {
+                return getValueType().equals(((JsonValue)obj).getValueType());
+            }
+            return false;
+        }
+
+        /**
+         * Returns the hash code value for this {@link JsonValue#NULL} object.
+         * The hash code of the {@link JsonValue#NULL} object is defined to be
+         * its {@link #getValueType()} object's hash code.
+         *
+         * @return the hash code value for this JsonString object
+         */
+        @Override
+        public int hashCode() {
+            return ValueType.NULL.hashCode();
+        }
+
+        /**
+         * Returns a "null" string.
+         *
+         * @return "null"
+         */
+        @Override
+        public String toString() {
+            return "null";
+        }
+    };
+
+    /**
+     * JSON true value.
+     */
+    static final JsonValue TRUE = new JsonValue() {
+        @Override
+        public ValueType getValueType() {
+            return ValueType.TRUE;
+        }
+
+        /**
+         * Compares the specified object with this {@link JsonValue#TRUE}
+         * object for equality. Returns {@code true} if and only if the
+         * specified object is also a JsonValue, and their
+         * {@link #getValueType()} objects are <i>equal</i>.
+         *
+         * @param obj the object to be compared for equality with this JsonValue.
+         * @return {@code true} if the specified object is equal to this JsonValue.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof JsonValue) {
+                return getValueType().equals(((JsonValue)obj).getValueType());
+            }
+            return false;
+        }
+
+        /**
+         * Returns the hash code value for this {@link JsonValue#TRUE} object.
+         * The hash code of the {@link JsonValue#TRUE} object is defined to be
+         * its {@link #getValueType()} object's hash code.
+         *
+         * @return the hash code value for this JsonString object
+         */
+        @Override
+        public int hashCode() {
+            return ValueType.TRUE.hashCode();
+        }
+
+        /**
+         * Returns "true" string
+         *
+         * @return "true"
+         */
+        @Override
+        public String toString() {
+            return "true";
+        }
+    };
+
+    /**
+     * JSON false value
+     */
+    static final JsonValue FALSE = new JsonValue() {
+        @Override
+        public ValueType getValueType() {
+            return ValueType.FALSE;
+        }
+
+        /**
+         * Compares the specified object with this {@link JsonValue#FALSE}
+         * object for equality. Returns {@code true} if and only if the
+         * specified object is also a JsonValue, and their
+         * {@link #getValueType()} objects are <i>equal</i>.
+         *
+         * @param obj the object to be compared for equality with this JsonValue
+         * @return {@code true} if the specified object is equal to this JsonValue
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj instanceof JsonValue) {
+                return getValueType().equals(((JsonValue)obj).getValueType());
+            }
+            return false;
+        }
+
+        /**
+         * Returns the hash code value for this {@link JsonValue#FALSE} object.
+         * The hash code of the {@link JsonValue#FALSE} object is defined to be
+         * its {@link #getValueType()} object's hash code.
+         *
+         * @return the hash code value for this JsonString object
+         */
+        @Override
+        public int hashCode() {
+            return ValueType.FALSE.hashCode();
+        }
+
+        /**
+         * Returns "false" string
+         *
+         * @return "false"
+         */
+        @Override
+        public String toString() {
+            return "false";
+        }
+    };
+
+    /**
+     * Returns the value type of this JSON value.
+     *
+     * @return JSON value type
+     */
+    ValueType getValueType();
+
+    /**
+     * Returns JSON text for this JSON value.
+     *
+     * @return JSON text
+     */
+    @Override
+    String toString();
+
+}
Index: trunk/src/javax/json/JsonWriter.java
===================================================================
--- trunk/src/javax/json/JsonWriter.java	(revision 6756)
+++ trunk/src/javax/json/JsonWriter.java	(revision 6756)
@@ -0,0 +1,131 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.Closeable;
+
+/**
+ * Writes a JSON {@link JsonObject object} or {@link JsonArray array} structure
+ * to an output source.
+ *
+ * <p>The class {@link javax.json.Json} contains methods to create writers from
+ * output sources ({@link java.io.OutputStream} and {@link java.io.Writer}).
+ *
+ * <p>
+ * <a id="JsonWriterExample1"/>
+ * The following example demonstrates how write an empty JSON object:
+ * <pre>
+ * <code>
+ * JsonWriter jsonWriter = Json.createWriter(...);
+ * jsonWriter.writeObject(Json.createObjectBuilder().build());
+ * jsonWriter.close();
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonWriterFactory} also contains methods to create
+ * {@code JsonWriter} instances. A factory instance can be used to create
+ * multiple writer instances with the same configuration. This the preferred
+ * way to create multiple instances. A sample usage is shown in the following
+ * example:
+ * <pre>
+ * <code>
+ * JsonWriterFactory factory = Json.createWriterFactory(config);
+ * JsonWriter writer1 = factory.createWriter(...);
+ * JsonWriter writer2 = factory.createWriter(...);
+ * </code>
+ * </pre>
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonWriter extends  /*Auto*/Closeable {
+
+    /**
+     * Writes the specified JSON {@link JsonArray array} to the output
+     * source. This method needs to be called only once for a writer instance.
+     *
+     * @param array JSON array that is to be written to the output source
+     * @throws JsonException if the specified JSON object cannot be
+     *     written due to i/o error (IOException would be cause of
+     *     JsonException)
+     * @throws IllegalStateException if writeArray, writeObject, write or close
+     *     method is already called
+     */
+    void writeArray(JsonArray array);
+
+    /**
+     * Writes the specified JSON {@link JsonObject object} to the output
+     * source. This method needs to be called only once for a writer instance.
+     *
+     * @param object JSON object that is to be written to the output source
+     * @throws JsonException if the specified JSON object cannot be
+     *     written due to i/o error (IOException would be cause of JsonException)
+     * @throws IllegalStateException if writeArray, writeObject, write or close
+     *     method is already called
+     */
+    void writeObject(JsonObject object);
+
+    /**
+     * Writes the specified JSON {@link JsonObject object} or
+     * {@link JsonArray array} to the output source. This method needs
+     * to be called only once for a writer instance.
+     *
+     * @param value JSON array or object that is to be written to the output
+     *              source
+     * @throws JsonException if the specified JSON object cannot be
+     *     written due to i/o error (IOException would be cause of
+     *     JsonException)
+     * @throws IllegalStateException if writeArray, writeObject, write
+     *     or close method is already called
+     */
+    void write(JsonStructure value);
+
+    /**
+     * Closes this JSON writer and frees any resources associated with the
+     * writer. This method closes the underlying output source.
+     *
+     * @throws JsonException if an i/o error occurs (IOException would be
+     * cause of JsonException)
+     */
+    @Override
+    void close();
+
+}
Index: trunk/src/javax/json/JsonWriterFactory.java
===================================================================
--- trunk/src/javax/json/JsonWriterFactory.java	(revision 6756)
+++ trunk/src/javax/json/JsonWriterFactory.java	(revision 6756)
@@ -0,0 +1,120 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link javax.json.JsonWriter} instances. If a factory
+ * instance is configured with some configuration, that would be
+ * used to configure the created writer instances.
+ *
+ * <p>
+ * {@link javax.json.JsonWriter} can also be created using {@link Json}'s
+ * {@code createWriter} methods. If multiple writer instances are created,
+ * then creating them using a writer factory is preferred.
+ *
+ * <p>
+ * <b>For example:</b>
+ * <pre>
+ * <code>
+ * JsonWriterFactory factory = Json.createWriterFactory(...);
+ * JsonWriter writer1 = factory.createWriter(...);
+ * JsonWriter writer2 = factory.createWriter(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonWriterFactory {
+
+    /**
+     * Creates a JSON writer to write a JSON {@link JsonObject object} or
+     * {@link JsonArray array} structure to the specified character stream.
+     * The writer is configured with the factory configuration.
+     *
+     * @param writer to which JSON object or array is written
+     * @return a JSON writer
+     */
+    JsonWriter createWriter(Writer writer);
+
+    /**
+     * Creates a JSON writer to write a JSON {@link JsonObject object} or
+     * {@link JsonArray array} structure to the specified byte stream.
+     * Characters written to the stream are encoded into bytes using UTF-8
+     * encoding. The writer is configured with the factory configuration.
+     *
+     * @param out to which JSON object or array is written
+     * @return a JSON writer
+     */
+    JsonWriter createWriter(OutputStream out);
+
+    /**
+     * Creates a JSON writer to write a JSON {@link JsonObject object} or
+     * {@link JsonArray array} structure to the specified byte stream.
+     * Characters written to the stream are encoded into bytes using the
+     * specified charset. The writer is configured with the factory
+     * configuration.
+     *
+     * @param out to which JSON object or array is written
+     * @param charset a charset
+     * @return a JSON writer
+     */
+    JsonWriter createWriter(OutputStream out, Charset charset);
+
+    /**
+     * Returns read-only map of supported provider specific configuration
+     * properties that are used to configure the created JSON writer objects.
+     * If there are any specified configuration properties that are not
+     * supported by the provider, they won't be part of the returned map.
+     *
+     * @return a map of supported provider specific properties that are used
+     * to configure the created writers. The map may be empty but not null.
+     */
+    Map<String, ?> getConfigInUse();
+
+}
Index: trunk/src/javax/json/package-info.java
===================================================================
--- trunk/src/javax/json/package-info.java	(revision 6756)
+++ trunk/src/javax/json/package-info.java	(revision 6756)
@@ -0,0 +1,65 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Provides an object model API to process <a href="http://json.org/">JSON</a>.
+ *
+ * <p>The object model API is a high-level API that provides immutable object
+ * models for JSON object and array structures. These JSON structures are
+ * represented as object models using the Java types {@link javax.json.JsonObject}
+ * and {@link javax.json.JsonArray}. The interface {@code javax.json.JsonObject} provides
+ * a {@link java.util.Map} view to access the unordered collection of zero or
+ * more name/value pairs from the model. Similarly, the interface
+ * {@code JsonArray} provides a {@link java.util.List} view to access the
+ * ordered sequence of zero or more values from the model.
+ *
+ * <p>The object model API uses builder patterns to create these object models. 
+ * The classes {@link javax.json.JsonObjectBuilder} and 
+ * {@link javax.json.JsonArrayBuilder} provide methods to create models
+ * of type {@code JsonObject} and {@code JsonArray} respectively.
+ *
+ * <p>These object models can also be created from an input source using
+ * the class {@link javax.json.JsonReader}. Similarly, these object models
+ * can be written to an output source using the class {@link javax.json.JsonWriter}.
+ *
+ * @since JSON Processing 1.0
+ * @author Jitendra Kotamraju
+ */
+package javax.json;
Index: trunk/src/javax/json/spi/JsonProvider.java
===================================================================
--- trunk/src/javax/json/spi/JsonProvider.java	(revision 6756)
+++ trunk/src/javax/json/spi/JsonProvider.java	(revision 6756)
@@ -0,0 +1,274 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.spi;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.ServiceLoader;
+
+/**
+ * Service provider for JSON processing objects.
+ *
+ * <p>All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @see ServiceLoader
+ * @author Jitendra Kotamraju
+ */
+public abstract class JsonProvider {
+
+    /**
+     * A constant representing the name of the default
+     * {@code JsonProvider} implementation class.
+     */
+    private static final String DEFAULT_PROVIDER
+            = "org.glassfish.json.JsonProviderImpl";
+
+    protected JsonProvider() {
+    }
+
+    /**
+     *
+     * Creates a JSON provider object. The provider is loaded using the
+     * {@link ServiceLoader#load(Class)} method. If there are no available
+     * service providers, this method returns the default service provider.
+     *
+     * @see ServiceLoader
+     * @return a JSON provider
+     */
+    public static JsonProvider provider() {
+        ServiceLoader<JsonProvider> loader = ServiceLoader.load(JsonProvider.class);
+        Iterator<JsonProvider> it = loader.iterator();
+        if (it.hasNext()) {
+            return it.next();
+        }
+
+        try {
+            Class<?> clazz = Class.forName(DEFAULT_PROVIDER);
+            return (JsonProvider)clazz.newInstance();
+        } catch (ClassNotFoundException x) {
+            throw new JsonException(
+                    "Provider " + DEFAULT_PROVIDER + " not found", x);
+        } catch (Exception x) {
+            throw new JsonException(
+                    "Provider " + DEFAULT_PROVIDER + " could not be instantiated: " + x,
+                    x);
+        }
+    }
+
+    /**
+     * Creates a JSON parser from a character stream.
+     *
+     * @param reader i/o reader from which JSON is to be read
+     * @return a JSON parser
+     */
+    public abstract JsonParser createParser(Reader reader);
+
+    /**
+     * Creates a JSON parser from the specified byte stream.
+     * The character encoding of the stream is determined
+     * as defined in <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627
+     * </a>.
+     *
+     * @param in i/o stream from which JSON is to be read
+     * @throws JsonException if encoding cannot be determined
+     *         or i/o error (IOException would be cause of JsonException)
+     * @return a JSON parser
+     */
+    public abstract JsonParser createParser(InputStream in);
+
+    /**
+     * Creates a parser factory for creating {@link JsonParser} instances.
+     *
+     * @return a JSON parser factory
+     *
+    public abstract JsonParserFactory createParserFactory();
+     */
+
+    /**
+     * Creates a parser factory for creating {@link JsonParser} instances.
+     * The factory is configured with the specified map of
+     * provider specific configuration properties. Provider implementations
+     * should ignore any unsupported configuration properties specified in
+     * the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON parsers. The map may be empty or null
+     * @return a JSON parser factory
+     */
+    public abstract JsonParserFactory createParserFactory(Map<String, ?> config);
+
+    /**
+     * Creates a JSON generator for writing JSON text to a character stream.
+     *
+     * @param writer a i/o writer to which JSON is written
+     * @return a JSON generator
+     */
+    public abstract JsonGenerator createGenerator(Writer writer);
+
+    /**
+     * Creates a JSON generator for writing JSON text to a byte stream.
+     *
+     * @param out i/o stream to which JSON is written
+     * @return a JSON generator
+     */
+    public abstract JsonGenerator createGenerator(OutputStream out);
+
+    /**
+     * Creates a generator factory for creating {@link JsonGenerator} instances.
+     *
+     * @return a JSON generator factory
+     *
+    public abstract JsonGeneratorFactory createGeneratorFactory();
+     */
+
+    /**
+     * Creates a generator factory for creating {@link JsonGenerator} instances.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should
+     * ignore any unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON generators. The map may be empty or null
+     * @return a JSON generator factory
+     */
+    public abstract JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config);
+
+    /**
+     * Creates a JSON reader from a character stream.
+     *
+     * @param reader a reader from which JSON is to be read
+     * @return a JSON reader
+     */
+    public abstract JsonReader createReader(Reader reader);
+
+    /**
+     * Creates a JSON reader from a byte stream. The character encoding of
+     * the stream is determined as described in
+     * <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+     *
+     * @param in a byte stream from which JSON is to be read
+     * @return a JSON reader
+     */
+    public abstract JsonReader createReader(InputStream in);
+
+    /**
+     * Creates a JSON writer to write a
+     * JSON {@link JsonObject object} or {@link JsonArray array}
+     * structure to the specified character stream.
+     *
+     * @param writer to which JSON object or array is written
+     * @return a JSON writer
+     */
+    public abstract JsonWriter createWriter(Writer writer);
+
+    /**
+     * Creates a JSON writer to write a
+     * JSON {@link JsonObject object} or {@link JsonArray array}
+     * structure to the specified byte stream. Characters written to
+     * the stream are encoded into bytes using UTF-8 encoding.
+     *
+     * @param out to which JSON object or array is written
+     * @return a JSON writer
+     */
+    public abstract JsonWriter createWriter(OutputStream out);
+
+    /**
+     * Creates a writer factory for creating {@link JsonWriter} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON writers. The map may be empty or null
+     * @return a JSON writer factory
+     */
+    public abstract JsonWriterFactory createWriterFactory(Map<String,?> config);
+
+    /**
+     * Creates a reader factory for creating {@link JsonReader} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON readers. The map may be empty or null
+     * @return a JSON reader factory
+     */
+    public abstract JsonReaderFactory createReaderFactory(Map<String,?> config);
+
+    /**
+     * Creates a JSON object builder
+     *
+     * @return a JSON object builder
+     */
+    public abstract JsonObjectBuilder createObjectBuilder();
+
+    /**
+     * Creates a JSON array builder
+     *
+     * @return a JSON array builder
+     */
+    public abstract JsonArrayBuilder createArrayBuilder();
+
+    /**
+     * Creates a builder factory for creating {@link JsonArrayBuilder}
+     * and {@link JsonObjectBuilder} objects.
+     * The factory is configured with the specified map of provider specific
+     * configuration properties. Provider implementations should ignore any
+     * unsupported configuration properties specified in the map.
+     *
+     * @param config a map of provider specific properties to configure the
+     *               JSON builders. The map may be empty or null
+     * @return a JSON builder factory
+     */
+    public abstract JsonBuilderFactory createBuilderFactory(Map<String,?> config);
+
+}
Index: trunk/src/javax/json/spi/package-info.java
===================================================================
--- trunk/src/javax/json/spi/package-info.java	(revision 6756)
+++ trunk/src/javax/json/spi/package-info.java	(revision 6756)
@@ -0,0 +1,57 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Service Provider Interface (SPI) to plug in implementations for
+ * JSON processing objects.
+ *
+ * <p> {@link javax.json.spi.JsonProvider JsonProvider} is an abstract class 
+ * that provides a service for creating JSON processing instances.
+ * A <i>service provider</i> for {@code JsonProvider} provides an 
+ * specific implementation by subclassing and implementing the methods in
+ * {@code JsonProvider}. This enables using custom, efficient JSON processing
+ * implementations (for e.g. parser and generator) other than the default ones.
+ *
+ * <p>The API locates and loads providers using {@link java.util.ServiceLoader}.
+ *
+ * @since JSON Processing 1.0
+ * @author Jitendra Kotamraju
+ */
+package javax.json.spi;
Index: trunk/src/javax/json/stream/JsonGenerationException.java
===================================================================
--- trunk/src/javax/json/stream/JsonGenerationException.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonGenerationException.java	(revision 6756)
@@ -0,0 +1,83 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonException;
+
+/**
+ * {@code JsonGenerationException} indicates an incorrect JSON is
+ * being generated.
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonGenerationException extends JsonException {
+
+    /**
+     * Constructs a new runtime exception with the specified detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     *
+     * @param message the detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     */
+    public JsonGenerationException(String message) {
+        super(message);
+    }
+
+    /**
+     * Constructs a new runtime exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this runtime exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *                by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *              {@link #getCause()} method). (A <tt>null</tt> value is
+     *              permitted, and indicates that the cause is nonexistent or
+     *              unknown.)
+     */
+    public JsonGenerationException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+}
+
Index: trunk/src/javax/json/stream/JsonGenerator.java
===================================================================
--- trunk/src/javax/json/stream/JsonGenerator.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonGenerator.java	(revision 6756)
@@ -0,0 +1,538 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonValue;
+import java.io.Closeable;
+import java.io.Flushable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * Writes JSON data to an output source in a streaming way. The class
+ * {@link javax.json.Json} contains methods to create generators for character
+ * or output streams ({@link java.io.Writer} and {@link java.io.OutputStream}).
+ *
+ * <p>
+ * The following example shows how to create a JSON generator:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = Json.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonGeneratorFactory} also contains methods to create
+ * {@code JsonGenerator} instances. {@link JsonGeneratorFactory} should be used
+ * when creating multiple generator instances, as in the following example:
+ * <pre>
+ * <code>
+ * JsonGeneratorFactory factory = Json.createGeneratorFactory();
+ * JsonGenerator generator1 = factory.createGenerator(...);
+ * JsonGenerator generator2 = factory.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * JSON objects can be created using {@code JsonGenerator} by calling the
+ * {@link #writeStartObject()} method and then adding name/value pairs with the
+ * {@code write} method.
+ * <p>
+ * The following example shows how to generate an empty JSON object:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = ...;
+ * generator.writeStartObject().writeEnd().close();
+ * </code>
+ * </pre>
+ *
+ * JSON arrays can be created using {@code JsonGenerator} by calling the
+ * {@link #writeStartArray()} method and then adding values with the
+ * {@code write} method.
+ *
+ * <p>
+ * The following example shows how to generate an empty JSON array:
+ * <pre>
+ * <code>
+ * JsonGenerator generator = ...;
+ * generator.writeStartArray().writeEnd().close();
+ * </code>
+ * </pre>
+ *
+ * {@code JsonGenerator} methods can be chained as in the following example:
+ * <p>
+ * <a id="JsonGeneratorExample3"/>
+ * <pre>
+ * <code>
+ * generator
+ *     .writeStartObject()
+ *         .write("firstName", "John")
+ *         .write("lastName", "Smith")
+ *         .write("age", 25)
+ *         .writeStartObject("address")
+ *             .write("streetAddress", "21 2nd Street")
+ *             .write("city", "New York")
+ *             .write("state", "NY")
+ *             .write("postalCode", "10021")
+ *         .writeEnd()
+ *         .writeStartArray("phoneNumber")
+ *             .writeStartObject()
+ *                 .write("type", "home")
+ *                 .write("number", "212 555-1234")
+ *             .writeEnd()
+ *             .writeStartObject()
+ *                 .write("type", "fax")
+ *                 .write("number", "646 555-4567")
+ *             .writeEnd()
+ *         .writeEnd()
+ *     .writeEnd();
+ * generator.close();
+ * </code>
+ * </pre>
+ *
+ * The example code above generates the following JSON (or equivalent):
+ * <p>
+ * <pre>
+ * <code>
+ * {
+ *   "firstName": "John", "lastName": "Smith", "age": 25,
+ *   "address" : {
+ *       "streetAddress": "21 2nd Street",
+ *       "city": "New York",
+ *       "state": "NY",
+ *       "postalCode": "10021"
+ *   },
+ *   "phoneNumber": [
+ *       {"type": "home", "number": "212 555-1234"},
+ *       {"type": "fax", "number": "646 555-4567"}
+ *    ]
+ * }
+ * </code>
+ * </pre>
+ *
+ * The generated JSON text must strictly conform to the grammar defined in
+ * <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+ *
+ * @see javax.json.Json
+ * @see JsonGeneratorFactory
+ * @author Jitendra Kotamraju
+ */
+public interface JsonGenerator extends Flushable, /*Auto*/Closeable {
+    /**
+     * Configuration property to generate JSON prettily. All providers
+     * must support this property. The value of the property could be
+     * be anything.
+     */
+    String PRETTY_PRINTING = "javax.json.stream.JsonGenerator.prettyPrinting" ;
+
+    /**
+     * Writes the JSON start object character. It starts a new child object
+     * context within which JSON name/value pairs can be written to the object.
+     * This method is valid only in an array context or in no context (when a
+     * context is not yet started). This method can only be called once in
+     * no context.
+     *
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is called within an 
+     *      object context or if it is called more than once in no context.
+     */
+    JsonGenerator writeStartObject();
+
+    /**
+     * Writes the JSON name/start object character pair in the current
+     * object context. It starts a new child object context within which JSON
+     * name/value pairs can be written to the object.
+     *
+     * @param name a name within the JSON name/object pair to be written
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *     object context
+     */
+    JsonGenerator writeStartObject(String name);
+
+    /**
+     * Writes the JSON start array character. It starts a new child array
+     * context within which JSON values can be written to the array. This
+     * method is valid only in an array context or in no context (when a
+     * context is not yet started). This method can only be called once in
+     * no context.
+     *
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is called within an 
+     *      object context or if called more than once in no context
+     */
+    JsonGenerator writeStartArray();
+
+    /**
+     * Writes the JSON name/start array character pair with in the current
+     * object context. It starts a new child array context within which JSON
+     * values can be written to the array.
+     *
+     * @param name a name within the JSON name/array pair to be written
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within 
+     *      an object context
+     */
+    JsonGenerator writeStartArray(String name);
+
+    /**
+     * Writes a JSON name/value pair in the current object context.
+     *
+     * @param name a name in the JSON name/value pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/value pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context
+     */
+    JsonGenerator write(String name, JsonValue value);
+
+    /**
+     * Writes a JSON name/string value pair in the current object context.
+     * The specified value is written as JSON string value.
+     *
+     * @param name a name in the JSON name/string pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/string pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context
+     */
+    JsonGenerator write(String name, String value);
+
+    /**
+     * Writes a JSON name/number value pair in the current object context.
+     * The specified value is written as a JSON number value. The string
+     * {@code new BigDecimal(value).toString()}
+     * is used as the text value for writing.
+     *
+     * @param name a name in the JSON name/number pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/number pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context.
+     */
+    JsonGenerator write(String name, BigInteger value);
+
+    /**
+     * Writes a JSON name/number value pair in the current object context.
+     * The specified value is written as a JSON number value. The specified
+     * value's {@code toString()} is used as the text value for writing.
+     *
+     * @param name a name in the JSON name/number pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/number pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context.
+     */
+    JsonGenerator write(String name, BigDecimal value);
+
+    /**
+     * Writes a JSON name/number value pair in the current object context.
+     * The specified value is written as a JSON number value. The string
+     * {@code new BigDecimal(value).toString()} is used as the text value
+     * for writing.
+     *
+     * @param name a name in the JSON name/number pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/number pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context.
+     */
+    JsonGenerator write(String name, int value);
+
+    /**
+     * Writes a JSON name/number value pair in the current object context.
+     * The specified value is written as a JSON number value. The string
+     * {@code new BigDecimal(value).toString()} is used as the text
+     * value for writing.
+     *
+     * @param name a name in the JSON name/number pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/number pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context.
+     */
+    JsonGenerator write(String name, long value);
+
+    /**
+     * Writes a JSON name/number value pair in the current object context.
+     * The specified value is written as a JSON number value. The string
+     * {@code BigDecimal.valueOf(double).toString()}
+     * is used as the text value for writing.
+     *
+     * @param name a name in the JSON name/number pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/number pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws NumberFormatException if the value is Not-a-Number(NaN) or infinity.
+     * @throws JsonGenerationException if this method is not called within an
+     *      object context
+     */
+    JsonGenerator write(String name, double value);
+
+    /**
+     * Writes a JSON name/boolean value pair in the current object context.
+     * If value is true, it writes the JSON {@code true} value, otherwise 
+     * it writes the JSON {@code false} value.
+     *
+     * @param name a name in the JSON name/boolean pair to be written in
+     *             current JSON object
+     * @param value a value in the JSON name/boolean pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an
+     *      object context.
+     */
+    JsonGenerator write(String name, boolean value);
+
+
+    /**
+     * Writes a JSON name/null value pair in an current object context.
+     *
+     * @param name a name in the JSON name/null pair to be written in
+     *             current JSON object
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      object context
+     */
+    JsonGenerator writeNull(String name);
+
+    /**
+     * Writes the end of the current context. If the current context is
+     * an array context, this method writes the end-of-array character (']'). 
+     * If the current context is an object context, this method writes the
+     * end-of-object character ('}'). After writing the end of the current
+     * context, the parent context becomes the new current context.
+     *
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is called in no context.
+     */
+    JsonGenerator writeEnd();
+
+    /**
+     * Writes the specified value as a JSON value within
+     * the current array context.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context.
+     */
+    JsonGenerator write(JsonValue value);
+
+    /**
+     * Writes the specified value as a JSON string value within
+     * the current array context.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     */
+    JsonGenerator write(String value);
+
+    /**
+     * Writes the specified value as a JSON number value within
+     * the current array context. The specified value's {@code toString()}
+     * is used as the the text value for writing.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     *
+     * @see javax.json.JsonNumber
+     */
+    JsonGenerator write(BigDecimal value);
+
+    /**
+     * Writes the specified value as a JSON number value within
+     * the current array context. The string {@code new BigDecimal(value).toString()}
+     * is used as the text value for writing.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator.
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     *
+     * @see javax.json.JsonNumber
+     */
+    JsonGenerator write(BigInteger value);
+
+    /**
+     * Writes the specified value as a JSON number value within
+     * the current array context. The string {@code new BigDecimal(value).toString()}
+     * is used as the text value for writing.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     */
+    JsonGenerator write(int value);
+
+    /**
+     * Writes the specified value as a JSON number value within
+     * the current array context. The string {@code new BigDecimal(value).toString()}
+     * is used as the text value for writing.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     */
+    JsonGenerator write(long value);
+
+    /**
+     * Writes the specified value as a JSON number value within the current
+     * array context. The string {@code BigDecimal.valueOf(value).toString()}
+     * is used as the text value for writing.
+     *
+     * @param value a value to be written in current JSON array
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     * @throws NumberFormatException if the value is Not-a-Number(NaN) or infinity.
+     */
+    JsonGenerator write(double value);
+
+    /**
+     * Writes a JSON true or false value within the current array context.
+     * If value is true, this method writes the JSON {@code true} value, 
+     * otherwise it writes the JSON {@code false} value.
+     *
+     * @param value a {@code boolean} value
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context.
+     */
+    JsonGenerator write(boolean value);
+
+    /**
+     * Writes a JSON null value within the current array context.
+     *
+     * @return this generator
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if this method is not called within an 
+     *      array context
+     */
+    JsonGenerator writeNull();
+
+    /**
+     * Closes this generator and frees any resources associated with it. 
+     * This method closes the underlying output source.
+     *
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonGenerationException if an incomplete JSON is generated
+     */
+    @Override
+    void close();
+
+    /**
+     * Flushes the underlying output source. If the generator has saved
+     * any characters in a buffer, writes them immediately to the underlying
+     * output source before flushing it.
+     *
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     */
+    @Override
+    void flush();
+
+}
Index: trunk/src/javax/json/stream/JsonGeneratorFactory.java
===================================================================
--- trunk/src/javax/json/stream/JsonGeneratorFactory.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonGeneratorFactory.java	(revision 6756)
@@ -0,0 +1,112 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory to create {@link JsonGenerator} instances. If a factory
+ * instance is configured with some configuration, the configuration applies
+ * to all generator instances created using that factory instance.
+ *
+ * <p>
+ * The class {@link javax.json.Json Json} also provides methods to create
+ * {@link JsonGenerator} instances, but using {@code JsonGeneratorFactory} is
+ * preferred when creating multiple generator instances as shown in the
+ * following example:
+ *
+ * <pre>
+ * <code>
+ * JsonGeneratorFactory factory = Json.createGeneratorFactory();
+ * JsonGenerator generator1 = factory.createGenerator(...);
+ * JsonGenerator generator2 = factory.createGenerator(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonGeneratorFactory {
+
+    /**
+     * Creates a JSON generator to write JSON text to a character stream.
+     * The generator is configured with the factory configuration.
+     *
+     * @param writer i/o writer to which JSON is written
+     */
+    JsonGenerator createGenerator(Writer writer);
+
+    /**
+     * Creates a JSON generator to write JSON text to a byte stream. Characters 
+     * written to the stream are encoded into bytes using UTF-8 encoding. 
+     * The generator is configured with the factory's configuration.
+     *
+     * @param out i/o stream to which JSON is written
+     */
+    JsonGenerator createGenerator(OutputStream out);
+
+    /**
+     * Creates a JSON generator to write JSON text to a byte stream. Characters 
+     * written to the stream are encoded into bytes using the specified charset. 
+     * The generator is configured with the factory's configuration.
+     *
+     * @param out i/o stream to which JSON is written
+     * @param charset a charset
+     */
+    JsonGenerator createGenerator(OutputStream out, Charset charset);
+
+    /**
+     * Returns a read-only map of supported provider specific configuration
+     * properties that are used to configure the JSON generators.
+     * If there are any specified configuration properties that are not
+     * supported by the provider, they won't be part of the returned map.
+     *
+     * @return a map of supported provider specific properties that are used
+     * to configure the created generators. The map may be empty but not null
+     */
+    Map<String, ?> getConfigInUse();
+
+}
Index: trunk/src/javax/json/stream/JsonLocation.java
===================================================================
--- trunk/src/javax/json/stream/JsonLocation.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonLocation.java	(revision 6756)
@@ -0,0 +1,87 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+/**
+ * Provides the location information of a JSON event in an input source. The
+ * {@code JsonLocation} information can be used to identify incorrect JSON
+ * or can be used by higher frameworks to know about the processing location.
+ *
+ * <p>All the information provided by a {@code JsonLocation} is optional. For
+ * example, a provider may only report line numbers. Also, there may not be any
+ * location information for an input source. For example, if a
+ * {@code JsonParser} is created using
+ * {@link javax.json.JsonArray JsonArray} input source, all the methods in
+ * this class return -1.
+ *
+ * @author Jitendra Kotamraju
+ * @see JsonParser
+ * @see JsonParsingException
+ */
+public interface JsonLocation {
+
+    /**
+     * Return the line number for the current JSON event in the input source.
+     *
+     * @return the line number or -1 if none is available
+     */
+    long getLineNumber();
+
+    /**
+     * Return the column number for the current JSON event in the input source.
+     *
+     * @return the column number or -1 if none is available
+     */
+    long getColumnNumber();
+
+    /**
+     * Return the stream offset into the input source this location
+     * is pointing to. If the input source is a file or a byte stream then
+     * this is the byte offset into that stream, but if the input source is
+     * a character media then the offset is the character offset.
+     * Returns -1 if there is no offset available.
+     *
+     * @return the offset of input source stream, or -1 if there is
+     * no offset available
+     */
+    long getStreamOffset();
+
+}
Index: trunk/src/javax/json/stream/JsonParser.java
===================================================================
--- trunk/src/javax/json/stream/JsonParser.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonParser.java	(revision 6756)
@@ -0,0 +1,347 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+
+import java.io.Closeable;
+import java.math.BigDecimal;
+
+/**
+ * Provides forward, read-only access to JSON data in a streaming way. This
+ * is the most efficient way for reading JSON data. The class
+ * {@link javax.json.Json} contains methods to create parsers from input
+ * sources ({@link java.io.InputStream} and {@link java.io.Reader}).
+ *
+ * <p>
+ * The following example demonstrates how to create a parser from a string
+ * that contains an empty JSON array:
+ * <pre>
+ * <code>
+ * JsonParser parser = Json.createParser(new StringReader("[]"));
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * The class {@link JsonParserFactory} also contains methods to create
+ * {@code JsonParser} instances. {@link JsonParserFactory} is preferred
+ * when creating multiple parser instances. A sample usage is shown
+ * in the following example:
+ * <pre>
+ * <code>
+ * JsonParserFactory factory = Json.createParserFactory();
+ * JsonParser parser1 = factory.createParser(...);
+ * JsonParser parser2 = factory.createParser(...);
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * {@code JsonParser} parses JSON using the pull parsing programming model.
+ * In this model the client code controls the thread and calls the method
+ * {@code next()} to advance the parser to the next state after
+ * processing each element. The parser can generate the following events:
+ * {@code START_OBJECT}, {@code END_OBJECT}, {@code START_ARRAY},
+ * {@code END_ARRAY}, {@code KEY_NAME}, {@code VALUE_STRING},
+ * {@code VALUE_NUMBER}, {@code VALUE_TRUE}, {@code VALUE_FALSE},
+ * and {@code VALUE_NULL}.
+ *
+ * <p>
+ * <b>For example</b>, for an empty JSON object ({ }), the parser generates the event
+ * {@code START_OBJECT} with the first call to the method {@code next()} and the
+ * event {@code END_OBJECT} with the second call to the method {@code next()}.
+ * The following code demonstrates how to access these events:
+ *
+ * <pre>
+ * <code>
+ * Event event = parser.next(); // START_OBJECT
+ * event = parser.next();       // END_OBJECT
+ * </code>
+ * </pre>
+ *
+ * <p>
+ * <a id="JsonParserExample2"/>
+ * <p>
+ * <b>For example</b>, for the following JSON:
+ * <pre>
+ * {
+ *   "firstName": "John", "lastName": "Smith", "age": 25,
+ *   "phoneNumber": [
+ *       { "type": "home", "number": "212 555-1234" },
+ *       { "type": "fax", "number": "646 555-4567" }
+ *    ]
+ * }
+ * </pre>
+ *
+ * <p>calls to the method {@code next()} result in parse events at the specified
+ * locations below (marked in bold):
+ *
+ * <p>
+ * <pre>
+ * {<B>START_OBJECT</B>
+ *   "firstName"<B>KEY_NAME</B>: "John"<B>VALUE_STRING</B>, "lastName"<B>KEY_NAME</B>: "Smith"<B>VALUE_STRING</B>, "age"<B>KEY_NAME</B>: 25<B>VALUE_NUMBER</B>,
+ *   "phoneNumber"<B>KEY_NAME</B> : [<B>START_ARRAY</B>
+ *       {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "home"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "212 555-1234"<B>VALUE_STRING</B> }<B>END_OBJECT</B>,
+ *       {<B>START_OBJECT</B> "type"<B>KEY_NAME</B>: "fax"<B>VALUE_STRING</B>, "number"<B>KEY_NAME</B>: "646 555-4567"<B>VALUE_STRING</B> }<B>END_OBJECT</B>
+ *    ]<B>END_ARRAY</B>
+ * }<B>END_OBJECT</B>
+ * </pre>
+ *
+ * <p>
+ * The methods {@code next()} and {@code hasNext()} enable iteration over
+ * parser events to process JSON data. {@code JsonParser} provides get methods
+ * to obtain the value at the current state of the parser. For example, the
+ * following code shows how to obtain the value "John" from the JSON above:
+ *
+ * <p>
+ * <pre>
+ * <code>
+ * Event event = parser.next(); // START_OBJECT
+ * event = parser.next();       // KEY_NAME
+ * event = parser.next();       // VALUE_STRING
+ * parser.getString();          // "John"
+ * </code>
+ * </pre>
+ *
+ * @see javax.json.Json
+ * @see JsonParserFactory
+ * @author Jitendra Kotamraju
+ */
+public interface JsonParser extends /*Auto*/Closeable {
+
+    /**
+     * An event from {@code JsonParser}.
+     */
+    enum Event {
+        /**
+         * Start of a JSON array. The position of the parser is after '['.
+         */
+        START_ARRAY,
+        /**
+         * Start of a JSON object. The position of the parser is after '{'.
+         */
+        START_OBJECT,
+        /**
+         * Name in a name/value pair of a JSON object. The position of the parser
+         * is after the key name. The method {@link #getString} returns the key
+         * name.
+         */
+        KEY_NAME,
+        /**
+         * String value in a JSON array or object. The position of the parser is
+         * after the string value. The method {@link #getString}
+         * returns the string value.
+         */
+        VALUE_STRING,
+        /**
+         * Number value in a JSON array or object. The position of the parser is
+         * after the number value. {@code JsonParser} provides the following
+         * methods to access the number value: {@link #getInt},
+         * {@link #getLong}, and {@link #getBigDecimal}.
+         */
+        VALUE_NUMBER,
+        /**
+         * {@code true} value in a JSON array or object. The position of the
+         * parser is after the {@code true} value.
+         */
+        VALUE_TRUE,
+        /**
+         * {@code false} value in a JSON array or object. The position of the
+         * parser is after the {@code false} value.
+         */
+        VALUE_FALSE,
+        /**
+         * {@code null} value in a JSON array or object. The position of the
+         * parser is after the {@code null} value.
+         */
+        VALUE_NULL,
+        /**
+         * End of a JSON object. The position of the parser is after '}'.
+         */
+        END_OBJECT,
+        /**
+         * End of a JSON array. The position of the parser is after ']'.
+         */
+        END_ARRAY
+    }
+
+    /**
+     * Returns {@code true} if there are more parsing states. This method returns
+     * {@code false} if the parser reaches the end of the JSON text.
+     *
+     * @return {@code true} if there are more parsing states.
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonParsingException if the parser encounters invalid JSON
+     * when advancing to next state.
+     */
+    boolean hasNext();
+
+    /**
+     * Returns the event for the next parsing state.
+     *
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     * @throws JsonParsingException if the parser encounters invalid JSON
+     * when advancing to next state.
+     * @throws java.util.NoSuchElementException if there are no more parsing
+     * states.
+     */
+    Event next();
+
+    /**
+     * Returns a {@code String} for the name in a name/value pair,
+     * for a string value or a number value. This method should only be called
+     * when the parser state is {@link Event#KEY_NAME}, {@link Event#VALUE_STRING},
+     * or {@link Event#VALUE_NUMBER}.
+     *
+     * @return a name when the parser state is {@link Event#KEY_NAME}
+     *         a string value when the parser state is {@link Event#VALUE_STRING}
+     *         a number value when the parser state is {@link Event#VALUE_NUMBER}
+     * @throws IllegalStateException when the parser state is not
+     *      {@code KEY_NAME}, {@code VALUE_STRING}, or {@code VALUE_NUMBER}
+     */
+    String getString();
+
+    /**
+     * Returns true if the JSON number at the current parser state is a
+     * integral number. A {@link BigDecimal} may be used to store the value
+     * internally and this method semantics are defined using its
+     * {@code scale()}. If the scale is zero, then it is considered integral
+     * type. This integral type information can be used to invoke an
+     * appropriate accessor method to obtain a numeric value as in the
+     * following example:
+     *
+     * <pre>
+     * <code>
+     * JsonParser parser = ...
+     * if (parser.isIntegralNumber()) {
+     *     parser.getInt();     // or other methods to get integral value
+     * } else {
+     *     parser.getBigDecimal();
+     * }
+     * </code>
+     * </pre>
+     *
+     * @return true if this number is a integral number, otherwise false
+     * @throws IllegalStateException when the parser state is not
+     *      {@code VALUE_NUMBER}
+     */
+    boolean isIntegralNumber();
+
+    /**
+     * Returns a JSON number as an integer. The returned value is equal
+     * to {@code new BigDecimal(getString()).intValue()}. Note that
+     * this conversion can lose information about the overall magnitude
+     * and precision of the number value as well as return a result with
+     * the opposite sign. This method should only be called when the parser
+     * state is {@link Event#VALUE_NUMBER}.
+     *
+     * @return an integer for a JSON number
+     * @throws IllegalStateException when the parser state is not
+     *      {@code VALUE_NUMBER}
+     * @see java.math.BigDecimal#intValue()
+     */
+    int getInt();
+
+    /**
+     * Returns a JSON number as a long. The returned value is equal
+     * to {@code new BigDecimal(getString()).longValue()}. Note that this
+     * conversion can lose information about the overall magnitude and
+     * precision of the number value as well as return a result with
+     * the opposite sign. This method is only called when the parser state is
+     * {@link Event#VALUE_NUMBER}.
+     *
+     * @return a long for a JSON number
+     * @throws IllegalStateException when the parser state is not
+     *      {@code VALUE_NUMBER}
+     * @see java.math.BigDecimal#longValue()
+     */
+    long getLong();
+
+    /**
+     * Returns a JSON number as a {@code BigDecimal}. The {@code BigDecimal}
+     * is created using {@code new BigDecimal(getString())}. This
+     * method should only called when the parser state is
+     * {@link Event#VALUE_NUMBER}.
+     *
+     * @return a {@code BigDecimal} for a JSON number
+     * @throws IllegalStateException when the parser state is not
+     *      {@code VALUE_NUMBER}
+     */
+    BigDecimal getBigDecimal();
+
+    /**
+     * Return the location that corresponds to the parser's current state in
+     * the JSON input source. The location information is only valid in the
+     * current parser state (or until the parser is advanced to a next state).
+     *
+     * @return a non-null location corresponding to the current parser state
+     * in JSON input source
+     */
+    JsonLocation getLocation();
+
+    /**
+     * getJsonValue(JsonObject.class) is valid in the START_OBJECT state and
+     * moves the cursor to END_OBJECT.
+     *
+     * getJsonValue(JsonArray.class) is valid in the START_ARRAY state
+     * and moves the cursor to END_ARRAY.
+     *
+     * getJsonValue(JsonString.class) is valid in the VALUE_STRING state.
+     *
+     * getJsonValue(JsonNumber.class) is valid in the VALUE_NUMBER state.
+     *
+     * @param clazz
+     * @return
+     *
+    public <T extends JsonValue> T getJsonValue(Class<T> clazz);
+     */
+
+    /**
+     * Closes this parser and frees any resources associated with the
+     * parser. This method closes the underlying input source.
+     *
+     * @throws javax.json.JsonException if an i/o error occurs (IOException
+     * would be cause of JsonException)
+     */
+    @Override
+    void close();
+
+}
Index: trunk/src/javax/json/stream/JsonParserFactory.java
===================================================================
--- trunk/src/javax/json/stream/JsonParserFactory.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonParserFactory.java	(revision 6756)
@@ -0,0 +1,129 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2011-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * Factory for creating {@link JsonParser} instances. If a factory
+ * instance is configured with a configuration, the configuration applies
+ * to all parser instances created using that factory instance.
+ *
+ * <p>
+ * The class {@link javax.json.Json Json} also provides methods to create
+ * {@link JsonParser} instances, but using {@code JsonParserFactory} is 
+ * preferred when creating multiple parser instances as shown in the following
+ * example:
+ *
+ * <pre>
+ * <code>
+ * JsonParserFactory factory = Json.createParserFactory();
+ * JsonParser parser1 = factory.createParser(...);
+ * JsonParser parser2 = factory.createParser(...);
+ * </code>
+ * </pre>
+ *
+ * <p> All the methods in this class are safe for use by multiple concurrent
+ * threads.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface JsonParserFactory {
+
+    /**
+     * Creates a JSON parser from a character stream.
+     *
+     * @param reader a i/o reader from which JSON is to be read
+     */
+    JsonParser createParser(Reader reader);
+
+    /**
+     * Creates a JSON parser from the specified byte stream.
+     * The character encoding of the stream is determined
+     * as specified in <a href="http://tools.ietf.org/rfc/rfc4627.txt">RFC 4627</a>.
+     *
+     * @param in i/o stream from which JSON is to be read
+     * @throws javax.json.JsonException if encoding cannot be determined
+     *         or i/o error (IOException would be cause of JsonException)
+     */
+    JsonParser createParser(InputStream in);
+
+    /**
+     * Creates a JSON parser from the specified byte stream.
+     * The bytes of the stream are decoded to characters using the
+     * specified charset.
+     *
+     * @param in i/o stream from which JSON is to be read
+     * @param charset a charset
+     */
+    JsonParser createParser(InputStream in, Charset charset);
+
+    /**
+     * Creates a JSON parser from the specified JSON object.
+     *
+     * @param obj a JSON object
+     */
+    JsonParser createParser(JsonObject obj);
+
+    /**
+     * Creates a JSON parser from the specified JSON array.
+     *
+     * @param array a JSON array
+     */
+    JsonParser createParser(JsonArray array);
+
+    /**
+     * Returns a read-only map of supported provider specific configuration
+     * properties that are used to configure the JSON parsers.
+     * If there are any specified configuration properties that are not
+     * supported by the provider, they won't be part of the returned map.
+     *
+     * @return a map of supported provider specific properties that are used
+     * to configure the created parsers. The map may be empty but not null
+     */
+    Map<String, ?> getConfigInUse();
+
+}
Index: trunk/src/javax/json/stream/JsonParsingException.java
===================================================================
--- trunk/src/javax/json/stream/JsonParsingException.java	(revision 6756)
+++ trunk/src/javax/json/stream/JsonParsingException.java	(revision 6756)
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package javax.json.stream;
+
+import javax.json.JsonException;
+
+/**
+ * {@code JsonParsingException} is used when an incorrect JSON is
+ * being parsed.
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonParsingException extends JsonException {
+
+    private final JsonLocation location;
+
+    /**
+     * Constructs a new runtime exception with the specified detail message.
+     * The cause is not initialized, and may subsequently be initialized by a
+     * call to {@link #initCause}.
+     *
+     * @param message the detail message. The detail message is saved for
+     *                later retrieval by the {@link #getMessage()} method.
+     * @param location the location of the incorrect JSON
+     */
+    public JsonParsingException(String message, JsonLocation location) {
+        super(message);
+        this.location = location;
+    }
+
+    /**
+     * Constructs a new runtime exception with the specified detail message and
+     * cause.  <p>Note that the detail message associated with
+     * {@code cause} is <i>not</i> automatically incorporated in
+     * this runtime exception's detail message.
+     *
+     * @param message the detail message (which is saved for later retrieval
+     *                by the {@link #getMessage()} method).
+     * @param cause the cause (which is saved for later retrieval by the
+     *              {@link #getCause()} method). (A <tt>null</tt> value is
+     *              permitted, and indicates that the cause is nonexistent or
+     *              unknown.)
+     * @param location the location of the incorrect JSON
+     */
+    public JsonParsingException(String message, Throwable cause, JsonLocation location) {
+        super(message, cause);
+        this.location = location;
+    }
+
+    /**
+     * Return the location of the incorrect JSON.
+     *
+     * @return the non-null location of the incorrect JSON
+     */
+    public JsonLocation getLocation() {
+        return location;
+    }
+
+}
+
Index: trunk/src/javax/json/stream/package-info.java
===================================================================
--- trunk/src/javax/json/stream/package-info.java	(revision 6756)
+++ trunk/src/javax/json/stream/package-info.java	(revision 6756)
@@ -0,0 +1,72 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+/**
+ * Provides a streaming API to parse and generate
+ * <a href="http://json.org/">JSON</a>.
+ *
+ * <p>
+ * The streaming API consists of the interfaces
+ * {@link javax.json.stream.JsonParser} and
+ * {@link javax.json.stream.JsonGenerator}. The interface {@code JsonParser}
+ * contains methods to parse JSON in a streaming way. The interface
+ * {@code JsonGenerator} contains methods to write JSON to an output source
+ * in a streaming way.
+ *
+ * <p>
+ * {@code JsonParser} provides forward, read-only access to JSON data using the
+ * pull parsing programming model. In this model the application code controls
+ * the thread and calls methods in the parser interface to move the parser
+ * forward or to obtain JSON data from the current state of the parser.
+ *
+ * <p>
+ * {@code JsonGenerator} provides methods to write JSON to an output source.
+ * The generator writes name/value pairs in JSON objects and values in JSON
+ * arrays.
+ * 
+ * <p>
+ * The streaming API is a low-level API designed to process large amounts of
+ * JSON data efficiently. Other JSON frameworks (such as JSON binding) can be
+ * implemented using this API.
+ *
+ * @since JSON Processing 1.0
+ * @author Jitendra Kotamraju
+ */
+package javax.json.stream;
Index: trunk/src/org/glassfish/json/BufferPoolImpl.java
===================================================================
--- trunk/src/org/glassfish/json/BufferPoolImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/BufferPoolImpl.java	(revision 6756)
@@ -0,0 +1,98 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+/**
+ * char[] pool that pool instances of char[] which are expensive to create.
+ *
+ * @author Jitendra Kotamraju
+ */
+class BufferPoolImpl implements BufferPool {
+
+    // volatile since multiple threads may access queue reference
+    private volatile WeakReference<ConcurrentLinkedQueue<char[]>> queue;
+
+    /**
+     * Gets a new object from the pool.
+     *
+     * <p>
+     * If no object is available in the pool, this method creates a new one.
+     *
+     * @return
+     *      always non-null.
+     */
+    @Override
+    public final char[] take() {
+        char[] t = getQueue().poll();
+        if (t==null)
+            return new char[4096];
+        return t;
+    }
+
+    private ConcurrentLinkedQueue<char[]> getQueue() {
+        WeakReference<ConcurrentLinkedQueue<char[]>> q = queue;
+        if (q != null) {
+            ConcurrentLinkedQueue<char[]> d = q.get();
+            if (d != null)
+                return d;
+        }
+
+        // overwrite the queue
+        ConcurrentLinkedQueue<char[]> d = new ConcurrentLinkedQueue<char[]>();
+        queue = new WeakReference<ConcurrentLinkedQueue<char[]>>(d);
+
+        return d;
+    }
+
+    /**
+     * Returns an object back to the pool.
+     */
+    @Override
+    public final void recycle(char[] t) {
+        getQueue().offer(t);
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonArrayBuilderImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonArrayBuilderImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonArrayBuilderImpl.java	(revision 6756)
@@ -0,0 +1,275 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * JsonArrayBuilder impl
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonArrayBuilderImpl implements JsonArrayBuilder {
+    private ArrayList<JsonValue> valueList;
+    private final BufferPool bufferPool;
+
+    JsonArrayBuilderImpl(BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+    }
+
+    public JsonArrayBuilder add(JsonValue value) {
+        validateValue(value);
+        addValueList(value);
+        return this;
+    }
+
+    public JsonArrayBuilder add(String value) {
+        validateValue(value);
+        addValueList(new JsonStringImpl(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(BigDecimal value) {
+        validateValue(value);
+        addValueList(JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(BigInteger value) {
+        validateValue(value);
+        addValueList(JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(int value) {
+        addValueList(JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(long value) {
+        addValueList(JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(double value) {
+        addValueList(JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonArrayBuilder add(boolean value) {
+        addValueList(value ? JsonValue.TRUE : JsonValue.FALSE);
+        return this;
+    }
+
+    public JsonArrayBuilder addNull() {
+        addValueList(JsonValue.NULL);
+        return this;
+    }
+
+    public JsonArrayBuilder add(JsonObjectBuilder builder) {
+        if (builder == null) {
+            throw new NullPointerException(JsonMessages.ARRBUILDER_OBJECT_BUILDER_NULL());
+        }
+        addValueList(builder.build());
+        return this;
+    }
+
+    public JsonArrayBuilder add(JsonArrayBuilder builder) {
+        if (builder == null) {
+            throw new NullPointerException(JsonMessages.ARRBUILDER_ARRAY_BUILDER_NULL());
+        }
+        addValueList(builder.build());
+        return this;
+    }
+
+    public JsonArray build() {
+        List<JsonValue> snapshot;
+        if (valueList == null) {
+            snapshot = Collections.emptyList();
+        } else {
+            // Should we trim to minimize storage ?
+            // valueList.trimToSize();
+            snapshot = Collections.unmodifiableList(valueList);
+        }
+        valueList = null;
+        return new JsonArrayImpl(snapshot, bufferPool);
+    }
+
+    private void addValueList(JsonValue value) {
+        if (valueList == null) {
+            valueList = new ArrayList<JsonValue>();
+        }
+        valueList.add(value);
+    }
+
+    private void validateValue(Object value) {
+        if (value == null) {
+            throw new NullPointerException(JsonMessages.ARRBUILDER_VALUE_NULL());
+        }
+    }
+
+    private static final class JsonArrayImpl extends AbstractList<JsonValue> implements JsonArray {
+        private final List<JsonValue> valueList;    // Unmodifiable
+        private final BufferPool bufferPool;
+
+        JsonArrayImpl(List<JsonValue> valueList, BufferPool bufferPool) {
+            this.valueList = valueList;
+            this.bufferPool = bufferPool;
+        }
+
+        @Override
+        public int size() {
+            return valueList.size();
+        }
+
+        @Override
+        public JsonObject getJsonObject(int index) {
+            return (JsonObject)valueList.get(index);
+        }
+
+        @Override
+        public JsonArray getJsonArray(int index) {
+            return (JsonArray)valueList.get(index);
+        }
+
+        @Override
+        public JsonNumber getJsonNumber(int index) {
+            return (JsonNumber)valueList.get(index);
+        }
+
+        @Override
+        public JsonString getJsonString(int index) {
+            return (JsonString)valueList.get(index);
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public <T extends JsonValue> List<T> getValuesAs(Class<T> clazz) {
+            return (List<T>)valueList;
+        }
+
+        @Override
+        public String getString(int index) {
+            return getJsonString(index).getString();
+        }
+
+        @Override
+        public String getString(int index, String defaultValue) {
+            try {
+                return getString(index);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public int getInt(int index) {
+            return getJsonNumber(index).intValue();
+        }
+
+        @Override
+        public int getInt(int index, int defaultValue) {
+            try {
+                return getInt(index);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public boolean getBoolean(int index) {
+            JsonValue jsonValue = get(index);
+            if (jsonValue == JsonValue.TRUE) {
+                return true;
+            } else if (jsonValue == JsonValue.FALSE) {
+                return false;
+            } else {
+                throw new ClassCastException();
+            }
+        }
+
+        @Override
+        public boolean getBoolean(int index, boolean defaultValue) {
+            try {
+                return getBoolean(index);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public boolean isNull(int index) {
+            return valueList.get(index).equals(JsonValue.NULL);
+        }
+
+        @Override
+        public ValueType getValueType() {
+            return ValueType.ARRAY;
+        }
+
+        @Override
+        public JsonValue get(int index) {
+            return valueList.get(index);
+        }
+
+        @Override
+        public String toString() {
+            StringWriter sw = new StringWriter();
+            JsonWriter jw = new JsonWriterImpl(sw, bufferPool);
+            jw.write(this);
+            jw.close();
+            return sw.toString();
+        }
+    }
+
+}
+
+
+
Index: trunk/src/org/glassfish/json/JsonBuilderFactoryImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonBuilderFactoryImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonBuilderFactoryImpl.java	(revision 6756)
@@ -0,0 +1,77 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonBuilderFactory;
+import javax.json.JsonObjectBuilder;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonBuilderFactoryImpl implements JsonBuilderFactory {
+    private final Map<String, ?> config;
+    private final BufferPool bufferPool;
+
+    JsonBuilderFactoryImpl(BufferPool bufferPool) {
+        this.config = Collections.emptyMap();
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonObjectBuilder createObjectBuilder() {
+        return new JsonObjectBuilderImpl(bufferPool);
+    }
+
+    @Override
+    public JsonArrayBuilder createArrayBuilder() {
+        return new JsonArrayBuilderImpl(bufferPool);
+    }
+
+    @Override
+    public Map<String, ?> getConfigInUse() {
+        return config;
+    }
+}
Index: trunk/src/org/glassfish/json/JsonGeneratorFactoryImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonGeneratorFactoryImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonGeneratorFactoryImpl.java	(revision 6756)
@@ -0,0 +1,94 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonGeneratorFactoryImpl implements JsonGeneratorFactory {
+
+    private final boolean prettyPrinting;
+    private final Map<String, ?> config;    // unmodifiable map
+    private final BufferPool bufferPool;
+
+    JsonGeneratorFactoryImpl(Map<String, ?> config, boolean prettyPrinting,
+            BufferPool bufferPool) {
+        this.config = config;
+        this.prettyPrinting = prettyPrinting;
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonGenerator createGenerator(Writer writer) {
+        return prettyPrinting
+                ? new JsonPrettyGeneratorImpl(writer, bufferPool)
+                : new JsonGeneratorImpl(writer, bufferPool);
+    }
+
+    @Override
+    public JsonGenerator createGenerator(OutputStream out) {
+        return prettyPrinting
+                ? new JsonPrettyGeneratorImpl(out, bufferPool)
+                : new JsonGeneratorImpl(out, bufferPool);
+    }
+
+    @Override
+    public JsonGenerator createGenerator(OutputStream out, Charset charset) {
+        return prettyPrinting
+                ? new JsonPrettyGeneratorImpl(out, charset, bufferPool)
+                : new JsonGeneratorImpl(out, charset, bufferPool);
+    }
+
+    @Override
+    public Map<String, ?> getConfigInUse() {
+        return config;
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonGeneratorImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonGeneratorImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonGeneratorImpl.java	(revision 6756)
@@ -0,0 +1,709 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerationException;
+import javax.json.stream.JsonGenerator;
+import java.io.*;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.nio.charset.Charset;
+import java.util.ArrayDeque;
+import java.util.Deque;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonGeneratorImpl implements JsonGenerator {
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    private static final char[] INT_MIN_VALUE_CHARS = "-2147483648".toCharArray();
+    private static final int[] INT_CHARS_SIZE_TABLE = { 9, 99, 999, 9999, 99999,
+            999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE };
+
+    private static final char [] DIGIT_TENS = {
+            '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
+            '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
+            '2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
+            '3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
+            '4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
+            '5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
+            '6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
+            '7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
+            '8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
+            '9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
+    } ;
+
+    private static final char [] DIGIT_ONES = {
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+    } ;
+
+    /**
+     * All possible chars for representing a number as a String
+     */
+    private static final char[] DIGITS = {
+            '0' , '1' , '2' , '3' , '4' , '5' ,
+            '6' , '7' , '8' , '9'
+    };
+
+    private static enum Scope {
+        IN_NONE,
+        IN_OBJECT,
+        IN_ARRAY
+    }
+
+    private final BufferPool bufferPool;
+    private final Writer writer;
+    private Context currentContext = new Context(Scope.IN_NONE);
+    private final Deque<Context> stack = new ArrayDeque<Context>();
+
+    // Using own buffering mechanism as JDK's BufferedWriter uses synchronized
+    // methods. Also, flushBuffer() is useful when you don't want to actually
+    // flush the underlying output source
+    private final char buf[];     // capacity >= INT_MIN_VALUE_CHARS.length
+    private int len = 0;
+
+    JsonGeneratorImpl(Writer writer, BufferPool bufferPool) {
+        this.writer = writer;
+        this.bufferPool = bufferPool;
+        this.buf = bufferPool.take();
+    }
+
+    JsonGeneratorImpl(OutputStream out, BufferPool bufferPool) {
+        this(out, UTF_8, bufferPool);
+    }
+
+    JsonGeneratorImpl(OutputStream out, Charset encoding, BufferPool bufferPool) {
+        this(new OutputStreamWriter(out, encoding), bufferPool);
+    }
+
+    @Override
+    public void flush() {
+        flushBuffer();
+        try {
+            writer.flush();
+        } catch (IOException ioe) {
+            throw new JsonException(JsonMessages.GENERATOR_FLUSH_IO_ERR(), ioe);
+        }
+    }
+
+    @Override
+    public JsonGenerator writeStartObject() {
+        if (currentContext.scope == Scope.IN_OBJECT) {
+            throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        if (currentContext.scope == Scope.IN_NONE && !currentContext.first) {
+            throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_MULTIPLE_TEXT());
+        }
+        writeComma();
+        writeChar('{');
+        stack.push(currentContext);
+        currentContext = new Context(Scope.IN_OBJECT);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartObject(String name) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeChar('{');
+        stack.push(currentContext);
+        currentContext = new Context(Scope.IN_OBJECT);
+        return this;
+    }
+
+    private JsonGenerator writeName(String name) {
+        writeComma();
+        writeEscapedString(name);
+        writeChar(':');
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, String fieldValue) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeEscapedString(fieldValue);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, int value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeInt(value);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, long value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeString(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, double value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        if (Double.isInfinite(value) || Double.isNaN(value)) {
+            throw new NumberFormatException(JsonMessages.GENERATOR_DOUBLE_INFINITE_NAN());
+        }
+        writeName(name);
+        writeString(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, BigInteger value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeString(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, BigDecimal value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeString(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, boolean value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeString(value? "true" : "false");
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeNull(String name) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeString("null");
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(JsonValue value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        switch (value.getValueType()) {
+            case ARRAY:
+                JsonArray array = (JsonArray)value;
+                writeStartArray();
+                for(JsonValue child: array) {
+                    write(child);
+                }
+                writeEnd();
+                break;
+            case OBJECT:
+                JsonObject object = (JsonObject)value;
+                writeStartObject();
+                for(Map.Entry<String, JsonValue> member: object.entrySet()) {
+                    write(member.getKey(), member.getValue());
+                }
+                writeEnd();
+                break;
+            case STRING:
+                JsonString str = (JsonString)value;
+                write(str.getString());
+                break;
+            case NUMBER:
+                JsonNumber number = (JsonNumber)value;
+                writeValue(number.toString());
+                break;
+            case TRUE:
+                write(true);
+                break;
+            case FALSE:
+                write(false);
+                break;
+            case NULL:
+                writeNull();
+                break;
+        }
+
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartArray() {
+        if (currentContext.scope == Scope.IN_OBJECT) {
+            throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        if (currentContext.scope == Scope.IN_NONE && !currentContext.first) {
+            throw new JsonGenerationException(JsonMessages.GENERATOR_ILLEGAL_MULTIPLE_TEXT());
+        }
+        writeComma();
+        writeChar('[');
+        stack.push(currentContext);
+        currentContext = new Context(Scope.IN_ARRAY);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartArray(String name) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeName(name);
+        writeChar('[');
+        stack.push(currentContext);
+        currentContext = new Context(Scope.IN_ARRAY);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(String name, JsonValue value) {
+        if (currentContext.scope != Scope.IN_OBJECT) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        switch (value.getValueType()) {
+            case ARRAY:
+                JsonArray array = (JsonArray)value;
+                writeStartArray(name);
+                for(JsonValue child: array) {
+                    write(child);
+                }
+                writeEnd();
+                break;
+            case OBJECT:
+                JsonObject object = (JsonObject)value;
+                writeStartObject(name);
+                for(Map.Entry<String, JsonValue> member: object.entrySet()) {
+                    write(member.getKey(), member.getValue());
+                }
+                writeEnd();
+                break;
+            case STRING:
+                JsonString str = (JsonString)value;
+                write(name, str.getString());
+                break;
+            case NUMBER:
+                JsonNumber number = (JsonNumber)value;
+                writeValue(name, number.toString());
+                break;
+            case TRUE:
+                write(name, true);
+                break;
+            case FALSE:
+                write(name, false);
+                break;
+            case NULL:
+                writeNull(name);
+                break;
+        }
+        return this;
+    }
+
+    public JsonGenerator write(String value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeComma();
+        writeEscapedString(value);
+        return this;
+    }
+
+
+    public JsonGenerator write(int value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeComma();
+        writeInt(value);
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(long value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeValue(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(double value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        if (Double.isInfinite(value) || Double.isNaN(value)) {
+            throw new NumberFormatException(JsonMessages.GENERATOR_DOUBLE_INFINITE_NAN());
+        }
+        writeValue(String.valueOf(value));
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(BigInteger value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeValue(value.toString());
+        return this;
+    }
+
+    @Override
+    public JsonGenerator write(BigDecimal value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeValue(value.toString());
+        return this;
+    }
+
+    public JsonGenerator write(boolean value) {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeComma();
+        writeString(value ? "true" : "false");
+        return this;
+    }
+
+    public JsonGenerator writeNull() {
+        if (currentContext.scope != Scope.IN_ARRAY) {
+            throw new JsonGenerationException(
+                    JsonMessages.GENERATOR_ILLEGAL_METHOD(currentContext.scope));
+        }
+        writeComma();
+        writeString("null");
+        return this;
+    }
+
+    private void writeValue(String value) {
+        writeComma();
+        writeString(value);
+    }
+
+    private void writeValue(String name, String value) {
+        writeComma();
+        writeEscapedString(name);
+        writeChar(':');
+        writeString(value);
+    }
+
+    @Override
+    public JsonGenerator writeEnd() {
+        if (currentContext.scope == Scope.IN_NONE) {
+            throw new JsonGenerationException("writeEnd() cannot be called in no context");
+        }
+        writeChar(currentContext.scope == Scope.IN_ARRAY ? ']' : '}');
+        currentContext = stack.pop();
+        return this;
+    }
+
+    protected void writeComma() {
+        if (!currentContext.first) {
+            writeChar(',');
+        }
+        currentContext.first = false;
+    }
+
+    private static class Context {
+        boolean first = true;
+        final Scope scope;
+
+        Context(Scope scope) {
+            this.scope = scope;
+        }
+
+    }
+
+    public void close() {
+        if (currentContext.scope != Scope.IN_NONE || currentContext.first) {
+            throw new JsonGenerationException(JsonMessages.GENERATOR_INCOMPLETE_JSON());
+        }
+        flushBuffer();
+        try {
+            writer.close();
+        } catch (IOException ioe) {
+            throw new JsonException(JsonMessages.GENERATOR_CLOSE_IO_ERR(), ioe);
+        }
+        bufferPool.recycle(buf);
+    }
+
+    // begin, end-1 indexes represent characters that need not
+    // be escaped
+    //
+    // XXXssssssssssssXXXXXXXXXXXXXXXXXXXXXXrrrrrrrrrrrrrrXXXXXX
+    //    ^           ^                     ^             ^
+    //    |           |                     |             |
+    //   begin       end                   begin         end
+    void writeEscapedString(String string) {
+        writeChar('"');
+        int len = string.length();
+        for(int i = 0; i < len; i++) {
+            int begin = i, end = i;
+            char c = string.charAt(i);
+            // find all the characters that need not be escaped
+            // unescaped = %x20-21 | %x23-5B | %x5D-10FFFF
+            while(c >= 0x20 && c <= 0x10ffff && c != 0x22 && c != 0x5c) {
+                i++; end = i;
+                if (i < len) {
+                    c = string.charAt(i);
+                } else {
+                    break;
+                }
+            }
+            // Write characters without escaping
+            if (begin < end) {
+                writeString(string, begin, end);
+                if (i == len) {
+                    break;
+                }
+            }
+
+            switch (c) {
+                case '"':
+                case '\\':
+                    writeChar('\\'); writeChar(c);
+                    break;
+                case '\b':
+                    writeChar('\\'); writeChar('b');
+                    break;
+                case '\f':
+                    writeChar('\\'); writeChar('f');
+                    break;
+                case '\n':
+                    writeChar('\\'); writeChar('n');
+                    break;
+                case '\r':
+                    writeChar('\\'); writeChar('r');
+                    break;
+                case '\t':
+                    writeChar('\\'); writeChar('t');
+                    break;
+                default:
+                    String hex = "000" + Integer.toHexString(c);
+                    writeString("\\u" + hex.substring(hex.length() - 4));
+            }
+        }
+        writeChar('"');
+    }
+
+    void writeString(String str, int begin, int end) {
+        while (begin < end) {       // source begin and end indexes
+            int no = Math.min(buf.length - len, end - begin);
+            str.getChars(begin, begin + no, buf, len);
+            begin += no;            // Increment source index
+            len += no;              // Increment dest index
+            if (len >= buf.length) {
+                flushBuffer();
+            }
+        }
+    }
+
+    void writeString(String str) {
+        writeString(str, 0, str.length());
+    }
+
+    void writeChar(char c) {
+        if (len >= buf.length) {
+            flushBuffer();
+        }
+        buf[len++] = c;
+    }
+
+    // Not using Integer.toString() since it creates intermediary String
+    // Also, we want the chars to be copied to our buffer directly
+    void writeInt(int num) {
+        int size;
+        if (num == Integer.MIN_VALUE) {
+            size = INT_MIN_VALUE_CHARS.length;
+        } else {
+            size = (num < 0) ? stringSize(-num) + 1 : stringSize(num);
+        }
+        if (len+size >= buf.length) {
+            flushBuffer();
+        }
+        if (num == Integer.MIN_VALUE) {
+            System.arraycopy(INT_MIN_VALUE_CHARS, 0, buf, len, size);
+        } else {
+            fillIntChars(num, buf, len+size);
+        }
+        len += size;
+    }
+
+    // flushBuffer writes the buffered contents to writer. But incase of
+    // byte stream, an OuputStreamWriter is created and that buffers too.
+    // We may need to call OutputStreamWriter#flushBuffer() using
+    // reflection if that is really required (commented out below)
+    void flushBuffer() {
+        try {
+            if (len > 0) {
+                writer.write(buf, 0, len);
+                len = 0;
+            }
+        } catch (IOException ioe) {
+            throw new JsonException(JsonMessages.GENERATOR_WRITE_IO_ERR(), ioe);
+        }
+    }
+
+//    private static final Method flushBufferMethod;
+//    static {
+//        Method m = null;
+//        try {
+//            m = OutputStreamWriter.class.getDeclaredMethod("flushBuffer");
+//            m.setAccessible(true);
+//        } catch (Exception e) {
+//            // no-op
+//        }
+//        flushBufferMethod = m;
+//    }
+//    void flushBufferOSW() {
+//        flushBuffer();
+//        if (writer instanceof OutputStreamWriter) {
+//            try {
+//                flushBufferMethod.invoke(writer);
+//            } catch (Exception e) {
+//                // no-op
+//            }
+//        }
+//    }
+
+    // Requires positive x
+    private static int stringSize(int x) {
+        for (int i=0; ; i++)
+            if (x <= INT_CHARS_SIZE_TABLE[i])
+                return i+1;
+    }
+
+    /**
+     * Places characters representing the integer i into the
+     * character array buf. The characters are placed into
+     * the buffer backwards starting with the least significant
+     * digit at the specified index (exclusive), and working
+     * backwards from there.
+     *
+     * Will fail if i == Integer.MIN_VALUE
+     */
+    private static void fillIntChars(int i, char[] buf, int index) {
+        int q, r;
+        int charPos = index;
+        char sign = 0;
+
+        if (i < 0) {
+            sign = '-';
+            i = -i;
+        }
+
+        // Generate two digits per iteration
+        while (i >= 65536) {
+            q = i / 100;
+            // really: r = i - (q * 100);
+            r = i - ((q << 6) + (q << 5) + (q << 2));
+            i = q;
+            buf [--charPos] = DIGIT_ONES[r];
+            buf [--charPos] = DIGIT_TENS[r];
+        }
+
+        // Fall thru to fast mode for smaller numbers
+        // assert(i <= 65536, i);
+        for (;;) {
+            q = (i * 52429) >>> (16+3);
+            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ...
+            buf [--charPos] = DIGITS[r];
+            i = q;
+            if (i == 0) break;
+        }
+        if (sign != 0) {
+            buf [--charPos] = sign;
+        }
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonLocationImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonLocationImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonLocationImpl.java	(revision 6756)
@@ -0,0 +1,80 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.stream.JsonLocation;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonLocationImpl implements JsonLocation {
+    static final JsonLocation UNKNOWN = new JsonLocationImpl(-1, -1, -1);
+
+    private final long columnNo;
+    private final long lineNo;
+    private final long offset;
+
+    JsonLocationImpl(long lineNo, long columnNo, long streamOffset) {
+        this.lineNo = lineNo;
+        this.columnNo = columnNo;
+        this.offset = streamOffset;
+    }
+
+    @Override
+    public long getLineNumber() {
+        return lineNo;
+    }
+
+    @Override
+    public long getColumnNumber() {
+        return columnNo;
+    }
+
+    @Override
+    public long getStreamOffset() {
+        return offset;
+    }
+
+    public String toString() {
+        return "(line no="+lineNo+", column no="+columnNo+", offset="+ offset +")";
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonMessages.java
===================================================================
--- trunk/src/org/glassfish/json/JsonMessages.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonMessages.java	(revision 6756)
@@ -0,0 +1,214 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+/**
+ * Defines string formatting method for each constant in the resource file
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonMessages {
+    private static final ResourceBundle BUNDLE =
+            ResourceBundle.getBundle("org.glassfish.json.messages");
+
+    // tokenizer messages
+    static String TOKENIZER_UNEXPECTED_CHAR(int unexpected, JsonLocation location) {
+        return localize("tokenizer.unexpected.char", unexpected, location);
+    }
+
+    static String TOKENIZER_EXPECTED_CHAR(int unexpected, JsonLocation location, char expected) {
+        return localize("tokenizer.expected.char", unexpected, location, expected);
+    }
+
+    static String TOKENIZER_IO_ERR() {
+        return localize("tokenizer.io.err");
+    }
+
+
+    // parser messages
+    static String PARSER_GETSTRING_ERR(JsonParser.Event event) {
+        return localize("parser.getString.err", event);
+    }
+
+    static String PARSER_ISINTEGRALNUMBER_ERR(JsonParser.Event event) {
+        return localize("parser.isIntegralNumber.err", event);
+    }
+
+    static String PARSER_GETINT_ERR(JsonParser.Event event) {
+        return localize("parser.getInt.err", event);
+    }
+
+    static String PARSER_GETLONG_ERR(JsonParser.Event event) {
+        return localize("parser.getLong.err", event);
+    }
+
+    static String PARSER_GETBIGDECIMAL_ERR(JsonParser.Event event) {
+        return localize("parser.getBigDecimal.err", event);
+    }
+
+    static String PARSER_EXPECTED_EOF(JsonTokenizer.JsonToken token) {
+        return localize("parser.expected.eof", token);
+    }
+
+    static String PARSER_TOKENIZER_CLOSE_IO() {
+        return localize("parser.tokenizer.close.io");
+    }
+
+    static String PARSER_INVALID_TOKEN(JsonTokenizer.JsonToken token, JsonLocation location, String expectedTokens) {
+        return localize("parser.invalid.token", token, location, expectedTokens);
+    }
+
+
+    // generator messages
+    static String GENERATOR_FLUSH_IO_ERR() {
+        return localize("generator.flush.io.err");
+    }
+
+    static String GENERATOR_CLOSE_IO_ERR() {
+        return localize("generator.close.io.err");
+    }
+
+    static String GENERATOR_WRITE_IO_ERR() {
+        return localize("generator.write.io.err");
+    }
+
+    static String GENERATOR_ILLEGAL_METHOD(Object scope) {
+        return localize("generator.illegal.method", scope);
+    }
+
+    static String GENERATOR_DOUBLE_INFINITE_NAN() {
+        return localize("generator.double.infinite.nan");
+    }
+
+    static String GENERATOR_INCOMPLETE_JSON() {
+        return localize("generator.incomplete.json");
+    }
+
+    static String GENERATOR_ILLEGAL_MULTIPLE_TEXT() {
+        return localize("generator.illegal.multiple.text");
+    }
+
+
+
+    // writer messages
+    static String WRITER_WRITE_ALREADY_CALLED() {
+        return localize("writer.write.already.called");
+    }
+
+
+    // reader messages
+    static String READER_READ_ALREADY_CALLED() {
+        return localize("reader.read.already.called");
+    }
+
+    static String READER_EXPECTED_ARRAY_GOT_OBJECT() {
+        return localize("reader.expected.array.got.object");
+    }
+
+    static String READER_EXPECTED_OBJECT_GOT_ARRAY() {
+        return localize("reader.expected.object.got.array");
+    }
+
+
+    // obj builder messages
+    static String OBJBUILDER_NAME_NULL() {
+        return localize("objbuilder.name.null");
+    }
+
+    static String OBJBUILDER_VALUE_NULL() {
+        return localize("objbuilder.value.null");
+    }
+
+    static String OBJBUILDER_OBJECT_BUILDER_NULL() {
+        return localize("objbuilder.object.builder.null");
+    }
+
+    static String OBJBUILDER_ARRAY_BUILDER_NULL() {
+        return localize("objbuilder.array.builder.null");
+    }
+
+
+    // array builder messages
+    static String ARRBUILDER_VALUE_NULL() {
+        return localize("arrbuilder.value.null");
+    }
+
+    static String ARRBUILDER_OBJECT_BUILDER_NULL() {
+        return localize("arrbuilder.object.builder.null");
+    }
+
+    static String ARRBUILDER_ARRAY_BUILDER_NULL() {
+        return localize("arrbuilder.array.builder.null");
+    }
+
+
+    private static String localize(String key, Object ... args) {
+        try {
+            String msg = BUNDLE.getString(key);
+            return MessageFormat.format(msg, args);
+        } catch (Exception e) {
+            return getDefaultMessage(key, args);
+        }
+    }
+
+    private static String getDefaultMessage(String key, Object ... args) {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[failed to localize] ");
+        sb.append(key);
+        if (args != null) {
+            sb.append('(');
+            for (int i = 0; i < args.length; ++i) {
+                if (i != 0)
+                    sb.append(", ");
+                sb.append(String.valueOf(args[i]));
+            }
+            sb.append(')');
+        }
+        return sb.toString();
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonNumberImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonNumberImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonNumberImpl.java	(revision 6756)
@@ -0,0 +1,260 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonNumber;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+
+/**
+ * JsonNumber impl. Subclasses provide optimized implementations
+ * when backed by int, long, BigDecimal
+ *
+ * @author Jitendra Kotamraju
+ */
+abstract class JsonNumberImpl implements JsonNumber {
+
+    static JsonNumber getJsonNumber(int num) {
+        return new JsonIntNumber(num);
+    }
+
+    static JsonNumber getJsonNumber(long num) {
+        return new JsonLongNumber(num);
+    }
+
+    static JsonNumber getJsonNumber(BigInteger value) {
+        return new JsonBigDecimalNumber(new BigDecimal(value));
+    }
+
+    static JsonNumber getJsonNumber(double value) {
+        //bigDecimal = new BigDecimal(value);
+        // This is the preferred way to convert double to BigDecimal
+        return new JsonBigDecimalNumber(BigDecimal.valueOf(value));
+    }
+
+    static JsonNumber getJsonNumber(BigDecimal value) {
+        return new JsonBigDecimalNumber(value);
+    }
+
+    // Optimized JsonNumber impl for int numbers.
+    private static final class JsonIntNumber extends JsonNumberImpl {
+        private final int num;
+        private BigDecimal bigDecimal;  // assigning it lazily on demand
+
+        JsonIntNumber(int num) {
+            this.num = num;
+        }
+
+        @Override
+        public boolean isIntegral() {
+            return true;
+        }
+
+        @Override
+        public int intValue() {
+            return num;
+        }
+
+        @Override
+        public int intValueExact() {
+            return num;
+        }
+
+        @Override
+        public long longValue() {
+            return num;
+        }
+
+        @Override
+        public long longValueExact() {
+            return num;
+        }
+
+        @Override
+        public double doubleValue() {
+            return num;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            // reference assignments are atomic. At the most some more temp
+            // BigDecimal objects are created
+            BigDecimal bd = bigDecimal;
+            if (bd == null) {
+                bigDecimal = bd = new BigDecimal(num);
+            }
+            return bd;
+        }
+
+        @Override
+        public String toString() {
+            return Integer.toString(num);
+        }
+    }
+
+    // Optimized JsonNumber impl for long numbers.
+    private static final class JsonLongNumber extends JsonNumberImpl {
+        private final long num;
+        private BigDecimal bigDecimal;  // assigning it lazily on demand
+
+        JsonLongNumber(long num) {
+            this.num = num;
+        }
+
+        @Override
+        public boolean isIntegral() {
+            return true;
+        }
+
+        @Override
+        public long longValue() {
+            return num;
+        }
+
+        @Override
+        public long longValueExact() {
+            return num;
+        }
+
+        @Override
+        public double doubleValue() {
+            return num;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            // reference assignments are atomic. At the most some more temp
+            // BigDecimal objects are created
+            BigDecimal bd = bigDecimal;
+            if (bd == null) {
+                bigDecimal = bd = new BigDecimal(num);
+            }
+            return bd;
+        }
+
+        @Override
+        public String toString() {
+            return Long.toString(num);
+        }
+
+    }
+
+    // JsonNumber impl using BigDecimal numbers.
+    private static final class JsonBigDecimalNumber extends JsonNumberImpl {
+        private final BigDecimal bigDecimal;
+
+        JsonBigDecimalNumber(BigDecimal value) {
+            this.bigDecimal = value;
+        }
+
+        @Override
+        public BigDecimal bigDecimalValue() {
+            return bigDecimal;
+        }
+
+    }
+
+    @Override
+    public boolean isIntegral() {
+        return bigDecimalValue().scale() == 0;
+    }
+
+    @Override
+    public int intValue() {
+        return bigDecimalValue().intValue();
+    }
+
+    @Override
+    public int intValueExact() {
+        return bigDecimalValue().intValueExact();
+    }
+
+    @Override
+    public long longValue() {
+        return bigDecimalValue().longValue();
+    }
+
+    @Override
+    public long longValueExact() {
+        return bigDecimalValue().longValueExact();
+    }
+
+    @Override
+    public double doubleValue() {
+        return bigDecimalValue().doubleValue();
+    }
+
+    @Override
+    public BigInteger bigIntegerValue() {
+        return bigDecimalValue().toBigInteger();
+    }
+
+    @Override
+    public BigInteger bigIntegerValueExact() {
+        return bigDecimalValue().toBigIntegerExact();
+    }
+
+    @Override
+    public ValueType getValueType() {
+        return ValueType.NUMBER;
+    }
+
+    @Override
+    public int hashCode() {
+        return bigDecimalValue().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof JsonNumber)) {
+            return false;
+        }
+        JsonNumber other = (JsonNumber)obj;
+        return bigDecimalValue().equals(other.bigDecimalValue());
+    }
+
+    @Override
+    public String toString() {
+        return bigDecimalValue().toString();
+    }
+
+}
+
Index: trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonObjectBuilderImpl.java	(revision 6756)
@@ -0,0 +1,273 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonArrayBuilder;
+import javax.json.*;
+import java.io.StringWriter;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.*;
+
+/**
+ * JsonObjectBuilder impl
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonObjectBuilderImpl implements JsonObjectBuilder {
+    private Map<String, JsonValue> valueMap;
+    private final BufferPool bufferPool;
+
+    JsonObjectBuilderImpl(BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+    }
+
+    public JsonObjectBuilder add(String name, JsonValue value) {
+        validateName(name);
+        validateValue(value);
+        putValueMap(name, value);
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, String value) {
+        validateName(name);
+        validateValue(value);
+        putValueMap(name, new JsonStringImpl(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, BigInteger value) {
+        validateName(name);
+        validateValue(value);
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, BigDecimal value) {
+        validateName(name);
+        validateValue(value);
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, int value) {
+        validateName(name);
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, long value) {
+        validateName(name);
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, double value) {
+        validateName(name);
+        putValueMap(name, JsonNumberImpl.getJsonNumber(value));
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, boolean value) {
+        validateName(name);
+        putValueMap(name, value ? JsonValue.TRUE : JsonValue.FALSE);
+        return this;
+    }
+
+    public JsonObjectBuilder addNull(String name) {
+        validateName(name);
+        putValueMap(name, JsonValue.NULL);
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, JsonObjectBuilder builder) {
+        validateName(name);
+        if (builder == null) {
+            throw new NullPointerException(JsonMessages.OBJBUILDER_OBJECT_BUILDER_NULL());
+        }
+        putValueMap(name, builder.build());
+        return this;
+    }
+
+    public JsonObjectBuilder add(String name, JsonArrayBuilder builder) {
+        validateName(name);
+        if (builder == null) {
+            throw new NullPointerException(JsonMessages.OBJBUILDER_ARRAY_BUILDER_NULL());
+        }
+        putValueMap(name, builder.build());
+        return this;
+    }
+
+    public JsonObject build() {
+        Map<String, JsonValue> snapshot = (valueMap == null)
+                ? Collections.<String, JsonValue>emptyMap()
+                : Collections.unmodifiableMap(valueMap);
+        valueMap = null;
+        return new JsonObjectImpl(snapshot, bufferPool);
+    }
+
+    private void putValueMap(String name, JsonValue value) {
+        if (valueMap == null) {
+            this.valueMap = new LinkedHashMap<String, JsonValue>();
+        }
+        valueMap.put(name, value);
+    }
+
+    private void validateName(String name) {
+        if (name == null) {
+            throw new NullPointerException(JsonMessages.OBJBUILDER_NAME_NULL());
+        }
+    }
+
+    private void validateValue(Object value) {
+        if (value == null) {
+            throw new NullPointerException(JsonMessages.OBJBUILDER_VALUE_NULL());
+        }
+    }
+
+    private static final class JsonObjectImpl extends AbstractMap<String, JsonValue> implements JsonObject {
+        private final Map<String, JsonValue> valueMap;      // unmodifiable
+        private final BufferPool bufferPool;
+
+        JsonObjectImpl(Map<String, JsonValue> valueMap, BufferPool bufferPool) {
+            this.valueMap = valueMap;
+            this.bufferPool = bufferPool;
+        }
+
+        @Override
+        public JsonArray getJsonArray(String name) {
+            return (JsonArray)get(name);
+        }
+
+        @Override
+        public JsonObject getJsonObject(String name) {
+            return (JsonObject)get(name);
+        }
+
+        @Override
+        public JsonNumber getJsonNumber(String name) {
+            return (JsonNumber)get(name);
+        }
+
+        @Override
+        public JsonString getJsonString(String name) {
+            return (JsonString)get(name);
+        }
+
+        @Override
+        public String getString(String name) {
+            return getJsonString(name).getString();
+        }
+
+        @Override
+        public String getString(String name, String defaultValue) {
+            try {
+                return getString(name);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public int getInt(String name) {
+            return getJsonNumber(name).intValue();
+        }
+
+        @Override
+        public int getInt(String name, int defaultValue) {
+            try {
+                return getInt(name);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public boolean getBoolean(String name) {
+            JsonValue value = get(name);
+            if (value == null) {
+                throw new NullPointerException();
+            } else if (value == JsonValue.TRUE) {
+                return true;
+            } else if (value == JsonValue.FALSE) {
+                return false;
+            } else {
+                throw new ClassCastException();
+            }
+        }
+
+        @Override
+        public boolean getBoolean(String name, boolean defaultValue) {
+            try {
+                return getBoolean(name);
+            } catch (Exception e) {
+                return defaultValue;
+            }
+        }
+
+        @Override
+        public boolean isNull(String name) {
+            return get(name).equals(JsonValue.NULL);
+        }
+
+        @Override
+        public ValueType getValueType() {
+            return ValueType.OBJECT;
+        }
+
+        @Override
+        public Set<Entry<String, JsonValue>> entrySet() {
+            return valueMap.entrySet();
+        }
+
+        @Override
+        public String toString() {
+            StringWriter sw = new StringWriter();
+            JsonWriter jw = new JsonWriterImpl(sw, bufferPool);
+            jw.write(this);
+            jw.close();
+            return sw.toString();
+        }
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonParserFactoryImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonParserFactoryImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonParserFactoryImpl.java	(revision 6756)
@@ -0,0 +1,95 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonArray;
+import javax.json.JsonObject;
+import javax.json.stream.JsonParserFactory;
+import javax.json.stream.JsonParser;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonParserFactoryImpl implements JsonParserFactory {
+    private final Map<String, ?> config = Collections.emptyMap();
+    private final BufferPool bufferPool;
+
+    JsonParserFactoryImpl(BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonParser createParser(Reader reader) {
+        return new JsonParserImpl(reader, bufferPool);
+    }
+
+    @Override
+    public JsonParser createParser(InputStream in) {
+        return new JsonParserImpl(in, bufferPool);
+    }
+
+    @Override
+    public JsonParser createParser(InputStream in, Charset charset) {
+        return new JsonParserImpl(in, charset, bufferPool);
+    }
+
+    @Override
+    public JsonParser createParser(JsonArray array) {
+        return new JsonStructureParser(array);
+    }
+
+    @Override
+    public Map<String, ?> getConfigInUse() {
+        return config;
+    }
+
+    @Override
+    public JsonParser createParser(JsonObject object) {
+        return new JsonStructureParser(object);
+    }
+}
Index: trunk/src/org/glassfish/json/JsonParserImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonParserImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonParserImpl.java	(revision 6756)
@@ -0,0 +1,332 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.*;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import java.io.*;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+import java.util.*;
+
+import org.glassfish.json.JsonTokenizer.JsonToken;
+import org.glassfish.json.api.BufferPool;
+
+/**
+ * JSON parser implementation. NoneContext, ArrayContext, ObjectContext is used
+ * to go to next parser state.
+ *
+ * @author Jitendra Kotamraju
+ */
+public class JsonParserImpl implements JsonParser {
+
+    private Context currentContext = new NoneContext();
+    private Event currentEvent;
+
+    private final Stack stack = new Stack();
+    private final StateIterator stateIterator;
+    private final JsonTokenizer tokenizer;
+
+    public JsonParserImpl(Reader reader, BufferPool bufferPool) {
+        tokenizer = new JsonTokenizer(reader, bufferPool);
+        stateIterator = new StateIterator();
+    }
+
+    public JsonParserImpl(InputStream in, BufferPool bufferPool) {
+        UnicodeDetectingInputStream uin = new UnicodeDetectingInputStream(in);
+        tokenizer = new JsonTokenizer(new InputStreamReader(uin, uin.getCharset()), bufferPool);
+        stateIterator = new StateIterator();
+    }
+
+    public JsonParserImpl(InputStream in, Charset encoding, BufferPool bufferPool) {
+        tokenizer = new JsonTokenizer(new InputStreamReader(in, encoding), bufferPool);
+        stateIterator = new StateIterator();
+    }
+
+    public String getString() {
+        if (currentEvent == Event.KEY_NAME || currentEvent == Event.VALUE_STRING
+                || currentEvent == Event.VALUE_NUMBER) {
+            return tokenizer.getValue();
+        }
+        throw new IllegalStateException(
+                JsonMessages.PARSER_GETSTRING_ERR(currentEvent));
+    }
+
+    @Override
+    public boolean isIntegralNumber() {
+        if (currentEvent != Event.VALUE_NUMBER) {
+            throw new IllegalStateException(
+                    JsonMessages.PARSER_ISINTEGRALNUMBER_ERR(currentEvent));
+        }
+        return tokenizer.isIntegral();
+    }
+
+    @Override
+    public int getInt() {
+        if (currentEvent != Event.VALUE_NUMBER) {
+            throw new IllegalStateException(
+                    JsonMessages.PARSER_GETINT_ERR(currentEvent));
+        }
+        return tokenizer.getInt();
+    }
+
+    boolean isDefinitelyInt() {
+        return tokenizer.isDefinitelyInt();
+    }
+
+    @Override
+    public long getLong() {
+        if (currentEvent != Event.VALUE_NUMBER) {
+            throw new IllegalStateException(
+                    JsonMessages.PARSER_GETLONG_ERR(currentEvent));
+        }
+        return tokenizer.getBigDecimal().longValue();
+    }
+
+    @Override
+    public BigDecimal getBigDecimal() {
+        if (currentEvent != Event.VALUE_NUMBER) {
+            throw new IllegalStateException(
+                    JsonMessages.PARSER_GETBIGDECIMAL_ERR(currentEvent));
+        }
+        return tokenizer.getBigDecimal();
+    }
+
+    @Override
+    public JsonLocation getLocation() {
+        return tokenizer.getLocation();
+    }
+
+    public JsonLocation getLastCharLocation() {
+        return tokenizer.getLastCharLocation();
+    }
+
+    public boolean hasNext() {
+        return stateIterator.hasNext();
+    }
+
+    public Event next() {
+        return stateIterator.next();
+    }
+
+    private class StateIterator implements  Iterator<JsonParser.Event> {
+
+        @Override
+        public boolean hasNext() {
+            if (stack.isEmpty() && (currentEvent == Event.END_ARRAY || currentEvent == Event.END_OBJECT)) {
+                JsonToken token = tokenizer.nextToken();
+                if (token != JsonToken.EOF) {
+                    throw new JsonParsingException(JsonMessages.PARSER_EXPECTED_EOF(token),
+                            getLastCharLocation());
+                }
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public JsonParser.Event next() {
+            if (!hasNext()) {
+                throw new NoSuchElementException();
+            }
+            return currentEvent = currentContext.getNextEvent();
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    public void close() {
+        try {
+            tokenizer.close();
+        } catch (IOException e) {
+            throw new JsonException(JsonMessages.PARSER_TOKENIZER_CLOSE_IO(), e);
+        }
+    }
+
+    // Using the optimized stack impl as we don't require other things
+    // like iterator etc.
+    private static final class Stack {
+        private Context head;
+
+        private void push(Context context) {
+            context.next = head;
+            head = context;
+        }
+
+        private Context pop() {
+            if (head == null) {
+                throw new NoSuchElementException();
+            }
+            Context temp = head;
+            head = head.next;
+            return temp;
+        }
+
+        private boolean isEmpty() {
+            return head == null;
+        }
+    }
+
+    private abstract class Context {
+        Context next;
+        abstract Event getNextEvent();
+    }
+
+    private final class NoneContext extends Context {
+        @Override
+        public Event getNextEvent() {
+            // Handle 1. {     2. [
+            JsonToken token = tokenizer.nextToken();
+            if (token == JsonToken.CURLYOPEN) {
+                stack.push(currentContext);
+                currentContext = new ObjectContext();
+                return Event.START_OBJECT;
+            } else if (token == JsonToken.SQUAREOPEN) {
+                stack.push(currentContext);
+                currentContext = new ArrayContext();
+                return Event.START_ARRAY;
+            }
+            throw parsingException(token, "[CURLYOPEN, SQUAREOPEN]");
+        }
+    }
+
+    private JsonParsingException parsingException(JsonToken token, String expectedTokens) {
+        JsonLocation location = getLastCharLocation();
+        return new JsonParsingException(
+                JsonMessages.PARSER_INVALID_TOKEN(token, location, expectedTokens), location);
+    }
+
+    private final class ObjectContext extends Context {
+        private boolean firstValue = true;
+
+        /*
+         * Some more things could be optimized. For example, instead
+         * tokenizer.nextToken(), one could use tokenizer.matchColonToken() to
+         * match ':'. That might optimize a bit, but will fragment nextToken().
+         * I think the current one is more readable.
+         *
+         */
+        @Override
+        public Event getNextEvent() {
+            // Handle 1. }   2. name:value   3. ,name:value
+            JsonToken token = tokenizer.nextToken();
+            if (currentEvent == Event.KEY_NAME) {
+                // Handle 1. :value
+                if (token != JsonToken.COLON) {
+                    throw parsingException(token, "[COLON]");
+                }
+                token = tokenizer.nextToken();
+                if (token.isValue()) {
+                    return token.getEvent();
+                } else if (token == JsonToken.CURLYOPEN) {
+                    stack.push(currentContext);
+                    currentContext = new ObjectContext();
+                    return Event.START_OBJECT;
+                } else if (token == JsonToken.SQUAREOPEN) {
+                    stack.push(currentContext);
+                    currentContext = new ArrayContext();
+                    return Event.START_ARRAY;
+                }
+                throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]");
+            } else {
+                // Handle 1. }   2. name   3. ,name
+                if (token == JsonToken.CURLYCLOSE) {
+                    currentContext = stack.pop();
+                    return Event.END_OBJECT;
+                }
+                if (firstValue) {
+                    firstValue = false;
+                } else {
+                    if (token != JsonToken.COMMA) {
+                        throw parsingException(token, "[COMMA]");
+                    }
+                    token = tokenizer.nextToken();
+                }
+                if (token == JsonToken.STRING) {
+                    return Event.KEY_NAME;
+                }
+                throw parsingException(token, "[STRING]");
+            }
+        }
+
+    }
+
+    private final class ArrayContext extends Context {
+        private boolean firstValue = true;
+
+        // Handle 1. ]   2. value   3. ,value
+        @Override
+        public Event getNextEvent() {
+            JsonToken token = tokenizer.nextToken();
+            if (token == JsonToken.SQUARECLOSE) {
+                currentContext = stack.pop();
+                return Event.END_ARRAY;
+            }
+            if (firstValue) {
+                firstValue = false;
+            } else {
+                if (token != JsonToken.COMMA) {
+                    throw parsingException(token, "[COMMA]");
+                }
+                token = tokenizer.nextToken();
+            }
+            if (token.isValue()) {
+                return token.getEvent();
+            } else if (token == JsonToken.CURLYOPEN) {
+                stack.push(currentContext);
+                currentContext = new ObjectContext();
+                return Event.START_OBJECT;
+            } else if (token == JsonToken.SQUAREOPEN) {
+                stack.push(currentContext);
+                currentContext = new ArrayContext();
+                return Event.START_ARRAY;
+            }
+            throw parsingException(token, "[CURLYOPEN, SQUAREOPEN, STRING, NUMBER, TRUE, FALSE, NULL]");
+        }
+
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonPrettyGeneratorImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonPrettyGeneratorImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonPrettyGeneratorImpl.java	(revision 6756)
@@ -0,0 +1,122 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.stream.JsonGenerator;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonPrettyGeneratorImpl extends JsonGeneratorImpl {
+    private int indentLevel;
+    private static final String INDENT = "    ";
+
+    public JsonPrettyGeneratorImpl(Writer writer, BufferPool bufferPool) {
+        super(writer, bufferPool);
+    }
+
+    public JsonPrettyGeneratorImpl(OutputStream out, BufferPool bufferPool) {
+        super(out, bufferPool);
+    }
+
+    public JsonPrettyGeneratorImpl(OutputStream out, Charset encoding, BufferPool bufferPool) {
+        super(out, encoding, bufferPool);
+    }
+
+    @Override
+    public JsonGenerator writeStartObject() {
+        super.writeStartObject();
+        indentLevel++;
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartObject(String name) {
+        super.writeStartObject(name);
+        indentLevel++;
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartArray() {
+        super.writeStartArray();
+        indentLevel++;
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeStartArray(String name) {
+        super.writeStartArray(name);
+        indentLevel++;
+        return this;
+    }
+
+    @Override
+    public JsonGenerator writeEnd() {
+        writeNewLine();
+        indentLevel--;
+        writeIndent();
+        super.writeEnd();
+        return this;
+    }
+
+    private void writeIndent() {
+        for(int i=0; i < indentLevel; i++) {
+            writeString(INDENT);
+        }
+    }
+
+    @Override
+    protected void writeComma() {
+        super.writeComma();
+        writeChar('\n');
+        writeIndent();
+    }
+
+    private void writeNewLine() {
+        writeChar('\n');
+    }
+}
Index: trunk/src/org/glassfish/json/JsonProviderImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonProviderImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonProviderImpl.java	(revision 6756)
@@ -0,0 +1,206 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonGenerator;
+import javax.json.stream.JsonGeneratorFactory;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParserFactory;
+import javax.json.spi.JsonProvider;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+public class JsonProviderImpl extends JsonProvider {
+
+    private final BufferPool bufferPool = new BufferPoolImpl();
+
+    @Override
+    public JsonGenerator createGenerator(Writer writer) {
+        return new JsonGeneratorImpl(writer, bufferPool);
+    }
+
+    @Override
+    public JsonGenerator createGenerator(OutputStream out) {
+        return new JsonGeneratorImpl(out, bufferPool);
+    }
+
+    @Override
+    public JsonParser createParser(Reader reader) {
+        return new JsonParserImpl(reader, bufferPool);
+    }
+
+    @Override
+    public JsonParser createParser(InputStream in) {
+        return new JsonParserImpl(in, bufferPool);
+    }
+
+    @Override
+    public JsonParserFactory createParserFactory(Map<String, ?> config) {
+        BufferPool pool = null;
+        if (config != null && config.containsKey(BufferPool.class.getName())) {
+            pool = (BufferPool)config.get(BufferPool.class.getName());
+        }
+        if (pool == null) {
+            pool = bufferPool;
+        }
+        return new JsonParserFactoryImpl(pool);
+    }
+
+    @Override
+    public JsonGeneratorFactory createGeneratorFactory(Map<String, ?> config) {
+        Map<String, Object> providerConfig;
+        boolean prettyPrinting;
+        BufferPool pool;
+        if (config == null) {
+            providerConfig = Collections.emptyMap();
+            prettyPrinting = false;
+            pool = bufferPool;
+        } else {
+            providerConfig = new HashMap<String, Object>();
+            if (prettyPrinting=JsonProviderImpl.isPrettyPrintingEnabled(config)) {
+                providerConfig.put(JsonGenerator.PRETTY_PRINTING, true);
+            }
+            pool = (BufferPool)config.get(BufferPool.class.getName());
+            if (pool != null) {
+                providerConfig.put(BufferPool.class.getName(), pool);
+            } else {
+                pool = bufferPool;
+            }
+            providerConfig = Collections.unmodifiableMap(providerConfig);
+        }
+
+        return new JsonGeneratorFactoryImpl(providerConfig, prettyPrinting, pool);
+    }
+
+    @Override
+    public JsonReader createReader(Reader reader) {
+        return new JsonReaderImpl(reader, bufferPool);
+    }
+
+    @Override
+    public JsonReader createReader(InputStream in) {
+        return new JsonReaderImpl(in, bufferPool);
+    }
+
+    @Override
+    public JsonWriter createWriter(Writer writer) {
+        return new JsonWriterImpl(writer, bufferPool);
+    }
+
+    @Override
+    public JsonWriter createWriter(OutputStream out) {
+        return new JsonWriterImpl(out, bufferPool);
+    }
+
+    @Override
+    public JsonWriterFactory createWriterFactory(Map<String, ?> config) {
+        Map<String, Object> providerConfig;
+        boolean prettyPrinting;
+        BufferPool pool;
+        if (config == null) {
+            providerConfig = Collections.emptyMap();
+            prettyPrinting = false;
+            pool = bufferPool;
+        } else {
+            providerConfig = new HashMap<String, Object>();
+            if (prettyPrinting=JsonProviderImpl.isPrettyPrintingEnabled(config)) {
+                providerConfig.put(JsonGenerator.PRETTY_PRINTING, true);
+            }
+            pool = (BufferPool)config.get(BufferPool.class.getName());
+            if (pool != null) {
+                providerConfig.put(BufferPool.class.getName(), pool);
+            } else {
+                pool = bufferPool;
+            }
+            providerConfig = Collections.unmodifiableMap(providerConfig);
+        }
+        return new JsonWriterFactoryImpl(providerConfig, prettyPrinting, pool);
+    }
+
+    @Override
+    public JsonReaderFactory createReaderFactory(Map<String, ?> config) {
+        BufferPool pool = null;
+        if (config != null && config.containsKey(BufferPool.class.getName())) {
+            pool = (BufferPool)config.get(BufferPool.class.getName());
+        }
+        if (pool == null) {
+            pool = bufferPool;
+        }
+        return new JsonReaderFactoryImpl(pool);
+    }
+
+    @Override
+    public JsonObjectBuilder createObjectBuilder() {
+        return new JsonObjectBuilderImpl(bufferPool);
+    }
+
+    @Override
+    public JsonArrayBuilder createArrayBuilder() {
+        return new JsonArrayBuilderImpl(bufferPool);
+    }
+
+    @Override
+    public JsonBuilderFactory createBuilderFactory(Map<String,?> config) {
+        BufferPool pool = null ;
+        if (config != null && config.containsKey(BufferPool.class.getName())) {
+            pool = (BufferPool)config.get(BufferPool.class.getName());
+        }
+        if (pool == null) {
+            pool = bufferPool;
+        }
+        return new JsonBuilderFactoryImpl(pool);
+    }
+
+    static boolean isPrettyPrintingEnabled(Map<String, ?> config) {
+        return config.containsKey(JsonGenerator.PRETTY_PRINTING);
+    }
+}
Index: trunk/src/org/glassfish/json/JsonReaderFactoryImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonReaderFactoryImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonReaderFactoryImpl.java	(revision 6756)
@@ -0,0 +1,83 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonReader;
+import javax.json.JsonReaderFactory;
+import java.io.InputStream;
+import java.io.Reader;
+import java.nio.charset.Charset;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonReaderFactoryImpl implements JsonReaderFactory {
+    private final Map<String, ?> config = Collections.emptyMap();
+    private final BufferPool bufferPool;
+
+    JsonReaderFactoryImpl(BufferPool bufferPool) {
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonReader createReader(Reader reader) {
+        return new JsonReaderImpl(reader, bufferPool);
+    }
+
+    @Override
+    public JsonReader createReader(InputStream in) {
+        return new JsonReaderImpl(in, bufferPool);
+    }
+
+    @Override
+    public JsonReader createReader(InputStream in, Charset charset) {
+        return new JsonReaderImpl(in, charset, bufferPool);
+    }
+
+    @Override
+    public Map<String, ?> getConfigInUse() {
+        return config;
+    }
+}
Index: trunk/src/org/glassfish/json/JsonReaderImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonReaderImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonReaderImpl.java	(revision 6756)
@@ -0,0 +1,218 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import javax.json.stream.JsonParser;
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.nio.charset.Charset;
+
+/**
+ * JsonReader impl using parser and builders.
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonReaderImpl implements JsonReader {
+    private final JsonParserImpl parser;
+    private boolean readDone;
+    private final BufferPool bufferPool;
+
+    JsonReaderImpl(Reader reader, BufferPool bufferPool) {
+        parser = new JsonParserImpl(reader, bufferPool);
+        this.bufferPool = bufferPool;
+    }
+
+    JsonReaderImpl(InputStream in, BufferPool bufferPool) {
+        parser = new JsonParserImpl(in, bufferPool);
+        this.bufferPool = bufferPool;
+    }
+
+    JsonReaderImpl(InputStream in, Charset charset, BufferPool bufferPool) {
+        parser = new JsonParserImpl(in, charset, bufferPool);
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonStructure read() {
+        if (readDone) {
+            throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+        }
+        readDone = true;
+        if (parser.hasNext()) {
+            JsonParser.Event e = parser.next();
+            if (e == JsonParser.Event.START_ARRAY) {
+                return readArray(new JsonArrayBuilderImpl(bufferPool));
+            } else if (e == JsonParser.Event.START_OBJECT) {
+                return readObject(new JsonObjectBuilderImpl(bufferPool));
+            }
+        }
+        throw new JsonException("Internal Error");
+    }
+
+    @Override
+    public JsonObject readObject() {
+        if (readDone) {
+            throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+        }
+        readDone = true;
+        if (parser.hasNext()) {
+            JsonParser.Event e = parser.next();
+            if (e == JsonParser.Event.START_OBJECT) {
+                return readObject(new JsonObjectBuilderImpl(bufferPool));
+            } else if (e == JsonParser.Event.START_ARRAY) {
+                throw new JsonException(JsonMessages.READER_EXPECTED_OBJECT_GOT_ARRAY());
+            }
+        }
+        throw new JsonException("Internal Error");
+    }
+
+    @Override
+    public JsonArray readArray() {
+        if (readDone) {
+            throw new IllegalStateException(JsonMessages.READER_READ_ALREADY_CALLED());
+        }
+        readDone = true;
+        if (parser.hasNext()) {
+            JsonParser.Event e = parser.next();
+            if (e == JsonParser.Event.START_ARRAY) {
+                return readArray(new JsonArrayBuilderImpl(bufferPool));
+            } else if (e == JsonParser.Event.START_OBJECT) {
+                throw new JsonException(JsonMessages.READER_EXPECTED_ARRAY_GOT_OBJECT());
+            }
+        }
+        throw new JsonException("Internal Error");
+    }
+
+    @Override
+    public void close() {
+        readDone = true;
+        parser.close();
+    }
+
+    private JsonArray readArray(JsonArrayBuilder builder) {
+        while(parser.hasNext()) {
+            JsonParser.Event e = parser.next();
+            switch (e) {
+                case START_ARRAY:
+                    JsonArray array = readArray(new JsonArrayBuilderImpl(bufferPool));
+                    builder.add(array);
+                    break;
+                case START_OBJECT:
+                    JsonObject object = readObject(new JsonObjectBuilderImpl(bufferPool));
+                    builder.add(object);
+                    break;
+                case VALUE_STRING:
+                    builder.add(parser.getString());
+                    break;
+                case VALUE_NUMBER:
+                    if (parser.isDefinitelyInt()) {
+                        builder.add(parser.getInt());
+                    } else {
+                        builder.add(parser.getBigDecimal());
+                    }
+                    break;
+                case VALUE_TRUE:
+                    builder.add(JsonValue.TRUE);
+                    break;
+                case VALUE_FALSE:
+                    builder.add(JsonValue.FALSE);
+                    break;
+                case VALUE_NULL:
+                    builder.addNull();
+                    break;
+                case END_ARRAY:
+                    return builder.build();
+                default:
+                    throw new JsonException("Internal Error");
+            }
+        }
+        throw new JsonException("Internal Error");
+    }
+
+    private JsonObject readObject(JsonObjectBuilder builder) {
+        String key = null;
+        while(parser.hasNext()) {
+            JsonParser.Event e = parser .next();
+            switch (e) {
+                case START_ARRAY:
+                    JsonArray array = readArray(new JsonArrayBuilderImpl(bufferPool));
+                    builder.add(key, array);
+                    break;
+                case START_OBJECT:
+                    JsonObject object = readObject(new JsonObjectBuilderImpl(bufferPool));
+                    builder.add(key, object);
+                    break;
+                case KEY_NAME:
+                    key = parser.getString();
+                    break;
+                case VALUE_STRING:
+                    builder.add(key, parser.getString());
+                    break;
+                case VALUE_NUMBER:
+                    if (parser.isDefinitelyInt()) {
+                        builder.add(key, parser.getInt());
+                    } else {
+                        builder.add(key, parser.getBigDecimal());
+                    }
+                    break;
+                case VALUE_TRUE:
+                    builder.add(key, JsonValue.TRUE);
+                    break;
+                case VALUE_FALSE:
+                    builder.add(key, JsonValue.FALSE);
+                    break;
+                case VALUE_NULL:
+                    builder.addNull(key);
+                    break;
+                case END_OBJECT:
+                    return builder.build();
+                default:
+                    throw new JsonException("Internal Error");
+            }
+        }
+        throw new JsonException("Internal Error");
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonStringImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonStringImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonStringImpl.java	(revision 6756)
@@ -0,0 +1,129 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonString;
+
+/**
+ * JsonString impl
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonStringImpl implements JsonString {
+
+    private final String value;
+
+    JsonStringImpl(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String getString() {
+        return value;
+    }
+
+    @Override
+    public CharSequence getChars() {
+        return value;
+    }
+
+    @Override
+    public ValueType getValueType() {
+        return ValueType.STRING;
+    }
+
+    @Override
+    public int hashCode() {
+        return getString().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof JsonString)) {
+            return false;
+        }
+        JsonString other = (JsonString)obj;
+        return getString().equals(other.getString());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append('"');
+
+        for(int i = 0; i < value.length(); i++) {
+            char c = value.charAt(i);
+            // unescaped = %x20-21 | %x23-5B | %x5D-10FFFF
+            if (c >= 0x20 && c <= 0x10ffff && c != 0x22 && c != 0x5c) {
+                sb.append(c);
+            } else {
+                switch (c) {
+                    case '"':
+                    case '\\':
+                        sb.append('\\'); sb.append(c);
+                        break;
+                    case '\b':
+                        sb.append('\\'); sb.append('b');
+                        break;
+                    case '\f':
+                        sb.append('\\'); sb.append('f');
+                        break;
+                    case '\n':
+                        sb.append('\\'); sb.append('n');
+                        break;
+                    case '\r':
+                        sb.append('\\'); sb.append('r');
+                        break;
+                    case '\t':
+                        sb.append('\\'); sb.append('t');
+                        break;
+                    default:
+                        String hex = "000" + Integer.toHexString(c);
+                        sb.append("\\u").append(hex.substring(hex.length() - 4));
+                }
+            }
+        }
+
+        sb.append('"');
+        return sb.toString();
+    }
+}
+
Index: trunk/src/org/glassfish/json/JsonStructureParser.java
===================================================================
--- trunk/src/org/glassfish/json/JsonStructureParser.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonStructureParser.java	(revision 6756)
@@ -0,0 +1,271 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.*;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import java.math.BigDecimal;
+import java.util.*;
+
+/**
+ * {@link JsonParser} implementation on top of JsonArray/JsonObject
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonStructureParser implements JsonParser {
+
+    private Scope current;
+    private Event state;
+    private final Deque<Scope> scopeStack = new ArrayDeque<Scope>();
+
+    JsonStructureParser(JsonArray array) {
+        current = new ArrayScope(array);
+    }
+
+    JsonStructureParser(JsonObject object) {
+        current = new ObjectScope(object);
+    }
+
+    @Override
+    public String getString() {
+        if (state == Event.KEY_NAME) {
+            return ((ObjectScope)current).key;
+        } else if (state == Event.VALUE_STRING) {
+            return ((JsonString)current.getJsonValue()).getString();
+        }
+        throw new IllegalStateException(JsonMessages.PARSER_GETSTRING_ERR(state));
+    }
+
+    @Override
+    public boolean isIntegralNumber() {
+        if (state == Event.VALUE_NUMBER) {
+            return ((JsonNumber)current.getJsonValue()).isIntegral();
+        }
+        throw new IllegalStateException(JsonMessages.PARSER_ISINTEGRALNUMBER_ERR(state));
+    }
+
+    @Override
+    public int getInt() {
+        if (state == Event.VALUE_NUMBER) {
+            return ((JsonNumber)current.getJsonValue()).intValue();
+        }
+        throw new IllegalStateException(JsonMessages.PARSER_GETINT_ERR(state));
+    }
+
+    @Override
+    public long getLong() {
+        if (state == Event.VALUE_NUMBER) {
+            return ((JsonNumber)current.getJsonValue()).longValue();
+        }
+        throw new IllegalStateException(JsonMessages.PARSER_GETLONG_ERR(state));
+    }
+
+    @Override
+    public BigDecimal getBigDecimal() {
+        if (state == Event.VALUE_NUMBER) {
+            return ((JsonNumber)current.getJsonValue()).bigDecimalValue();
+        }
+        throw new IllegalStateException(JsonMessages.PARSER_GETBIGDECIMAL_ERR(state));
+    }
+
+    @Override
+    public JsonLocation getLocation() {
+        return JsonLocationImpl.UNKNOWN;
+    }
+
+    @Override
+    public boolean hasNext() {
+        return !((state == Event.END_OBJECT || state == Event.END_ARRAY) && scopeStack.isEmpty());
+    }
+
+    @Override
+    public Event next() {
+        if (!hasNext()) {
+            throw new NoSuchElementException();
+        }
+        transition();
+        return state;
+    }
+
+    private void transition() {
+        if (state == null) {
+            state = current instanceof ArrayScope ? Event.START_ARRAY : Event.START_OBJECT;
+        } else {
+            if (state == Event.END_OBJECT || state == Event.END_ARRAY) {
+                current = scopeStack.pop();
+            }
+            if (current instanceof ArrayScope) {
+                if (current.hasNext()) {
+                    current.next();
+                    state = getState(current.getJsonValue());
+                    if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
+                        scopeStack.push(current);
+                        current = Scope.createScope(current.getJsonValue());
+                    }
+                } else {
+                    state = Event.END_ARRAY;
+                }
+            } else {
+                // ObjectScope
+                if (state == Event.KEY_NAME) {
+                    state = getState(current.getJsonValue());
+                    if (state == Event.START_ARRAY || state == Event.START_OBJECT) {
+                        scopeStack.push(current);
+                        current = Scope.createScope(current.getJsonValue());
+                    }
+                } else {
+                    if (current.hasNext()) {
+                        current.next();
+                        state = Event.KEY_NAME;
+                    } else {
+                        state = Event.END_OBJECT;
+                    }
+                }
+            }
+        }
+    }
+
+    @Override
+    public void close() {
+        // no-op
+    }
+
+    private static Event getState(JsonValue value) {
+        switch (value.getValueType()) {
+            case ARRAY:
+                return Event.START_ARRAY;
+            case OBJECT:
+                return Event.START_OBJECT;
+            case STRING:
+                return Event.VALUE_STRING;
+            case NUMBER:
+                return Event.VALUE_NUMBER;
+            case TRUE:
+                return Event.VALUE_TRUE;
+            case FALSE:
+                return Event.VALUE_FALSE;
+            case NULL:
+                return Event.VALUE_NULL;
+            default:
+                throw new JsonException("Unknown value type="+value.getValueType());
+        }
+    }
+
+    private static abstract class Scope implements Iterator {
+        abstract JsonValue getJsonValue();
+
+        static Scope createScope(JsonValue value) {
+            if (value instanceof JsonArray) {
+                return new ArrayScope((JsonArray)value);
+            } else if (value instanceof JsonObject) {
+                return new ObjectScope((JsonObject)value);
+            }
+            throw new JsonException("Cannot be called for value="+value);
+        }
+    }
+
+    private static class ArrayScope extends Scope {
+        private final Iterator<JsonValue> it;
+        private JsonValue value;
+
+        ArrayScope(JsonArray array) {
+            this.it = array.iterator();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return it.hasNext();
+        }
+
+        @Override
+        public JsonValue next() {
+            value = it.next();
+            return value;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        JsonValue getJsonValue() {
+            return value;
+        }
+
+    }
+
+    private static class ObjectScope extends Scope {
+        private final Iterator<Map.Entry<String, JsonValue>> it;
+        private JsonValue value;
+        private String key;
+
+        ObjectScope(JsonObject object) {
+            this.it = object.entrySet().iterator();
+        }
+
+        @Override
+        public boolean hasNext() {
+            return it.hasNext();
+        }
+
+        @Override
+        public Map.Entry<String, JsonValue> next() {
+            Map.Entry<String, JsonValue> next = it.next();
+            this.key = next.getKey();
+            this.value = next.getValue();
+            return next;
+        }
+
+        @Override
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        JsonValue getJsonValue() {
+            return value;
+        }
+
+    }
+
+}
Index: trunk/src/org/glassfish/json/JsonTokenizer.java
===================================================================
--- trunk/src/org/glassfish/json/JsonTokenizer.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonTokenizer.java	(revision 6756)
@@ -0,0 +1,542 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonException;
+import javax.json.stream.JsonLocation;
+import javax.json.stream.JsonParser;
+import javax.json.stream.JsonParsingException;
+import java.io.*;
+import java.math.BigDecimal;
+import java.util.Arrays;
+
+import javax.json.stream.JsonParser.Event;
+
+/**
+ * JSON Tokenizer
+ *
+ * @author Jitendra Kotamraju
+ */
+final class JsonTokenizer implements Closeable {
+    // Table to look up hex ch -> value (for e.g HEX['F'] = 15, HEX['5'] = 5)
+    private final static int[] HEX = new int[128];
+    static {
+        Arrays.fill(HEX, -1);
+        for (int i='0'; i <= '9'; i++) {
+            HEX[i] = i-'0';
+        }
+        for (int i='A'; i <= 'F'; i++) {
+            HEX[i] = 10+i-'A';
+        }
+        for (int i='a'; i <= 'f'; i++) {
+            HEX[i] = 10+i-'a';
+        }
+    }
+    private final static int HEX_LENGTH = HEX.length;
+
+    private final BufferPool bufferPool;
+
+    private final Reader reader;
+
+    // Internal buffer that is used for parsing. It is also used
+    // for storing current string and number value token
+    private char[] buf;
+
+    // Indexes in buffer
+    //
+    // XXXssssssssssssXXXXXXXXXXXXXXXXXXXXXXrrrrrrrrrrrrrrXXXXXX
+    //    ^           ^                     ^             ^
+    //    |           |                     |             |
+    //   storeBegin  storeEnd            readBegin      readEnd
+    private int readBegin;
+    private int readEnd;
+    private int storeBegin;
+    private int storeEnd;
+
+    // line number of the current pointer of parsing char
+    private long lineNo = 1;
+
+    // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+    // ^
+    // |
+    // bufferOffset
+    //
+    // offset of the last \r\n or \n. will be used to calculate column number
+    // of a token or an error. This may be outside of the buffer.
+    private long lastLineOffset = 0;
+    // offset in the stream for the start of the buffer, will be used in
+    // calculating JsonLocation's stream offset, column no.
+    private long bufferOffset = 0;
+
+    private boolean minus;
+    private boolean fracOrExp;
+    private BigDecimal bd;
+
+    enum JsonToken {
+        CURLYOPEN(Event.START_OBJECT, false),
+        SQUAREOPEN(Event.START_ARRAY, false),
+        COLON(null, false),
+        COMMA(null, false),
+        STRING(Event.VALUE_STRING, true),
+        NUMBER(Event.VALUE_NUMBER, true),
+        TRUE(Event.VALUE_TRUE, true),
+        FALSE(Event.VALUE_FALSE, true),
+        NULL(Event.VALUE_NULL, true),
+        CURLYCLOSE(Event.END_OBJECT, false),
+        SQUARECLOSE(Event.END_ARRAY, false),
+        EOF(null, false);
+
+        private final JsonParser.Event event;
+        private final boolean value;
+
+        JsonToken(JsonParser.Event event, boolean value) {
+            this.event = event;
+            this.value = value;
+        }
+
+        JsonParser.Event getEvent() {
+            return event;
+        }
+
+        boolean isValue() {
+            return value;
+        }
+    }
+
+    JsonTokenizer(Reader reader, BufferPool bufferPool) {
+        this.reader = reader;
+        this.bufferPool = bufferPool;
+        buf = bufferPool.take();
+    }
+
+    private void readString() {
+        // when inPlace is true, no need to copy chars
+        boolean inPlace = true;
+        storeBegin = storeEnd = readBegin;
+
+        do {
+            // Write unescaped char block within the current buffer
+            if (inPlace) {
+                int ch;
+                while(readBegin < readEnd && ((ch=buf[readBegin]) >= 0x20) && ch != '\\') {
+                    if (ch == '"') {
+                        storeEnd = readBegin++; // ++ to consume quote char
+                        return;                 // Got the entire string
+                    }
+                    readBegin++;                // consume unescaped char
+                }
+                storeEnd = readBegin;
+            }
+
+            // string may be crossing buffer boundaries and may contain
+            // escaped characters.
+            int ch = read();
+            if (ch >= 0x20 && ch != 0x22 && ch != 0x5c) {
+                if (!inPlace) {
+                    buf[storeEnd] = (char)ch;
+                }
+                storeEnd++;
+                continue;
+            }
+            switch (ch) {
+                case '\\':
+                    inPlace = false;        // Now onwards need to copy chars
+                    unescape();
+                    break;
+                case '"':
+                    return;
+                default:
+                    throw unexpectedChar(ch);
+            }
+        } while (true);
+    }
+
+    private void unescape() {
+        int ch = read();
+        switch (ch) {
+            case 'b':
+                buf[storeEnd++] = '\b';
+                break;
+            case 't':
+                buf[storeEnd++] = '\t';
+                break;
+            case 'n':
+                buf[storeEnd++] = '\n';
+                break;
+            case 'f':
+                buf[storeEnd++] = '\f';
+                break;
+            case 'r':
+                buf[storeEnd++] = '\r';
+                break;
+            case '"':
+            case '\\':
+            case '/':
+                buf[storeEnd++] = (char)ch;
+                break;
+            case 'u': {
+                int unicode = 0;
+                for (int i = 0; i < 4; i++) {
+                    int ch3 = read();
+                    int digit = (ch3 >= 0 && ch3 < HEX_LENGTH) ? HEX[ch3] : -1;
+                    if (digit < 0) {
+                        throw unexpectedChar(ch3);
+                    }
+                    unicode = (unicode << 4)|digit;
+                }
+                buf[storeEnd++] = (char)unicode;
+                break;
+            }
+            default:
+                throw unexpectedChar(ch);
+        }
+    }
+
+    // Reads a number char. If the char is within the buffer, directly
+    // reads from the buffer. Otherwise, uses read() which takes care
+    // of resizing, filling up the buf, adjusting the pointers
+    private int readNumberChar() {
+        if (readBegin < readEnd) {
+            return buf[readBegin++];
+        } else {
+            storeEnd = readBegin;
+            return read();
+        }
+    }
+
+    private void readNumber(int ch)  {
+        storeBegin = storeEnd = readBegin-1;
+        // sign
+        if (ch == '-') {
+            this.minus = true;
+            ch = readNumberChar();
+            if (ch < '0' || ch >'9') {
+                throw unexpectedChar(ch);
+            }
+        }
+
+        // int
+        if (ch == '0') {
+            ch = readNumberChar();
+        } else {
+            do {
+                ch = readNumberChar();
+            } while (ch >= '0' && ch <= '9');
+        }
+
+        // frac
+        if (ch == '.') {
+            this.fracOrExp = true;
+            int count = 0;
+            do {
+                ch = readNumberChar();
+                count++;
+            } while (ch >= '0' && ch <= '9');
+            if (count == 1) {
+                throw unexpectedChar(ch);
+            }
+        }
+
+        // exp
+        if (ch == 'e' || ch == 'E') {
+            this.fracOrExp = true;
+            ch = readNumberChar();
+            if (ch == '+' || ch == '-') {
+                ch = readNumberChar();
+            }
+            int count;
+            for (count = 0; ch >= '0' && ch <= '9'; count++) {
+                ch = readNumberChar();
+            }
+            if (count == 0) {
+                throw unexpectedChar(ch);
+            }
+        }
+        readBegin--;
+        storeEnd = readBegin;
+    }
+
+    private void readTrue() {
+        int ch1 = read();
+        if (ch1 != 'r') {
+            throw expectedChar(ch1, 'r');
+        }
+        int ch2 = read();
+        if (ch2 != 'u') {
+            throw expectedChar(ch2, 'u');
+        }
+        int ch3 = read();
+        if (ch3 != 'e') {
+            throw expectedChar(ch3, 'e');
+        }
+    }
+
+    private void readFalse() {
+        int ch1 = read();
+        if (ch1 != 'a') {
+            throw expectedChar(ch1, 'a');
+        }
+        int ch2 = read();
+        if (ch2 != 'l') {
+            throw expectedChar(ch2, 'l');
+        }
+        int ch3 = read();
+        if (ch3 != 's') {
+            throw expectedChar(ch3, 's');
+        }
+        int ch4 = read();
+        if (ch4 != 'e') {
+            throw expectedChar(ch4, 'e');
+        }
+    }
+
+    private void readNull() {
+        int ch1 = read();
+        if (ch1 != 'u') {
+            throw expectedChar(ch1, 'u');
+        }
+        int ch2 = read();
+        if (ch2 != 'l') {
+            throw expectedChar(ch2, 'l');
+        }
+        int ch3 = read();
+        if (ch3 != 'l') {
+            throw expectedChar(ch3, 'l');
+        }
+    }
+
+    /*
+     * Could be optimized if the parser uses separate methods to match colon
+     * etc (that would avoid the switch statement cost in certain cases)
+     */
+    JsonToken nextToken() {
+        reset();
+        int ch = read();
+
+        // whitespace
+        while (ch == 0x20 || ch == 0x09 || ch == 0x0a || ch == 0x0d) {
+            if (ch == '\r') {
+                ++lineNo;
+                ch = read();
+                if (ch == '\n') {
+                    lastLineOffset = bufferOffset+readBegin;
+                } else {
+                    lastLineOffset = bufferOffset+readBegin-1;
+                    continue;
+                }
+            } else if (ch == '\n') {
+                ++lineNo;
+                lastLineOffset = bufferOffset+readBegin;
+            }
+            ch = read();
+        }
+
+        switch (ch) {
+            case '"':
+                readString();
+                return JsonToken.STRING;
+            case '{':
+                return JsonToken.CURLYOPEN;
+            case '[':
+                return JsonToken.SQUAREOPEN;
+            case ':':
+                return JsonToken.COLON;
+            case ',':
+                return JsonToken.COMMA;
+            case 't':
+                readTrue();
+                return JsonToken.TRUE;
+            case 'f':
+                readFalse();
+                return JsonToken.FALSE;
+            case 'n':
+                readNull();
+                return JsonToken.NULL;
+            case ']':
+                return JsonToken.SQUARECLOSE;
+            case '}':
+                return JsonToken.CURLYCLOSE;
+            case '0':
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+            case '-':
+                readNumber(ch);
+                return JsonToken.NUMBER;
+            case -1:
+                return JsonToken.EOF;
+            default:
+                throw unexpectedChar(ch);
+        }
+    }
+
+    // Gives the location of the last char. Used for
+    // JsonParsingException.getLocation
+    JsonLocation getLastCharLocation() {
+        // Already read the char, so subtracting -1
+        return new JsonLocationImpl(lineNo, bufferOffset +readBegin-lastLineOffset, bufferOffset +readBegin-1);
+    }
+
+    // Gives the parser location. Used for JsonParser.getLocation
+    JsonLocation getLocation() {
+        return new JsonLocationImpl(lineNo, bufferOffset +readBegin-lastLineOffset+1, bufferOffset +readBegin);
+    }
+
+    private int read() {
+        try {
+            if (readBegin == readEnd) {     // need to fill the buffer
+                int len = fillBuf();
+                if (len == -1) {
+                    return -1;
+                }
+                assert len != 0;
+                readBegin = storeEnd;
+                readEnd = readBegin+len;
+            }
+            return buf[readBegin++];
+        } catch (IOException ioe) {
+            throw new JsonException(JsonMessages.TOKENIZER_IO_ERR(), ioe);
+        }
+    }
+
+    private int fillBuf() throws IOException {
+        if (storeEnd != 0) {
+            int storeLen = storeEnd-storeBegin;
+            if (storeLen > 0) {
+                // there is some store data
+                if (storeLen == buf.length) {
+                    // buffer is full, double the capacity
+                    char[] doubleBuf = Arrays.copyOf(buf, 2 * buf.length);
+                    bufferPool.recycle(buf);
+                    buf = doubleBuf;
+                } else {
+                    // Left shift all the stored data to make space
+                    System.arraycopy(buf, storeBegin, buf, 0, storeLen);
+                    storeEnd = storeLen;
+                    storeBegin = 0;
+                    bufferOffset += readBegin-storeEnd;
+                }
+            } else {
+                storeBegin = storeEnd = 0;
+                bufferOffset += readBegin;
+            }
+        } else {
+            bufferOffset += readBegin;
+        }
+        // Fill the rest of the buf
+        return reader.read(buf, storeEnd, buf.length-storeEnd);
+    }
+
+    // state associated with the current token is no more valid
+    private void reset() {
+        if (storeEnd != 0) {
+            storeBegin = 0;
+            storeEnd = 0;
+            bd = null;
+            minus = false;
+            fracOrExp = false;
+        }
+    }
+
+    String getValue() {
+        return new String(buf, storeBegin, storeEnd-storeBegin);
+    }
+
+    BigDecimal getBigDecimal() {
+        if (bd == null) {
+            bd = new BigDecimal(buf, storeBegin, storeEnd-storeBegin);
+        }
+        return bd;
+    }
+
+    int getInt() {
+        // no need to create BigDecimal for common integer values (1-9 digits)
+        int storeLen = storeEnd-storeBegin;
+        if (!fracOrExp && (storeLen <= 9 || (minus && storeLen == 10))) {
+            int num = 0;
+            int i = minus ? 1 : 0;
+            for(; i < storeLen; i++) {
+                num = num * 10 + (buf[storeBegin+i] - '0');
+            }
+            return minus ? -num : num;
+        } else {
+            return getBigDecimal().intValue();
+        }
+    }
+
+    // returns true for common integer values (1-9 digits).
+    // So there are cases it will return false even though the number is int
+    boolean isDefinitelyInt() {
+        int storeLen = storeEnd-storeBegin;
+        return !fracOrExp && (storeLen <= 9 || (minus && storeLen == 10));
+    }
+
+    boolean isIntegral() {
+        return !fracOrExp || getBigDecimal().scale() == 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        reader.close();
+        bufferPool.recycle(buf);
+    }
+
+    private JsonParsingException unexpectedChar(int ch) {
+        JsonLocation location = getLastCharLocation();
+        return new JsonParsingException(
+            JsonMessages.TOKENIZER_UNEXPECTED_CHAR(ch, location), location);
+    }
+
+    private JsonParsingException expectedChar(int unexpected, char expected) {
+        JsonLocation location = getLastCharLocation();
+        return new JsonParsingException(
+                JsonMessages.TOKENIZER_EXPECTED_CHAR(unexpected, location, expected), location);
+    }
+    
+}
Index: trunk/src/org/glassfish/json/JsonWriterFactoryImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonWriterFactoryImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonWriterFactoryImpl.java	(revision 6756)
@@ -0,0 +1,86 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.JsonWriter;
+import javax.json.JsonWriterFactory;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * @author Jitendra Kotamraju
+ */
+class JsonWriterFactoryImpl implements JsonWriterFactory {
+    private final Map<String, ?> config;        // unmodifiable map
+    private final boolean prettyPrinting;
+    private final BufferPool bufferPool;
+
+    JsonWriterFactoryImpl(Map<String, ?> config, boolean prettyPrinting,
+            BufferPool bufferPool) {
+        this.config = config;
+        this.prettyPrinting = prettyPrinting;
+        this.bufferPool = bufferPool;
+    }
+
+    @Override
+    public JsonWriter createWriter(Writer writer) {
+        return new JsonWriterImpl(writer, prettyPrinting, bufferPool);
+    }
+
+    @Override
+    public JsonWriter createWriter(OutputStream out) {
+        return new JsonWriterImpl(out, prettyPrinting, bufferPool);
+    }
+
+    @Override
+    public JsonWriter createWriter(OutputStream out, Charset charset) {
+        return new JsonWriterImpl(out, charset, prettyPrinting, bufferPool);
+    }
+
+    @Override
+    public Map<String, ?> getConfigInUse() {
+        return config;
+    }
+}
Index: trunk/src/org/glassfish/json/JsonWriterImpl.java
===================================================================
--- trunk/src/org/glassfish/json/JsonWriterImpl.java	(revision 6756)
+++ trunk/src/org/glassfish/json/JsonWriterImpl.java	(revision 6756)
@@ -0,0 +1,169 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import org.glassfish.json.api.BufferPool;
+
+import javax.json.*;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+import java.nio.charset.Charset;
+import java.util.Map;
+
+/**
+ * JsonWriter impl using generator.
+ *
+ * @author Jitendra Kotamraju
+ */
+class JsonWriterImpl implements JsonWriter {
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    private final JsonGeneratorImpl generator;
+    private boolean writeDone;
+    private final NoFlushOutputStream os;
+
+    JsonWriterImpl(Writer writer, BufferPool bufferPool) {
+        this(writer, false, bufferPool);
+    }
+
+    JsonWriterImpl(Writer writer, boolean prettyPrinting, BufferPool bufferPool) {
+        generator = prettyPrinting
+                ? new JsonPrettyGeneratorImpl(writer, bufferPool)
+                : new JsonGeneratorImpl(writer, bufferPool);
+        os = null;
+    }
+
+    JsonWriterImpl(OutputStream out, BufferPool bufferPool) {
+        this(out, UTF_8, false, bufferPool);
+    }
+
+    JsonWriterImpl(OutputStream out, boolean prettyPrinting, BufferPool bufferPool) {
+        this(out, UTF_8, prettyPrinting, bufferPool);
+    }
+
+    JsonWriterImpl(OutputStream out, Charset charset,
+                   boolean prettyPrinting, BufferPool bufferPool) {
+        // Decorating the given stream, so that buffered contents can be
+        // written without actually flushing the stream.
+        this.os = new NoFlushOutputStream(out);
+        generator = prettyPrinting
+                ? new JsonPrettyGeneratorImpl(os, charset, bufferPool)
+                : new JsonGeneratorImpl(os, charset, bufferPool);
+    }
+
+    @Override
+    public void writeArray(JsonArray array) {
+        if (writeDone) {
+            throw new IllegalStateException(JsonMessages.WRITER_WRITE_ALREADY_CALLED());
+        }
+        writeDone = true;
+        generator.writeStartArray();
+        for(JsonValue value : array) {
+            generator.write(value);
+        }
+        generator.writeEnd();
+        // Flush the generator's buffered contents. This won't work for byte
+        // streams as intermediary OutputStreamWriter buffers.
+        generator.flushBuffer();
+        // Flush buffered contents but not the byte stream. generator.flush()
+        // does OutputStreamWriter#flushBuffer (package private) and underlying
+        // byte stream#flush(). Here underlying stream's flush() is no-op.
+        if (os != null) {
+            generator.flush();
+        }
+    }
+
+    @Override
+    public void writeObject(JsonObject object) {
+        if (writeDone) {
+            throw new IllegalStateException(JsonMessages.WRITER_WRITE_ALREADY_CALLED());
+        }
+        writeDone = true;
+        generator.writeStartObject();
+        for(Map.Entry<String, JsonValue> e : object.entrySet()) {
+            generator.write(e.getKey(), e.getValue());
+        }
+        generator.writeEnd();
+        // Flush the generator's buffered contents. This won't work for byte
+        // streams as intermediary OutputStreamWriter buffers.
+        generator.flushBuffer();
+        // Flush buffered contents but not the byte stream. generator.flush()
+        // does OutputStreamWriter#flushBuffer (package private) and underlying
+        // byte stream#flush(). Here underlying stream's flush() is no-op.
+        if (os != null) {
+            generator.flush();
+        }
+    }
+
+    @Override
+    public void write(JsonStructure value) {
+        if (value instanceof JsonArray) {
+            writeArray((JsonArray)value);
+        } else {
+            writeObject((JsonObject)value);
+        }
+    }
+
+    @Override
+    public void close() {
+        writeDone = true;
+        generator.close();
+    }
+
+    private static final class NoFlushOutputStream extends FilterOutputStream {
+        public NoFlushOutputStream(OutputStream out) {
+            super(out);
+        }
+
+        @Override
+        public void write(byte b[], int off, int len) throws IOException {
+            out.write(b, off ,len);
+        }
+
+        @Override
+        public void flush() {
+            // no-op
+        }
+    }
+
+}
Index: trunk/src/org/glassfish/json/UnicodeDetectingInputStream.java
===================================================================
--- trunk/src/org/glassfish/json/UnicodeDetectingInputStream.java	(revision 6756)
+++ trunk/src/org/glassfish/json/UnicodeDetectingInputStream.java	(revision 6756)
@@ -0,0 +1,189 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2012-2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json;
+
+import javax.json.JsonException;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.Charset;
+
+/**
+ * A filter stream that detects the unicode encoding for the original
+ * stream
+ *
+ * @author Jitendra Kotamraju
+ */
+class UnicodeDetectingInputStream extends FilterInputStream {
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+    private static final Charset UTF_16BE = Charset.forName("UTF-16BE");
+    private static final Charset UTF_16LE = Charset.forName("UTF-16LE");
+    private static final Charset UTF_32LE = Charset.forName("UTF-32LE");
+    private static final Charset UTF_32BE = Charset.forName("UTF-32BE");
+
+    private static final byte FF = (byte)0xFF;
+    private static final byte FE = (byte)0xFE;
+    private static final byte EF = (byte)0xEF;
+    private static final byte BB = (byte)0xBB;
+    private static final byte BF = (byte)0xBF;
+    private static final byte NUL = (byte)0x00;
+
+    private final byte[] buf = new byte[4];
+    private int bufLen;
+    private int curIndex;
+    private final Charset charset;
+
+    UnicodeDetectingInputStream(InputStream is) {
+        super(is);
+        charset = detectEncoding();
+    }
+
+    Charset getCharset() {
+        return charset;
+    }
+
+    private void fillBuf() {
+        int b1;
+        int b2;
+        int b3;
+        int b4;
+
+        try {
+            b1 = in.read();
+            if (b1 == -1) {
+                return;
+            }
+
+            b2 = in.read();
+            if (b2 == -1) {
+                bufLen = 1;
+                buf[0] = (byte)b1;
+                return;
+            }
+
+            b3 = in.read();
+            if (b3 == -1) {
+                bufLen = 2;
+                buf[0] = (byte)b1;
+                buf[1] = (byte)b2;
+                return;
+            }
+
+            b4 = in.read();
+            if (b4 == -1) {
+                bufLen = 3;
+                buf[0] = (byte)b1;
+                buf[1] = (byte)b2;
+                buf[2] = (byte)b3;
+                return;
+            }
+            bufLen = 4;
+            buf[0] = (byte)b1;
+            buf[1] = (byte)b2;
+            buf[2] = (byte)b3;
+            buf[3] = (byte)b4;
+        } catch (IOException ioe) {
+            throw new JsonException("I/O error while auto-detecting the encoding of stream", ioe);
+        }
+    }
+
+    private Charset detectEncoding() {
+        fillBuf();
+        if (bufLen < 2) {
+            throw new JsonException("Cannot auto-detect encoding, not enough chars");
+        } else if (bufLen == 4) {
+            // Use BOM to detect encoding
+            if (buf[0] == NUL && buf[1] == NUL && buf[2] == FE && buf[3] == FF) {
+                curIndex = 4;
+                return UTF_32BE;
+            } else if (buf[0] == FF && buf[1] == FE && buf[2] == NUL && buf[3] == NUL) {
+                curIndex = 4;
+                return UTF_32LE;
+            } else if (buf[0] == FE && buf[1] == FF) {
+                curIndex = 2;
+                return UTF_16BE;
+            } else if (buf[0] == FF && buf[1] == FE) {
+                curIndex = 2;
+                return UTF_16LE;
+            } else if (buf[0] == EF && buf[1] == BB && buf[2] == BF) {
+                curIndex = 3;
+                return UTF_8;
+            }
+            // No BOM, just use JSON RFC's encoding algo to auto-detect
+            if (buf[0] == NUL && buf[1] == NUL && buf[2] == NUL) {
+                return UTF_32BE;
+            } else if (buf[0] == NUL && buf[2] == NUL) {
+                return UTF_16BE;
+            } else if (buf[1] == NUL && buf[2] == NUL && buf[3] == NUL) {
+                return UTF_32LE;
+            } else if (buf[1] == NUL && buf[3] == NUL) {
+                return UTF_16LE;
+            }
+        }
+        return UTF_8;
+    }
+
+    @Override
+    public int read() throws IOException {
+        if (curIndex < bufLen) {
+            return buf[curIndex++];
+        }
+        return in.read();
+    }
+
+    @Override
+    public int read(byte b[], int off, int len) throws IOException {
+        if (curIndex < bufLen) {
+            if (len == 0) {
+                return 0;
+            }
+            if (off < 0 || len < 0 || len > b.length -off) {
+                throw new IndexOutOfBoundsException();
+            }
+            int min = Math.min(bufLen-curIndex, len);
+            System.arraycopy(buf, curIndex, b, off, min);
+            curIndex += min;
+            return min;
+        }
+        return in.read(b, off, len);
+    }
+
+}
Index: trunk/src/org/glassfish/json/api/BufferPool.java
===================================================================
--- trunk/src/org/glassfish/json/api/BufferPool.java	(revision 6756)
+++ trunk/src/org/glassfish/json/api/BufferPool.java	(revision 6756)
@@ -0,0 +1,66 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common Development
+ * and Distribution License("CDDL") (collectively, the "License").  You
+ * may not use this file except in compliance with the License.  You can
+ * obtain a copy of the License at
+ * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
+ * or packager/legal/LICENSE.txt.  See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ * When distributing the software, include this License Header Notice in each
+ * file and include the License file at packager/legal/LICENSE.txt.
+ *
+ * GPL Classpath Exception:
+ * Oracle designates this particular file as subject to the "Classpath"
+ * exception as provided by Oracle in the GPL Version 2 section of the License
+ * file that accompanied this code.
+ *
+ * Modifications:
+ * If applicable, add the following below the License Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyright [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ * If you wish your version of this file to be governed by only the CDDL or
+ * only the GPL Version 2, indicate your decision by adding "[Contributor]
+ * elects to include this software in this distribution under the [CDDL or GPL
+ * Version 2] license."  If you don't indicate a single choice of license, a
+ * recipient has the option to distribute your version of this file under
+ * either the CDDL, the GPL Version 2 or to extend the choice of license to
+ * its licensees as provided above.  However, if you add GPL Version 2 code
+ * and therefore, elected the GPL Version 2 license, then the option applies
+ * only if the new code is made subject to such option by the copyright
+ * holder.
+ */
+
+package org.glassfish.json.api;
+
+/**
+ * char[] pool that pool instances of char[] which are expensive to create.
+ *
+ * @author Jitendra Kotamraju
+ */
+public interface BufferPool {
+
+    /**
+     * Gets a new char[] object from the pool.
+     *
+     * <p>
+     * If no object is available in the pool, this method creates a new one.
+     *
+     * @return
+     *      always non-null.
+     */
+    char[] take();
+
+    /**
+     * Returns an object back to the pool.
+     */
+    void recycle(char[] buf);
+
+}
Index: trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java
===================================================================
--- trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 6755)
+++ trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java	(revision 6756)
@@ -2,69 +2,75 @@
 package org.openstreetmap.josm.io;
 
+import java.io.StringWriter;
+import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import org.json.JSONStringer;
+import javax.json.Json;
+import javax.json.JsonArrayBuilder;
+import javax.json.JsonObjectBuilder;
+import javax.json.JsonWriter;
+import javax.json.stream.JsonGenerator;
+
 import org.openstreetmap.josm.data.Bounds;
 import org.openstreetmap.josm.data.coor.LatLon;
-import org.openstreetmap.josm.data.osm.Changeset;
+import org.openstreetmap.josm.data.osm.DataSet;
+import org.openstreetmap.josm.data.osm.INode;
+import org.openstreetmap.josm.data.osm.IRelation;
+import org.openstreetmap.josm.data.osm.IWay;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
-import org.openstreetmap.josm.data.osm.Relation;
 import org.openstreetmap.josm.data.osm.Way;
-import org.openstreetmap.josm.data.osm.visitor.Visitor;
+import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
 import org.openstreetmap.josm.gui.layer.OsmDataLayer;
 
-public class GeoJSONWriter implements Visitor {
+/**
+ * Writes OSM data as a GeoJSON string, using JSR 353: Java API for JSON Processing (JSON-P).
+ */
+public class GeoJSONWriter {
 
     private OsmDataLayer layer;
-    private JSONStringer out;
     private static final boolean skipEmptyNodes = true;
 
+    /**
+     * Constructs a new {@code GeoJSONWriter}.
+     * @param layer The OSM data layer to save
+     */
     public GeoJSONWriter(OsmDataLayer layer) {
         this.layer = layer;
     }
 
+    /**
+     * Writes OSM data as a GeoJSON string (prettified).
+     * @return The GeoJSON data
+     */
     public String write() {
-        out = new JSONStringer();
-        out.object().key("type").value("FeatureCollection");
-        out.key("generator").value("JOSM");
-        appendLayerBounds();
-        out.key("features").array();
-        for (Node n : layer.data.getNodes()) {
-            appendPrimitive(n);
-        }
-        for (Way w : layer.data.getWays()) {
-            appendPrimitive(w);
-        }
-        out.endArray().endObject();
-        return out.toString();
+        return write(true);
     }
 
-    @Override
-    public void visit(Node n) {
-        out.key("type").value("Point").key("coordinates");
-        appendCoord(n.getCoor());
+    /**
+     * Writes OSM data as a GeoJSON string (prettified or not).
+     * @param pretty {@code true} to have pretty output, {@code false} otherwise
+     * @return The GeoJSON data
+     * @since 6756
+     */
+    public String write(boolean pretty) {
+        StringWriter stringWriter = new StringWriter();
+        Map<String, Object> config = new HashMap<String, Object>(1);
+        config.put(JsonGenerator.PRETTY_PRINTING, pretty);
+        JsonWriter writer = Json.createWriterFactory(config).createWriter(stringWriter);
+        JsonObjectBuilder object = Json.createObjectBuilder()
+                .add("type", "FeatureCollection")
+                .add("generator", "JOSM");
+        appendLayerBounds(layer.data, object);
+        appendLayerFeatures(layer.data, object);
+        writer.writeObject(object.build());
+        String result = stringWriter.toString();
+        writer.close();
+        return result;
     }
 
-    @Override
-    public void visit(Way w) {
-        out.key("type").value("LineString").key("coordinates").array();
-        for (Node n : w.getNodes()) {
-            appendCoord(n.getCoor());
-        }
-        out.endArray();
-    }
-
-    @Override
-    public void visit(Relation e) {
-    }
-
-    @Override
-    public void visit(Changeset cs) {
-    }
-
-    protected void appendPrimitive(OsmPrimitive p) {
+    protected static void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
         if (p.isIncomplete()) {
             return;
@@ -72,41 +78,86 @@
             return;
         }
-        out.object().key("type").value("Feature");
-        Map<String, String> tags = p.getKeys();
-        out.key("properties").object();
-        for (Entry<String, String> t : tags.entrySet()) {
-            out.key(t.getKey()).value(t.getValue());
+
+        // Properties
+        final JsonObjectBuilder propObj = Json.createObjectBuilder();
+        for (Entry<String, String> t : p.getKeys().entrySet()) {
+            propObj.add(t.getKey(), t.getValue());
         }
-        out.endObject();
-        // append primitive specific
-        out.key("geometry").object();
-        p.accept(this);
-        out.endObject();
-        out.endObject();
+
+        // Geometry
+        final JsonObjectBuilder geomObj = Json.createObjectBuilder();
+        p.accept(new PrimitiveVisitor() {
+            @Override
+            public void visit(INode n) {
+                geomObj.add("type", "Point");
+                LatLon ll = n.getCoor();
+                if (ll != null) {
+                    geomObj.add("coordinates", getCoorArray(n.getCoor()));
+                }
+            }
+
+            @Override
+            public void visit(IWay w) {
+                geomObj.add("type", "LineString");
+                if (w instanceof Way) {
+                    JsonArrayBuilder array = Json.createArrayBuilder();
+                    for (Node n : ((Way)w).getNodes()) {
+                        LatLon ll = n.getCoor();
+                        if (ll != null) {
+                            array.add(getCoorArray(ll));
+                        }
+                    }
+                    geomObj.add("coordinates", array);
+                }
+            }
+
+            @Override
+            public void visit(IRelation r) {
+            }
+
+            private JsonArrayBuilder getCoorArray(LatLon c) {
+                return Json.createArrayBuilder().add(c.lon()).add(c.lat());
+            }
+        });
+
+        // Build primitive JSON object
+        array.add(Json.createObjectBuilder()
+                .add("type", "Feature")
+                .add("properties", propObj)
+                .add("geometry", geomObj));
     }
 
-    protected void appendCoord(LatLon c) {
-        if (c != null) {
-            out.array().value(c.lon()).value(c.lat()).endArray();
+    protected static void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
+        if (ds != null) {
+            Iterator<Bounds> it = ds.getDataSourceBounds().iterator();
+            if (it.hasNext()) {
+                Bounds b = new Bounds(it.next());
+                while (it.hasNext()) {
+                    b.extend(it.next());
+                }
+                appendBounds(b, object);
+            }
         }
     }
 
-    protected void appendLayerBounds() {
-        Iterator<Bounds> it = layer.data.getDataSourceBounds().iterator();
-        if (it.hasNext()) {
-            Bounds b = new Bounds(it.next());
-            while (it.hasNext()) {
-                b.extend(it.next());
-            }
-            appendBounds(b);
+    protected static void appendBounds(Bounds b, JsonObjectBuilder object) {
+        if (b != null) {
+            object.add("bbox", Json.createArrayBuilder()
+                    .add(b.getMinLon()).add(b.getMinLat())
+                    .add(b.getMaxLon()).add(b.getMaxLat()));
         }
     }
 
-    protected void appendBounds(Bounds b) {
-        if (b != null) {
-            out.key("bbox").array()
-            .value(b.getMinLon()).value(b.getMinLat())
-            .value(b.getMaxLon()).value(b.getMaxLat()).endArray();
+    protected static void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) {
+        JsonArrayBuilder array = Json.createArrayBuilder();
+        if (ds != null) {
+            for (Node n : ds.getNodes()) {
+                appendPrimitive(n, array);
+            }
+            for (Way w : ds.getWays()) {
+                appendPrimitive(w, array);
+            }
         }
+        object.add("features", array);
     }
 }
