diff --git a/json/src/rewrite/java/org/json/JSON.java b/json/src/rewrite/java/org/json/JSON.java
new file mode 100644
index 0000000..029884b
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSON.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+class JSON {
+    /**
+     * Returns the input if it is a JSON-permissable value; throws otherwise.
+     */
+    static double checkDouble(double d) throws JSONException {
+        if (Double.isInfinite(d) || Double.isNaN(d)) {
+            throw new JSONException("Forbidden numeric value: " + d);
+        }
+        return d;
+    }
+
+    static Boolean toBoolean(Object value) {
+        if (value instanceof Boolean) {
+            return (Boolean) value;
+        } else if (value instanceof String) {
+            return Boolean.valueOf(((String) value));
+        } else {
+            return null;
+        }
+    }
+
+    static Double toDouble(Object value) {
+        if (value instanceof Double) {
+            return (Double) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).doubleValue();
+        } else if (value instanceof String) {
+            try {
+                return Double.valueOf((String) value);
+            } catch (NumberFormatException e) {
+            }
+        }
+        return null;
+    }
+
+    static Integer toInteger(Object value) {
+        if (value instanceof Integer) {
+            return (Integer) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).intValue();
+        } else if (value instanceof String) {
+            try {
+                return Double.valueOf((String) value).intValue();
+            } catch (NumberFormatException e) {
+            }
+        }
+        return null;
+    }
+
+    static Long toLong(Object value) {
+        if (value instanceof Long) {
+            return (Long) value;
+        } else if (value instanceof Number) {
+            return ((Number) value).longValue();
+        } else if (value instanceof String) {
+            try {
+                return Double.valueOf((String) value).longValue();
+            } catch (NumberFormatException e) {
+            }
+        }
+        return null;
+    }
+
+    static String toString(Object value) {
+        if (value instanceof String) {
+            return (String) value;
+        } else if (value != null) {
+            return String.valueOf(value);
+        }
+        return null;
+    }
+
+    public static JSONException typeMismatch(Object indexOrName, Object actual,
+            String requiredType) throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value at " + indexOrName + " is null.");
+        } else {
+            throw new JSONException("Value " + actual + " at " + indexOrName
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+
+    public static JSONException typeMismatch(Object actual, String requiredType)
+            throws JSONException {
+        if (actual == null) {
+            throw new JSONException("Value is null.");
+        } else {
+            throw new JSONException("Value " + actual
+                    + " of type " + actual.getClass().getName()
+                    + " cannot be converted to " + requiredType);
+        }
+    }
+}
diff --git a/json/src/rewrite/java/org/json/JSONArray.java b/json/src/rewrite/java/org/json/JSONArray.java
new file mode 100644
index 0000000..fa42054
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSONArray.java
@@ -0,0 +1,322 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collection;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * An indexed sequence of JSON-safe values.
+ */
+public class JSONArray {
+
+    private final List<Object> values;
+
+    public JSONArray() {
+        values = new ArrayList<Object>();
+    }
+
+    /* Accept a raw type for API compatibility */
+    public JSONArray(Collection copyFrom) {
+        this();
+        Collection<?> copyFromTyped = (Collection<?>) copyFrom;
+        values.addAll(copyFromTyped);
+    }
+
+    public JSONArray(JSONTokener readFrom) throws JSONException {
+        /*
+         * Getting the parser to populate this could get tricky. Instead, just
+         * parse to temporary JSONArray and then steal the data from that.
+         */
+        Object object = readFrom.nextValue();
+        if (object instanceof JSONArray) {
+            values = ((JSONArray) object).values;
+        } else {
+            throw JSON.typeMismatch(object, "JSONArray");
+        }
+    }
+
+    public JSONArray(String json) throws JSONException {
+        this(new JSONTokener(json));
+    }
+
+    public int length() {
+        return values.size();
+    }
+
+    public JSONArray put(boolean value) {
+        values.add(value);
+        return this;
+    }
+
+    public JSONArray put(double value) throws JSONException {
+        values.add(JSON.checkDouble(value));
+        return this;
+    }
+
+    public JSONArray put(int value) {
+        values.add(value);
+        return this;
+    }
+
+    public JSONArray put(long value) {
+        values.add(value);
+        return this;
+    }
+
+    public JSONArray put(Object value) {
+        values.add(value);
+        return this;
+    }
+
+    public JSONArray put(int index, boolean value) throws JSONException {
+        return put(index, (Boolean) value);
+    }
+
+    public JSONArray put(int index, double value) throws JSONException {
+        return put(index, (Double) value);
+    }
+
+    public JSONArray put(int index, int value) throws JSONException {
+        return put(index, (Integer) value);
+    }
+
+    public JSONArray put(int index, long value) throws JSONException {
+        return put(index, (Long) value);
+    }
+
+    public JSONArray put(int index, Object value) throws JSONException {
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
+        }
+        while (values.size() <= index) {
+            values.add(null);
+        }
+        values.set(index, value);
+        return this;
+    }
+
+    public boolean isNull(int index) {
+        Object value = opt(index);
+        return value == null || value == JSONObject.NULL;
+    }
+
+    public Object get(int index) throws JSONException {
+        try {
+            Object value = values.get(index);
+            if (value == null) {
+                throw new JSONException("Value at " + index + " is null.");
+            }
+            return value;
+        } catch (IndexOutOfBoundsException e) {
+            throw new JSONException("Index " + index + " out of range [0.." + values.size() + ")");
+        }
+    }
+
+    public Object opt(int index) {
+        if (index < 0 || index >= values.size()) {
+            return null;
+        }
+        return values.get(index);
+    }
+
+    public boolean getBoolean(int index) throws JSONException {
+        Object object = get(index);
+        Boolean result = JSON.toBoolean(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "boolean");
+        }
+        return result;
+    }
+
+    public boolean optBoolean(int index) {
+        return optBoolean(index, false);
+    }
+
+    public boolean optBoolean(int index, boolean fallback) {
+        Object object = opt(index);
+        Boolean result = JSON.toBoolean(object);
+        return result != null ? result : fallback;
+    }
+
+    public double getDouble(int index) throws JSONException {
+        Object object = get(index);
+        Double result = JSON.toDouble(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "double");
+        }
+        return result;
+    }
+
+    public double optDouble(int index) {
+        return optDouble(index, Double.NaN);
+    }
+
+    public double optDouble(int index, double fallback) {
+        Object object = opt(index);
+        Double result = JSON.toDouble(object);
+        return result != null ? result : fallback;
+    }
+
+    public int getInt(int index) throws JSONException {
+        Object object = get(index);
+        Integer result = JSON.toInteger(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "int");
+        }
+        return result;
+    }
+
+    public int optInt(int index) {
+        return optInt(index, 0);
+    }
+
+    public int optInt(int index, int fallback) {
+        Object object = opt(index);
+        Integer result = JSON.toInteger(object);
+        return result != null ? result : fallback;
+    }
+
+    public long getLong(int index) throws JSONException {
+        Object object = get(index);
+        Long result = JSON.toLong(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "long");
+        }
+        return result;
+    }
+
+    public long optLong(int index) {
+        return optLong(index, 0L);
+    }
+
+    public long optLong(int index, long fallback) {
+        Object object = opt(index);
+        Long result = JSON.toLong(object);
+        return result != null ? result : fallback;
+    }
+
+    public String getString(int index) throws JSONException {
+        Object object = get(index);
+        String result = JSON.toString(object);
+        if (result == null) {
+            throw JSON.typeMismatch(index, object, "String");
+        }
+        return result;
+    }
+
+    public String optString(int index) {
+        return optString(index, "");
+    }
+
+    public String optString(int index, String fallback) {
+        Object object = opt(index);
+        String result = JSON.toString(object);
+        return result != null ? result : fallback;
+    }
+
+    public JSONArray getJSONArray(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONArray) {
+            return (JSONArray) object;
+        } else {
+            throw JSON.typeMismatch(index, object, "JSONArray");
+        }
+    }
+
+    public JSONArray optJSONArray(int index) {
+        Object object = opt(index);
+        return object instanceof JSONArray ? (JSONArray) object : null;
+    }
+
+    public JSONObject getJSONObject(int index) throws JSONException {
+        Object object = get(index);
+        if (object instanceof JSONObject) {
+            return (JSONObject) object;
+        } else {
+            throw JSON.typeMismatch(index, object, "JSONObject");
+        }
+    }
+
+    public JSONObject optJSONObject(int index) {
+        Object object = opt(index);
+        return object instanceof JSONObject ? (JSONObject) object : null;
+    }
+
+    public JSONObject toJSONObject(JSONArray names) throws JSONException {
+        JSONObject result = new JSONObject();
+        int length = Math.min(names.length(), values.size());
+        if (length == 0) {
+            return null;
+        }
+        for (int i = 0; i < length; i++) {
+            String name = JSON.toString(names.opt(i));
+            result.put(name, opt(i));
+        }
+        return result;
+    }
+
+    public String join(String separator) throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.open(JSONStringer.Scope.NULL, "");
+        for (int i = 0, size = values.size(); i < size; i++) {
+            if (i > 0) {
+                stringer.out.append(separator);
+            }
+            stringer.value(values.get(i));
+        }
+        stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+        return stringer.out.toString();
+    }
+
+    @Override public String toString() {
+        try {
+            JSONStringer stringer = new JSONStringer();
+            writeTo(stringer);
+            return stringer.toString();
+        } catch (JSONException e) {
+            return null;
+        }
+    }
+
+    public String toString(int indentSpaces) throws JSONException {
+        JSONStringer stringer = new JSONStringer(indentSpaces);
+        writeTo(stringer);
+        return stringer.toString();
+    }
+
+    void writeTo(JSONStringer stringer) throws JSONException {
+        stringer.array();
+        for (Object value : values) {
+            stringer.value(value);
+        }
+        stringer.endArray();
+    }
+
+    @Override public boolean equals(Object o) {
+        return o instanceof JSONArray && ((JSONArray) o).values.equals(values);
+    }
+
+    @Override public int hashCode() {
+        // diverge from the original, which doesn't implement hashCode
+        return values.hashCode();
+    }
+}
diff --git a/json/src/rewrite/java/org/json/JSONException.java b/json/src/rewrite/java/org/json/JSONException.java
new file mode 100644
index 0000000..e1efd9f
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSONException.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ * Thrown to indicate a problem with the JSON API. Such problems include:
+ * <ul>
+ *   <li>Attempts to parse or construct malformed documents
+ *   <li>Use of null as a name
+ *   <li>Use of numeric types not available to JSON, such as {@link Double#NaN
+ *       NaN} or {@link Double#POSITIVE_INFINITY infinity}.
+ *   <li>Lookups using an out of range index or nonexistant name
+ *   <li>Type mismatches on lookups
+ * </ul>
+ *
+ * <p>Although this is a checked exception, it is rarely recoverable. Most
+ * callers should simply wrap this exception in an unchecked exception and
+ * rethrow:
+ * <pre>  public JSONArray toJSONObject() {
+ *     try {
+ *         JSONObject result = new JSONObject();
+ *         ...
+ *     } catch (JSONException e) {
+ *         throw new RuntimeException(e);
+ *     }
+ * }</pre>
+ */
+public class JSONException extends Exception {
+
+    public JSONException(String s) {
+        super(s);
+    }
+}
diff --git a/json/src/rewrite/java/org/json/JSONObject.java b/json/src/rewrite/java/org/json/JSONObject.java
new file mode 100644
index 0000000..c92d549
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSONObject.java
@@ -0,0 +1,395 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ *
+ *
+ * <p>TODO: Note about self-use
+ */
+public class JSONObject {
+
+    private static final Double NEGATIVE_ZERO = -0d;
+
+    public static final Object NULL = new Object() {
+        @Override public boolean equals(Object o) {
+            return o == this || o == null; // API specifies this broken equals implementation
+        }
+        @Override public String toString() {
+            return "null";
+        }
+    };
+
+    private final Map<String, Object> nameValuePairs;
+
+    public JSONObject() {
+        nameValuePairs = new HashMap<String, Object>();
+    }
+
+    /* Accept a raw type for API compatibility */
+    public JSONObject(Map copyFrom) {
+        this();
+        Map<?, ?> contentsTyped = (Map<?, ?>) copyFrom;
+        for (Map.Entry<?, ?> entry : contentsTyped.entrySet()) {
+            /*
+             * Deviate from the original by checking that keys are non-null and
+             * of the proper type. (We still defer validating the values).
+             */
+            String key = (String) entry.getKey();
+            if (key == null) {
+                throw new NullPointerException();
+            }
+            nameValuePairs.put(key, entry.getValue());
+        }
+    }
+
+    public JSONObject(JSONTokener readFrom) throws JSONException {
+        /*
+         * Getting the parser to populate this could get tricky. Instead, just
+         * parse to temporary JSONObject and then steal the data from that.
+         */
+        Object object = readFrom.nextValue();
+        if (object instanceof JSONObject) {
+            this.nameValuePairs = ((JSONObject) object).nameValuePairs;
+        } else {
+            throw JSON.typeMismatch(object, "JSONObject");
+        }
+    }
+
+    public JSONObject(String json) throws JSONException {
+        this(new JSONTokener(json));
+    }
+
+    public JSONObject(JSONObject copyFrom, String[] names) throws JSONException {
+        this();
+        for (String name : names) {
+            Object value = copyFrom.opt(name);
+            if (value != null) {
+                nameValuePairs.put(name, value);
+            }
+        }
+    }
+
+    public int length() {
+        return nameValuePairs.size();
+    }
+
+    public JSONObject put(String name, boolean value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
+        return this;
+    }
+
+    public JSONObject put(String name, double value) throws JSONException {
+        nameValuePairs.put(checkName(name), JSON.checkDouble(value));
+        return this;
+    }
+
+    public JSONObject put(String name, int value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
+        return this;
+    }
+
+    public JSONObject put(String name, long value) throws JSONException {
+        nameValuePairs.put(checkName(name), value);
+        return this;
+    }
+
+    public JSONObject put(String name, Object value) throws JSONException {
+        if (value == null) {
+            nameValuePairs.remove(name);
+            return this;
+        }
+        if (value instanceof Number) {
+            // deviate from the original by checking all Numbers, not just floats & doubles
+            JSON.checkDouble(((Number) value).doubleValue());
+        }
+        nameValuePairs.put(checkName(name), value);
+        return this;
+    }
+
+    public JSONObject putOpt(String name, Object value) throws JSONException {
+        if (name == null || value == null) {
+            return this;
+        }
+        return put(name, value);
+    }
+
+    public JSONObject accumulate(String name, Object value) throws JSONException {
+        Object current = nameValuePairs.get(checkName(name));
+        if (current == null) {
+            put(name, value);
+        } else if (current instanceof JSONArray) {
+            JSONArray array = (JSONArray) current;
+            array.put(value);
+        } else {
+            JSONArray array = new JSONArray();
+            array.put(current);
+            array.put(value); // fails on bogus values
+            nameValuePairs.put(name, array);
+        }
+        return this;
+    }
+
+    String checkName(String name) throws JSONException {
+        if (name == null) {
+            throw new JSONException("Names must be non-null");
+        }
+        return name;
+    }
+
+    public Object remove(String name) {
+        return nameValuePairs.remove(name);
+    }
+
+    public boolean isNull(String name) {
+        Object value = nameValuePairs.get(name);
+        return value == null || value == NULL;
+    }
+
+    public boolean has(String name) {
+        return nameValuePairs.containsKey(name);
+    }
+
+    public Object get(String name) throws JSONException {
+        Object result = nameValuePairs.get(name);
+        if (result == null) {
+            throw new JSONException("No value for " + name);
+        }
+        return result;
+    }
+
+    public Object opt(String name) {
+        return nameValuePairs.get(name);
+    }
+
+    public boolean getBoolean(String name) throws JSONException {
+        Object object = get(name);
+        Boolean result = JSON.toBoolean(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "boolean");
+        }
+        return result;
+    }
+
+    public boolean optBoolean(String name) {
+        return optBoolean(name, false);
+    }
+
+    public boolean optBoolean(String name, boolean fallback) {
+        Object object = opt(name);
+        Boolean result = JSON.toBoolean(object);
+        return result != null ? result : fallback;
+    }
+
+    public double getDouble(String name) throws JSONException {
+        Object object = get(name);
+        Double result = JSON.toDouble(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "double");
+        }
+        return result;
+    }
+
+    public double optDouble(String name) {
+        return optDouble(name, Double.NaN);
+    }
+
+    public double optDouble(String name, double fallback) {
+        Object object = opt(name);
+        Double result = JSON.toDouble(object);
+        return result != null ? result : fallback;
+    }
+
+    public int getInt(String name) throws JSONException {
+        Object object = get(name);
+        Integer result = JSON.toInteger(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "int");
+        }
+        return result;
+    }
+
+    public int optInt(String name) {
+        return optInt(name, 0);
+    }
+
+    public int optInt(String name, int fallback) {
+        Object object = opt(name);
+        Integer result = JSON.toInteger(object);
+        return result != null ? result : fallback;
+    }
+
+    public long getLong(String name) throws JSONException {
+        Object object = get(name);
+        Long result = JSON.toLong(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "long");
+        }
+        return result;
+    }
+
+    public long optLong(String name) {
+        return optLong(name, 0L);
+    }
+
+    public long optLong(String name, long fallback) {
+        Object object = opt(name);
+        Long result = JSON.toLong(object);
+        return result != null ? result : fallback;
+    }
+
+    public String getString(String name) throws JSONException {
+        Object object = get(name);
+        String result = JSON.toString(object);
+        if (result == null) {
+            throw JSON.typeMismatch(name, object, "String");
+        }
+        return result;
+    }
+
+    public String optString(String name) {
+        return optString(name, "");
+    }
+
+    public String optString(String name, String fallback) {
+        Object object = opt(name);
+        String result = JSON.toString(object);
+        return result != null ? result : fallback;
+    }
+
+    public JSONArray getJSONArray(String name) throws JSONException {
+        Object object = get(name);
+        if (object instanceof JSONArray) {
+            return (JSONArray) object;
+        } else {
+            throw JSON.typeMismatch(name, object, "JSONArray");
+        }
+    }
+
+    public JSONArray optJSONArray(String name) {
+        Object object = opt(name);
+        return object instanceof JSONArray ? (JSONArray) object : null;
+    }
+
+    public JSONObject getJSONObject(String name) throws JSONException {
+        Object object = get(name);
+        if (object instanceof JSONObject) {
+            return (JSONObject) object;
+        } else {
+            throw JSON.typeMismatch(name, object, "JSONObject");
+        }
+    }
+
+    public JSONObject optJSONObject(String name) {
+        Object object = opt(name);
+        return object instanceof JSONObject ? (JSONObject) object : null;
+    }
+
+    public JSONArray toJSONArray(JSONArray names) throws JSONException {
+        JSONArray result = new JSONArray();
+        if (names == null) {
+            return null;
+        }
+        int length = names.length();
+        if (length == 0) {
+            return null;
+        }
+        for (int i = 0; i < length; i++) {
+            String name = JSON.toString(names.opt(i));
+            result.put(opt(name));
+        }
+        return result;
+    }
+
+    /* Return a raw type for API compatibility */
+    public Iterator keys() {
+        return nameValuePairs.keySet().iterator();
+    }
+
+    public JSONArray names() {
+        return nameValuePairs.isEmpty()
+                ? null
+                : new JSONArray(new ArrayList<String>(nameValuePairs.keySet()));
+    }
+
+    @Override public String toString() {
+        try {
+            JSONStringer stringer = new JSONStringer();
+            writeTo(stringer);
+            return stringer.toString();
+        } catch (JSONException e) {
+            return null;
+        }
+    }
+
+    public String toString(int indentSpaces) throws JSONException {
+        JSONStringer stringer = new JSONStringer(indentSpaces);
+        writeTo(stringer);
+        return stringer.toString();
+    }
+
+    void writeTo(JSONStringer stringer) throws JSONException {
+        stringer.object();
+        for (Map.Entry<String, Object> entry : nameValuePairs.entrySet()) {
+            stringer.key(entry.getKey()).value(entry.getValue());
+        }
+        stringer.endObject();
+    }
+
+    public static String numberToString(Number number) throws JSONException {
+        if (number == null) {
+            throw new JSONException("Number must be non-null");
+        }
+
+        double doubleValue = number.doubleValue();
+        JSON.checkDouble(doubleValue);
+
+        // the original returns "-0" instead of "-0.0" for negative zero
+        if (number.equals(NEGATIVE_ZERO)) {
+            return "-0";
+        }
+
+        long longValue = number.longValue();
+        if (doubleValue == (double) longValue) {
+            return Long.toString(longValue);
+        }
+
+        return number.toString();
+    }
+
+    public static String quote(String data) {
+        if (data == null) {
+            return "\"\"";
+        }
+        try {
+            JSONStringer stringer = new JSONStringer();
+            stringer.open(JSONStringer.Scope.NULL, "");
+            stringer.value(data);
+            stringer.close(JSONStringer.Scope.NULL, JSONStringer.Scope.NULL, "");
+            return stringer.toString();
+        } catch (JSONException e) {
+            throw new AssertionError();
+        }
+    }
+}
diff --git a/json/src/rewrite/java/org/json/JSONStringer.java b/json/src/rewrite/java/org/json/JSONStringer.java
new file mode 100644
index 0000000..fb60bd1
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSONStringer.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ *
+ */
+public class JSONStringer {
+
+    /** The output data, containing at most one top-level array or object. */
+    final StringBuilder out = new StringBuilder();
+
+    /**
+     * Lexical scoping elements within this stringer, necessary to insert the
+     * appropriate separator characters (ie. commas and colons) and to detect
+     * nesting errors.
+     */
+    enum Scope {
+
+        /**
+         * An array with no elements requires no separators or newlines before
+         * it is closed.
+         */
+        EMPTY_ARRAY,
+
+        /**
+         * A array with at least one value requires a comma and newline before
+         * the next element.
+         */
+        NONEMPTY_ARRAY,
+
+        /**
+         * An object with no keys or values requires no separators or newlines
+         * before it is closed.
+         */
+        EMPTY_OBJECT,
+
+        /**
+         * An object whose most recent element is a key. The next element must
+         * be a value.
+         */
+        DANGLING_KEY,
+
+        /**
+         * An object with at least one name/value pair requires a comma and
+         * newline before the next element.
+         */
+        NONEMPTY_OBJECT,
+
+        /**
+         * A special bracketless array needed by JSONStringer.join() and
+         * JSONObject.quote() only. Not used for JSON encoding.
+         */
+        NULL,
+    }
+
+    /**
+     * Unlike the original implementation, this stack isn't limited to 20
+     * levels of nesting.
+     */
+    private final List<Scope> stack = new ArrayList<Scope>();
+
+    /**
+     * A string containing a full set of spaces for a single level of
+     * indentation, or null for no pretty printing.
+     */
+    private final String indent;
+
+    public JSONStringer() {
+        indent = null;
+    }
+
+    JSONStringer(int indentSpaces) {
+        char[] indentChars = new char[indentSpaces];
+        Arrays.fill(indentChars, ' ');
+        indent = new String(indentChars);
+    }
+
+    public JSONStringer array() throws JSONException {
+        return open(Scope.EMPTY_ARRAY, "[");
+    }
+
+    public JSONStringer endArray() throws JSONException {
+        return close(Scope.EMPTY_ARRAY, Scope.NONEMPTY_ARRAY, "]");
+    }
+
+    public JSONStringer object() throws JSONException {
+        return open(Scope.EMPTY_OBJECT, "{");
+    }
+
+    public JSONStringer endObject() throws JSONException {
+        return close(Scope.EMPTY_OBJECT, Scope.NONEMPTY_OBJECT, "}");
+    }
+
+    /**
+     * Enters a new scope by appending any necessary whitespace and the given
+     * bracket.
+     */
+    JSONStringer open(Scope empty, String openBracket) throws JSONException {
+        if (stack.isEmpty() && out.length() > 0) {
+            throw new JSONException("Nesting problem: multiple top-level roots");
+        }
+        beforeValue();
+        stack.add(empty);
+        out.append(openBracket);
+        return this;
+    }
+
+    /**
+     * Closes the current scope by appending any necessary whitespace and the
+     * given bracket.
+     */
+    JSONStringer close(Scope empty, Scope nonempty, String closeBracket) throws JSONException {
+        Scope context = peek();
+        if (context != nonempty && context != empty) {
+            throw new JSONException("Nesting problem");
+        }
+
+        stack.remove(stack.size() - 1);
+        if (context == nonempty) {
+            newline();
+        }
+        out.append(closeBracket);
+        return this;
+    }
+
+    /**
+     * Returns the value on the top of the stack.
+     */
+    private Scope peek() throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        return stack.get(stack.size() - 1);
+    }
+
+    /**
+     * Replace the value on the top of the stack with the given value.
+     */
+    private void replaceTop(Scope topOfStack) {
+        stack.set(stack.size() - 1, topOfStack);
+    }
+
+    public JSONStringer value(Object value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+
+        if (value instanceof JSONArray) {
+            ((JSONArray) value).writeTo(this);
+            return this;
+
+        } else if (value instanceof JSONObject) {
+            ((JSONObject) value).writeTo(this);
+            return this;
+        }
+
+        beforeValue();
+
+        if (value == null
+                || value instanceof Boolean
+                || value == JSONObject.NULL) {
+            out.append(value);
+
+        } else if (value instanceof Number) {
+            out.append(JSONObject.numberToString((Number) value));
+
+        } else {
+            string(value.toString());
+        }
+
+        return this;
+    }
+
+    public JSONStringer value(boolean value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    public JSONStringer value(double value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(JSONObject.numberToString(value));
+        return this;
+    }
+
+    public JSONStringer value(long value) throws JSONException {
+        if (stack.isEmpty()) {
+            throw new JSONException("Nesting problem");
+        }
+        beforeValue();
+        out.append(value);
+        return this;
+    }
+
+    private void string(String value) {
+        out.append("\"");
+        for (int i = 0, length = value.length(); i < length; i++) {
+            char c = value.charAt(i);
+
+            /*
+             * From RFC 4627, "All Unicode characters may be placed within the
+             * quotation marks except for the characters that must be escaped:
+             * quotation mark, reverse solidus, and the control characters
+             * (U+0000 through U+001F)."
+             */
+            switch (c) {
+                case '"':
+                case '\\':
+                case '/':
+                    out.append('\\').append(c);
+                    break;
+
+                case '\t':
+                    out.append("\\t");
+                    break;
+
+                case '\b':
+                    out.append("\\b");
+                    break;
+
+                case '\n':
+                    out.append("\\n");
+                    break;
+
+                case '\r':
+                    out.append("\\r");
+                    break;
+
+                case '\f':
+                    out.append("\\f");
+                    break;
+
+                default:
+                    if (c <= 0x1F) {
+                        out.append(String.format("\\u%04x", (int) c));
+                    } else {
+                        out.append(c);
+                    }
+                    break;
+            }
+
+        }
+        out.append("\"");
+    }
+
+    private void newline() {
+        if (indent == null) {
+            return;
+        }
+
+        out.append("\n");
+        for (int i = 0; i < stack.size(); i++) {
+            out.append(indent);
+        }
+    }
+
+    public JSONStringer key(String name) throws JSONException {
+        if (name == null) {
+            throw new JSONException("Names must be non-null");
+        }
+        beforeKey();
+        string(name);
+        return this;
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a name. Also
+     * adjusts the stack to expect the key's value.
+     */
+    private void beforeKey() throws JSONException {
+        Scope context = peek();
+        if (context == Scope.NONEMPTY_OBJECT) { // first in object
+            out.append(',');
+        } else if (context != Scope.EMPTY_OBJECT) { // not in an object!
+            throw new JSONException("Nesting problem");
+        }
+        newline();
+        replaceTop(Scope.DANGLING_KEY);
+    }
+
+    /**
+     * Inserts any necessary separators and whitespace before a literal value,
+     * inline array, or inline object. Also adjusts the stack to expect either a
+     * closing bracket or another element.
+     */
+    private void beforeValue() throws JSONException {
+        if (stack.isEmpty()) {
+            return;
+        }
+
+        Scope context = peek();
+        if (context == Scope.EMPTY_ARRAY) { // first in array
+            replaceTop(Scope.NONEMPTY_ARRAY);
+            newline();
+        } else if (context == Scope.NONEMPTY_ARRAY) { // another in array
+            out.append(',');
+            newline();
+        } else if (context == Scope.DANGLING_KEY) { // value for key
+            out.append(indent == null ? ":" : ": ");
+            replaceTop(Scope.NONEMPTY_OBJECT);
+        } else if (context != Scope.NULL) {
+            throw new JSONException("Nesting problem");
+        }
+    }
+
+    /**
+     * Although it contradicts the general contract of {@link Object#toString},
+     * this method returns null if the stringer contains no data.
+     */
+    @Override public String toString() {
+        return out.length() == 0 ? null : out.toString();
+    }
+}
diff --git a/json/src/rewrite/java/org/json/JSONTokener.java b/json/src/rewrite/java/org/json/JSONTokener.java
new file mode 100644
index 0000000..e249c74
--- /dev/null
+++ b/json/src/rewrite/java/org/json/JSONTokener.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+// Note: this class was written without inspecting the non-free org.json sourcecode.
+
+/**
+ *
+ */
+public class JSONTokener {
+
+    /** The input JSON. */
+    private final String in;
+
+    /**
+     * The index of the next character to be returned by {@link #next()}. When
+     * the input is exhausted, this equals the input's length.
+     */
+    private int pos;
+
+    public JSONTokener(String in) {
+        this.in = in;
+    }
+
+    public Object nextValue() throws JSONException {
+        int c = nextCleanInternal();
+        switch (c) {
+            case -1:
+                throw syntaxError("End of input");
+
+            case '{':
+                return readObject();
+
+            case '[':
+                return readArray();
+
+            case '\'':
+            case '"':
+                return nextString((char) c);
+
+            default:
+                pos--;
+                return readLiteral();
+        }
+    }
+
+    private int nextCleanInternal() throws JSONException {
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            switch (c) {
+                case '\t':
+                case ' ':
+                case '\n':
+                case '\r':
+                    continue;
+
+                case '/':
+                    if (pos == in.length()) {
+                        return c;
+                    }
+
+                    char peek = in.charAt(pos);
+                    if (peek != '*' && peek != '/') {
+                        return c;
+                    }
+
+                    skipComment();
+                    continue;
+
+                default:
+                    return c;
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Advances the position until it is beyond the current comment. The opening
+     * slash '/' should have already been read, and character at the current
+     * position be an asterisk '*' for a C-style comment or a slash '/' for an
+     * end-of-line comment.
+     *
+     * @throws JSONException if a C-style comment was not terminated.
+     */
+    private void skipComment() throws JSONException {
+        if (in.charAt(pos++) == '*') {
+            int commentEnd = in.indexOf("*/", pos);
+            if (commentEnd == -1) {
+                throw syntaxError("Unterminated comment");
+            }
+            pos = commentEnd + 2;
+
+        } else {
+            /*
+             * Skip to the next newline character. If the line is terminated by
+             * "\r\n", the '\n' will be consumed as whitespace by the caller.
+             */
+            for (; pos < in.length(); pos++) {
+                char c = in.charAt(pos);
+                if (c == '\r' || c == '\n') {
+                    pos++;
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     *
+     *
+     * @throws NumberFormatException if any unicode escape sequences are
+     *     malformed.
+     */
+    public String nextString(char quote) throws JSONException {
+        /*
+         * For strings that are free of escape sequences, we can just extract
+         * the result as a substring of the input. But if we encounter an escape
+         * sequence, we need to use a StringBuilder to compose the result.
+         */
+        StringBuilder builder = null;
+
+        /* the index of the first character not yet appended to the builder. */
+        int start = pos;
+
+        while (pos < in.length()) {
+            int c = in.charAt(pos++);
+            if (c == quote) {
+                if (builder == null) {
+                    // a new string avoids leaking memory
+                    return new String(in.substring(start, pos - 1));
+                } else {
+                    builder.append(in, start, pos - 1);
+                    return builder.toString();
+                }
+            }
+
+            if (c == '\\') {
+                if (pos == in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                if (builder == null) {
+                    builder = new StringBuilder();
+                }
+                builder.append(in, start, pos - 1);
+                builder.append(readEscapeCharacter());
+                start = pos;
+            }
+        }
+
+        throw syntaxError("Unterminated string");
+    }
+
+    /**
+     * Unescapes the character identified by the character or characters that
+     * immediately follow a backslash. The backslash '\' should have already
+     * been read. This supports both unicode escapes "u000A" and two-character
+     * escapes "\n".
+     *
+     * @throws NumberFormatException if any unicode escape sequences are
+     *     malformed.
+     */
+    private char readEscapeCharacter() throws JSONException {
+        char escaped = in.charAt(pos++);
+        switch (escaped) {
+            case 'u':
+                if (pos + 4 > in.length()) {
+                    throw syntaxError("Unterminated escape sequence");
+                }
+                String hex = in.substring(pos, pos + 4);
+                pos += 4;
+                return (char) Integer.parseInt(hex, 16);
+
+            case 't':
+                return '\t';
+
+            case 'b':
+                return '\b';
+
+            case 'n':
+                return '\n';
+
+            case 'r':
+                return '\r';
+
+            case 'f':
+                return '\f';
+
+            case '\'':
+            case '"':
+            case '\\':
+            default:
+                return escaped;
+        }
+    }
+
+    /**
+     * Reads a null, boolean, numeric or unquoted string literal value. Numeric
+     * values will be returned as an Integer, Long, or Double, in that order of
+     * preference.
+     */
+    private Object readLiteral() throws JSONException {
+        String literal = nextToInternal("{}[]/\\:,=;# \t\f");
+
+        if (literal.length() == 0) {
+            throw syntaxError("Expected literal value");
+        } else if ("null".equalsIgnoreCase(literal)) {
+            return JSONObject.NULL;
+        } else if ("true".equalsIgnoreCase(literal)) {
+            return Boolean.TRUE;
+        } else if ("false".equalsIgnoreCase(literal)) {
+            return Boolean.FALSE;
+        }
+
+        /* try to parse as an integral type... */
+        if (literal.indexOf('.') == -1) {
+            int base = 10;
+            String number = literal;
+            if (number.startsWith("0x") || number.startsWith("0X")) {
+                number = number.substring(2);
+                base = 16;
+            } else if (number.startsWith("0") && number.length() > 1) {
+                number = number.substring(1);
+                base = 8;
+            }
+            try {
+                long longValue = Long.parseLong(number, base);
+                if (longValue <= Integer.MAX_VALUE && longValue >= Integer.MIN_VALUE) {
+                    return (int) longValue;
+                } else {
+                    return longValue;
+                }
+            } catch (NumberFormatException e) {
+                /*
+                 * This only happens for integral numbers greater than
+                 * Long.MAX_VALUE, numbers in exponential form (5e-10) and
+                 * unquoted strings. Fall through to try floating point.
+                 */
+            }
+        }
+
+        /* ...next try to parse as a floating point... */
+        try {
+            return Double.valueOf(literal);
+        } catch (NumberFormatException e) {
+        }
+
+        /* ... finally give up. We have an unquoted string */
+        return new String(literal); // a new string avoids leaking memory
+    }
+
+    /**
+     * Returns text from the current position until the first of any of the
+     * given characters or a newline character, excluding that character. The
+     * position is advanced to the excluded character.
+     */
+    private String nextToInternal(String excluded) {
+        int start = pos;
+        for (; pos < in.length(); pos++) {
+            char c = in.charAt(pos);
+            if (c == '\r' || c == '\n' || excluded.indexOf(c) != -1) {
+                return in.substring(start, pos);
+            }
+        }
+        return in.substring(start);
+    }
+
+    /**
+     * Reads a sequence of key/value pairs and the trailing closing brace '}' of
+     * an object. The opening brace '{' should have already been read.
+     */
+    private JSONObject readObject() throws JSONException {
+        JSONObject result = new JSONObject();
+
+        /* Peek to see if this is the empty object. */
+        int first = nextCleanInternal();
+        if (first == '}') {
+            return result;
+        } else if (first != -1) {
+            pos--;
+        }
+
+        while (true) {
+            Object name = nextValue();
+            if (!(name instanceof String)) {
+                if (name == null) {
+                    throw syntaxError("Names cannot be null");
+                } else {
+                    throw syntaxError("Names must be strings, but " + name
+                            + " is of type " + name.getClass().getName());
+                }
+            }
+
+            /*
+             * Expect the name/value separator to be either a colon ':', an
+             * equals sign '=', or an arrow "=>". The last two are bogus but we
+             * include them because that's what the original implementation did.
+             */
+            int separator = nextCleanInternal();
+            if (separator != ':' && separator != '=') {
+                throw syntaxError("Expected ':' after " + name);
+            }
+            if (pos < in.length() && in.charAt(pos) == '>') {
+                pos++;
+            }
+
+            result.put((String) name, nextValue());
+
+            switch (nextCleanInternal()) {
+                case '}':
+                    return result;
+                case ';':
+                case ',':
+                    continue;
+                default:
+                    throw syntaxError("Unterminated object");
+            }
+        }
+    }
+
+    /**
+     * Reads a sequence of values and the trailing closing brace ']' of an
+     * array. The opening brace '[' should have already been read. Note that
+     * "[]" yields an empty array, but "[,]" returns a two-element array
+     * equivalent to "[null,null]".
+     */
+    private JSONArray readArray() throws JSONException {
+        JSONArray result = new JSONArray();
+
+        /* to cover input that ends with ",]". */
+        boolean hasTrailingSeparator = false;
+
+        while (true) {
+            switch (nextCleanInternal()) {
+                case -1:
+                    throw syntaxError("Unterminated array");
+                case ']':
+                    if (hasTrailingSeparator) {
+                        result.put(null);
+                    }
+                    return result;
+                case ',':
+                case ';':
+                    /* A separator without a value first means "null". */
+                    result.put(null);
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    pos--;
+            }
+
+            result.put(nextValue());
+
+            switch (nextCleanInternal()) {
+                case ']':
+                    return result;
+                case ',':
+                case ';':
+                    hasTrailingSeparator = true;
+                    continue;
+                default:
+                    throw syntaxError("Unterminated array");
+            }
+        }
+    }
+
+    public JSONException syntaxError(String text) {
+        return new JSONException(text + this);
+    }
+
+    @Override public String toString() {
+        // consistent with the original implementation
+        return " at character " + pos + " of " + in;
+    }
+
+    /*
+     * Legacy APIs.
+     *
+     * None of the methods below are on the critical path of parsing JSON
+     * documents. They exist only because they were exposed by the original
+     * implementation and may be used by some clients.
+     */
+
+    public boolean more() {
+        return pos < in.length();
+    }
+
+    public char next() {
+        return pos < in.length() ? in.charAt(pos++) : '\0';
+    }
+
+    public char next(char c) throws JSONException {
+        char result = next();
+        if (result != c) {
+            throw syntaxError("Expected " + c + " but was " + result);
+        }
+        return result;
+    }
+
+    public char nextClean() throws JSONException {
+        int nextCleanInt = nextCleanInternal();
+        return nextCleanInt == -1 ? '\0' : (char) nextCleanInt;
+    }
+
+    /**
+     * TODO: note about how this method returns a substring, and could cause a memory leak
+     */
+    public String next(int length) throws JSONException {
+        if (pos + length > in.length()) {
+            throw syntaxError(length + " is out of bounds");
+        }
+        String result = in.substring(pos, pos + length);
+        pos += length;
+        return result;
+    }
+
+    /**
+     * TODO: note about how this method returns a substring, and could cause a memory leak
+     */
+    public String nextTo(String excluded) {
+        if (excluded == null) {
+            throw new NullPointerException();
+        }
+        return nextToInternal(excluded).trim();
+    }
+
+    /**
+     * TODO: note about how this method returns a substring, and could cause a memory leak
+     */
+    public String nextTo(char excluded) {
+        return nextToInternal(String.valueOf(excluded)).trim();
+    }
+
+    public void skipPast(String thru) {
+        int thruStart = in.indexOf(thru, pos);
+        pos = thruStart == -1 ? in.length() : (thruStart + thru.length());
+    }
+
+    public char skipTo(char to) {
+        for (int i = pos, length = in.length(); i < length; i++) {
+            if (in.charAt(i) == to) {
+                pos = i;
+                return to;
+            }
+        }
+        return '\0';
+    }
+
+    public void back() {
+        if (--pos == -1) {
+            pos = 0;
+        }
+    }
+
+    public static int dehexchar(char hex) {
+        if (hex >= '0' && hex <= '9') {
+            return hex - '0';
+        } else if (hex >= 'A' && hex <= 'F') {
+            return hex - 'A' + 10;
+        } else if (hex >= 'a' && hex <= 'f') {
+            return hex - 'a' + 10;
+        } else {
+            return -1;
+        }
+    }
+}
diff --git a/json/src/test/java/org/json/AllTests.java b/json/src/test/java/org/json/AllTests.java
index ee6c90e..8f5cc94 100644
--- a/json/src/test/java/org/json/AllTests.java
+++ b/json/src/test/java/org/json/AllTests.java
@@ -26,6 +26,7 @@
         suite.addTestSuite(JSONObjectTest.class);
         suite.addTestSuite(JSONStringerTest.class);
         suite.addTestSuite(JSONTokenerTest.class);
+        suite.addTestSuite(ParsingTest.class);
         suite.addTestSuite(SelfUseTest.class);
         return suite;
     }
diff --git a/json/src/test/java/org/json/JSONArrayTest.java b/json/src/test/java/org/json/JSONArrayTest.java
index d6013a8..485a729 100644
--- a/json/src/test/java/org/json/JSONArrayTest.java
+++ b/json/src/test/java/org/json/JSONArrayTest.java
@@ -1,11 +1,11 @@
-/**
+/*
  * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -20,6 +20,7 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.Collections;
 
 /**
  * This black box test was written without inspecting the non-free org.json sourcecode.
@@ -50,7 +51,7 @@
         assertFalse(array.optBoolean(0));
         assertTrue(array.optBoolean(0, true));
 
-        // bogus (but documented) behaviour: returns null rather than an empty object
+        // bogus (but documented) behaviour: returns null rather than an empty object!
         assertNull(array.toJSONObject(new JSONArray()));
     }
 
@@ -58,8 +59,7 @@
         JSONArray a = new JSONArray();
         JSONArray b = new JSONArray();
         assertTrue(a.equals(b));
-        // bogus behavior: JSONArray overrides equals() but not hashCode().
-        assertEquals(a.hashCode(), b.hashCode());
+        assertEquals("equals() not consistent with hashCode()", a.hashCode(), b.hashCode());
 
         a.put(true);
         a.put(false);
@@ -129,7 +129,7 @@
         assertEquals(4, array.length());
         assertEquals("[null,null,null,null]", array.toString());
 
-        // bogus behaviour: there's 2 ways to represent null; each behaves differently!
+        // there's 2 ways to represent null; each behaves differently!
         assertEquals(JSONObject.NULL, array.get(0));
         try {
             array.get(1);
@@ -168,7 +168,7 @@
         array.put(-0d);
         assertEquals(4, array.length());
 
-        // bogus behaviour: toString() and getString(int) return different values for -0d
+        // toString() and getString(int) return different values for -0d
         assertEquals("[4.9E-324,9223372036854775806,1.7976931348623157E308,-0]", array.toString());
 
         assertEquals(Double.MIN_VALUE, array.get(0));
@@ -259,6 +259,32 @@
         assertEquals(-1.0d, array.optDouble(3, -1.0d));
     }
 
+    public void testJoin() throws JSONException {
+        JSONArray array = new JSONArray();
+        array.put(null);
+        assertEquals("null", array.join(" & "));
+        array.put("\"");
+        assertEquals("null & \"\\\"\"", array.join(" & "));
+        array.put(5);
+        assertEquals("null & \"\\\"\" & 5", array.join(" & "));
+        array.put(true);
+        assertEquals("null & \"\\\"\" & 5 & true", array.join(" & "));
+        array.put(new JSONArray(Arrays.asList(true, false)));
+        assertEquals("null & \"\\\"\" & 5 & true & [true,false]", array.join(" & "));
+        array.put(new JSONObject(Collections.singletonMap("x", 6)));
+        assertEquals("null & \"\\\"\" & 5 & true & [true,false] & {\"x\":6}", array.join(" & "));
+    }
+
+    public void testJoinWithNull() throws JSONException {
+        JSONArray array = new JSONArray(Arrays.asList(5, 6));
+        assertEquals("5null6", array.join(null));
+    }
+
+    public void testJoinWithSpecialCharacters() throws JSONException {
+        JSONArray array = new JSONArray(Arrays.asList(5, 6));
+        assertEquals("5\"6", array.join("\""));
+    }
+
     public void testToJSONObject() throws JSONException {
         JSONArray keys = new JSONArray();
         keys.put("a");
@@ -286,7 +312,7 @@
         values.put(5.5d);
         values.put(null);
 
-        // bogus behaviour: null values are stripped
+        // null values are stripped!
         JSONObject object = values.toJSONObject(keys);
         assertEquals(1, object.length());
         assertFalse(object.has("b"));
@@ -345,6 +371,14 @@
         }
     }
 
+    public void testPutUnsupportedNumbersAsObject() throws JSONException {
+        JSONArray array = new JSONArray();
+        array.put(Double.valueOf(Double.NaN));
+        array.put(Double.valueOf(Double.NEGATIVE_INFINITY));
+        array.put(Double.valueOf(Double.POSITIVE_INFINITY));
+        assertEquals(null, array.toString());
+    }
+
     /**
      * Although JSONArray is usually defensive about which numbers it accepts,
      * it doesn't check inputs in its constructor.
@@ -357,7 +391,7 @@
     }
 
     public void testToStringWithUnsupportedNumbers() throws JSONException {
-        // bogus behaviour: when the array contains an unsupported number, toString returns null
+        // when the array contains an unsupported number, toString returns null!
         JSONArray array = new JSONArray(Arrays.asList(5.5, Double.NaN));
         assertNull(array.toString());
     }
@@ -369,6 +403,70 @@
         assertEquals(5, array.get(0));
     }
 
+    public void testTokenerConstructor() throws JSONException {
+        JSONArray object = new JSONArray(new JSONTokener("[false]"));
+        assertEquals(1, object.length());
+        assertEquals(false, object.get(0));
+    }
+
+    public void testTokenerConstructorWrongType() throws JSONException {
+        try {
+            new JSONArray(new JSONTokener("{\"foo\": false}"));
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testTokenerConstructorNull() throws JSONException {
+        try {
+            new JSONArray((JSONTokener) null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testTokenerConstructorParseFail() {
+        try {
+            new JSONArray(new JSONTokener("["));
+            fail();
+        } catch (JSONException e) {
+        } catch (StackOverflowError e) {
+            fail("Stack overflowed on input: \"[\"");
+        }
+    }
+
+    public void testStringConstructor() throws JSONException {
+        JSONArray object = new JSONArray("[false]");
+        assertEquals(1, object.length());
+        assertEquals(false, object.get(0));
+    }
+
+    public void testStringConstructorWrongType() throws JSONException {
+        try {
+            new JSONArray("{\"foo\": false}");
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testStringConstructorNull() throws JSONException {
+        try {
+            new JSONArray((String) null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testStringConstructorParseFail() {
+        try {
+            new JSONArray("[");
+            fail();
+        } catch (JSONException e) {
+        } catch (StackOverflowError e) {
+            fail("Stack overflowed on input: \"[\"");
+        }
+    }
+
     public void testCreate() throws JSONException {
         JSONArray array = new JSONArray(Arrays.asList(5.5, true));
         assertEquals(2, array.length());
@@ -405,8 +503,4 @@
         } catch (JSONException e) {
         }
     }
-
-    public void testParsingConstructor() {
-        fail("TODO");
-    }
 }
diff --git a/json/src/test/java/org/json/JSONObjectTest.java b/json/src/test/java/org/json/JSONObjectTest.java
index 83beea8..e431096 100644
--- a/json/src/test/java/org/json/JSONObjectTest.java
+++ b/json/src/test/java/org/json/JSONObjectTest.java
@@ -1,11 +1,11 @@
-/**
- * Copyright (C) 2010 Google Inc.
+/*
+ * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,7 +14,6 @@
  * limitations under the License.
  */
 
-
 package org.json;
 
 import junit.framework.TestCase;
@@ -32,10 +31,10 @@
         JSONObject object = new JSONObject();
         assertEquals(0, object.length());
 
-        // bogus (but documented) behaviour: returns null rather than the empty object
+        // bogus (but documented) behaviour: returns null rather than the empty object!
         assertNull(object.names());
 
-        // bogus behaviour: returns null rather than an empty array
+        // returns null rather than an empty array!
         assertNull(object.toJSONArray(new JSONArray()));
         assertEquals("{}", object.toString());
         assertEquals("{}", object.toString(5));
@@ -246,13 +245,14 @@
         object.put("quux", -0d);
         assertEquals(4, object.length());
 
-        assertTrue(object.toString().contains("\"foo\":4.9E-324"));
-        assertTrue(object.toString().contains("\"bar\":9223372036854775806"));
-        assertTrue(object.toString().contains("\"baz\":1.7976931348623157E308"));
+        String toString = object.toString();
+        assertTrue(toString, toString.contains("\"foo\":4.9E-324"));
+        assertTrue(toString, toString.contains("\"bar\":9223372036854775806"));
+        assertTrue(toString, toString.contains("\"baz\":1.7976931348623157E308"));
 
-        // bogus behaviour: toString() and getString() return different values for -0d
-        assertTrue(object.toString().contains("\"quux\":-0}") // no trailing decimal point
-                || object.toString().contains("\"quux\":-0,"));
+        // toString() and getString() return different values for -0d!
+        assertTrue(toString, toString.contains("\"quux\":-0}") // no trailing decimal point
+                || toString.contains("\"quux\":-0,"));
 
         assertEquals(Double.MIN_VALUE, object.get("foo"));
         assertEquals(9223372036854775806L, object.get("bar"));
@@ -310,13 +310,13 @@
     public void testOtherNumbers() throws JSONException {
         Number nan = new Number() {
             public int intValue() {
-                return 0;
+                throw new UnsupportedOperationException();
             }
             public long longValue() {
-                return 1L;
+                throw new UnsupportedOperationException();
             }
             public float floatValue() {
-                return 2;
+                throw new UnsupportedOperationException();
             }
             public double doubleValue() {
                 return Double.NaN;
@@ -326,10 +326,12 @@
             }
         };
 
-        // bogus behaviour: foreign object types should be rejected!
         JSONObject object = new JSONObject();
-        object.put("foo", nan);
-        assertEquals("{\"foo\":x}", object.toString());
+        try {
+            object.put("foo", nan);
+            fail("Object.put() accepted a NaN (via a custom Number class)");
+        } catch (JSONException e) {
+        }
     }
 
     public void testForeignObjects() throws JSONException {
@@ -339,7 +341,7 @@
             }
         };
 
-        // bogus behaviour: foreign object types should be rejected and not treated as Strings
+        // foreign object types are accepted and treated as Strings!
         JSONObject object = new JSONObject();
         object.put("foo", foreign);
         assertEquals("{\"foo\":\"x\"}", object.toString());
@@ -527,7 +529,7 @@
         names.put(false);
         names.put("foo");
 
-        // bogus behaviour: array elements are converted to Strings
+        // array elements are converted to strings to do name lookups on the map!
         JSONArray array = object.toJSONArray(names);
         assertEquals(3, array.length());
         assertEquals(10, array.get(0));
@@ -590,7 +592,7 @@
     }
 
     public void testToStringWithUnsupportedNumbers() {
-        // bogus behaviour: when the object contains an unsupported number, toString returns null
+        // when the object contains an unsupported number, toString returns null!
         JSONObject object = new JSONObject(Collections.singletonMap("foo", Double.NaN));
         assertEquals(null, object.toString());
     }
@@ -607,8 +609,97 @@
         Map<Object, Object> contents = new HashMap<Object, Object>();
         contents.put(5, 5);
 
-        // bogus behaviour: the constructor doesn't validate its input
-        new JSONObject(contents);
+        try {
+            new JSONObject(contents);
+            fail("JSONObject constructor doesn't validate its input!");
+        } catch (Exception e) {
+        }
+    }
+
+    public void testTokenerConstructor() throws JSONException {
+        JSONObject object = new JSONObject(new JSONTokener("{\"foo\": false}"));
+        assertEquals(1, object.length());
+        assertEquals(false, object.get("foo"));
+    }
+
+    public void testTokenerConstructorWrongType() throws JSONException {
+        try {
+            new JSONObject(new JSONTokener("[\"foo\", false]"));
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testTokenerConstructorNull() throws JSONException {
+        try {
+            new JSONObject((JSONTokener) null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testTokenerConstructorParseFail() {
+        try {
+            new JSONObject(new JSONTokener("{"));
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testStringConstructor() throws JSONException {
+        JSONObject object = new JSONObject("{\"foo\": false}");
+        assertEquals(1, object.length());
+        assertEquals(false, object.get("foo"));
+    }
+
+    public void testStringConstructorWrongType() throws JSONException {
+        try {
+            new JSONObject("[\"foo\", false]");
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testStringConstructorNull() throws JSONException {
+        try {
+            new JSONObject((String) null);
+            fail();
+        } catch (NullPointerException e) {
+        }
+    }
+
+    public void testStringonstructorParseFail() {
+        try {
+            new JSONObject("{");
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testCopyConstructor() throws JSONException {
+        JSONObject source = new JSONObject();
+        source.put("a", JSONObject.NULL);
+        source.put("b", false);
+        source.put("c", 5);
+
+        JSONObject copy = new JSONObject(source, new String[] { "a", "c" });
+        assertEquals(2, copy.length());
+        assertEquals(JSONObject.NULL, copy.get("a"));
+        assertEquals(5, copy.get("c"));
+        assertEquals(null, copy.opt("b"));
+    }
+
+    public void testCopyConstructorMissingName() throws JSONException {
+        JSONObject source = new JSONObject();
+        source.put("a", JSONObject.NULL);
+        source.put("b", false);
+        source.put("c", 5);
+
+        JSONObject copy = new JSONObject(source, new String[]{ "a", "c", "d" });
+        assertEquals(2, copy.length());
+        assertEquals(JSONObject.NULL, copy.get("a"));
+        assertEquals(5, copy.get("c"));
+        assertEquals(0, copy.optInt("b"));
     }
 
     public void testAccumulateMutatesInPlace() throws JSONException {
@@ -658,7 +749,7 @@
         object.put("foo", JSONObject.NULL);
         object.put("bar", null);
 
-        // bogus behaviour: there's 2 ways to represent null; each behaves differently!
+        // there are two ways to represent null; each behaves differently!
         assertTrue(object.has("foo"));
         assertFalse(object.has("bar"));
         assertTrue(object.isNull("foo"));
@@ -767,7 +858,11 @@
     }
 
     public void testQuote() {
-        // covered by JSONStringerTest.testEscaping()
+        // covered by JSONStringerTest.testEscaping
+    }
+
+    public void testQuoteNull() throws JSONException {
+        assertEquals("\"\"", JSONObject.quote(null));
     }
 
     public void testNumberToString() throws JSONException {
diff --git a/json/src/test/java/org/json/JSONStringerTest.java b/json/src/test/java/org/json/JSONStringerTest.java
index 03a2903..64c3a74 100644
--- a/json/src/test/java/org/json/JSONStringerTest.java
+++ b/json/src/test/java/org/json/JSONStringerTest.java
@@ -1,11 +1,11 @@
-/**
+/*
  * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -24,7 +24,7 @@
 public class JSONStringerTest extends TestCase {
 
     public void testEmptyStringer() {
-        // bogus behaviour: why isn't this the empty string?
+        // why isn't this the empty string?
         assertNull(new JSONStringer().toString());
     }
 
@@ -62,6 +62,16 @@
         assertEquals("[false,5,5,\"five\",null]", stringer.toString());
     }
 
+    public void testValueObjectMethods() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(Boolean.FALSE);
+        stringer.value(Double.valueOf(5.0));
+        stringer.value(Long.valueOf(5L));
+        stringer.endArray();
+        assertEquals("[false,5,5]", stringer.toString());
+    }
+
     public void testKeyValue() throws JSONException {
         JSONStringer stringer = new JSONStringer();
         stringer.object();
@@ -187,26 +197,27 @@
 
     public void testEscaping() throws JSONException {
         assertEscapedAllWays("a", "a");
-        assertEscapedAllWays("a\"", "a\\\"");
-        assertEscapedAllWays("\"", "\\\"");
+        assertEscapedAllWays("a\\\"", "a\"");
+        assertEscapedAllWays("\\\"", "\"");
         assertEscapedAllWays(":", ":");
         assertEscapedAllWays(",", ",");
-        assertEscapedAllWays("\n", "\\n");
-        assertEscapedAllWays("\t", "\\t");
+        assertEscapedAllWays("\\b", "\b");
+        assertEscapedAllWays("\\f", "\f");
+        assertEscapedAllWays("\\n", "\n");
+        assertEscapedAllWays("\\r", "\r");
+        assertEscapedAllWays("\\t", "\t");
         assertEscapedAllWays(" ", " ");
-        assertEscapedAllWays("\\", "\\\\");
+        assertEscapedAllWays("\\\\", "\\");
         assertEscapedAllWays("{", "{");
         assertEscapedAllWays("}", "}");
         assertEscapedAllWays("[", "[");
         assertEscapedAllWays("]", "]");
-
-        // how does it decide which characters to escape?
-        assertEscapedAllWays("\0", "\\u0000");
-        assertEscapedAllWays("\u0019", "\\u0019");
-        assertEscapedAllWays("\u0020", " ");
+        assertEscapedAllWays("\\u0000", "\0");
+        assertEscapedAllWays("\\u0019", "\u0019");
+        assertEscapedAllWays(" ", "\u0020");
     }
 
-    private void assertEscapedAllWays(String original, String escaped) throws JSONException {
+    private void assertEscapedAllWays(String escaped, String original) throws JSONException {
         assertEquals("{\"" + escaped + "\":false}",
                 new JSONStringer().object().key(original).value(false).endObject().toString());
         assertEquals("{\"a\":\"" + escaped + "\"}",
@@ -236,7 +247,7 @@
         assertEquals("{\"b\":{\"a\":false}}", stringer.toString());
     }
 
-    public void testArrayNestingMaxDepthIs20() throws JSONException {
+    public void testArrayNestingMaxDepthSupports20() throws JSONException {
         JSONStringer stringer = new JSONStringer();
         for (int i = 0; i < 20; i++) {
             stringer.array();
@@ -250,14 +261,9 @@
         for (int i = 0; i < 20; i++) {
             stringer.array();
         }
-        try {
-            stringer.array();
-            fail();
-        } catch (JSONException e) {
-        }
     }
 
-    public void testObjectNestingMaxDepthIs20() throws JSONException {
+    public void testObjectNestingMaxDepthSupports20() throws JSONException {
         JSONStringer stringer = new JSONStringer();
         for (int i = 0; i < 20; i++) {
             stringer.object();
@@ -276,14 +282,9 @@
             stringer.object();
             stringer.key("a");
         }
-        try {
-            stringer.object();
-            fail();
-        } catch (JSONException e) {
-        }
     }
 
-    public void testMixedMaxDepth() throws JSONException {
+    public void testMixedMaxDepthSupports20() throws JSONException {
         JSONStringer stringer = new JSONStringer();
         for (int i = 0; i < 20; i+=2) {
             stringer.array();
@@ -305,11 +306,6 @@
             stringer.object();
             stringer.key("a");
         }
-        try {
-            stringer.array();
-            fail();
-        } catch (JSONException e) {
-        }
     }
 
     public void testMaxDepthWithArrayValue() throws JSONException {
diff --git a/json/src/test/java/org/json/JSONTokenerTest.java b/json/src/test/java/org/json/JSONTokenerTest.java
index 1409a3b..70b7384 100644
--- a/json/src/test/java/org/json/JSONTokenerTest.java
+++ b/json/src/test/java/org/json/JSONTokenerTest.java
@@ -1,11 +1,11 @@
-/**
+/*
  * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -17,6 +17,7 @@
 package org.json;
 
 import junit.framework.TestCase;
+import junit.framework.AssertionFailedError;
 
 /**
  * This black box test was written without inspecting the non-free org.json sourcecode.
@@ -24,7 +25,7 @@
 public class JSONTokenerTest extends TestCase {
 
     public void testNulls() throws JSONException {
-        // bogus behaviour: JSONTokener accepts null, only to fail later on almost all APIs.
+        // JSONTokener accepts null, only to fail later on almost all APIs!
         new JSONTokener(null).back();
 
         try {
@@ -147,12 +148,6 @@
         }
         assertEquals('E', abcdeTokener.nextClean());
         assertEquals('\0', abcdeTokener.next());
-        try {
-            // bogus behaviour: returning an empty string should be valid
-            abcdeTokener.next(0);
-            fail();
-        } catch (JSONException e) {
-        }
         assertFalse(abcdeTokener.more());
         abcdeTokener.back();
         assertTrue(abcdeTokener.more());
@@ -174,7 +169,7 @@
         abcTokener.back();
         abcTokener.back();
         abcTokener.back();
-        abcTokener.back(); // bogus behaviour: you can back up before the beginning of a String
+        abcTokener.back(); // you can back up before the beginning of a String!
         assertEquals('A', abcTokener.next());
     }
 
@@ -209,26 +204,31 @@
             fail();
         } catch (JSONException e) {
         }
+    }
+
+    public void testNextNWithAllRemaining() throws JSONException {
+        JSONTokener tokener = new JSONTokener("ABCDEF");
+        tokener.next(3);
         try {
-            // bogus behaviour: there should be 3 characters left, but there must be an off-by-one
-            // error in the implementation.
-            assertEquals("DEF", abcdeTokener.next(3));
-            fail();
+            tokener.next(3);
         } catch (JSONException e) {
+            AssertionFailedError error = new AssertionFailedError("off-by-one error?");
+            error.initCause(e);
+            throw error;
         }
-        assertEquals("DE", abcdeTokener.next(2));
-        assertEquals('F', abcdeTokener.next());
+    }
+
+    public void testNext0() throws JSONException {
+        JSONTokener tokener = new JSONTokener("ABCDEF");
+        tokener.next(5);
+        tokener.next();
         try {
-            // bogus behaviour: returning an empty string should be valid
-            abcdeTokener.next(0);
-            fail();
+            tokener.next(0);
         } catch (JSONException e) {
+            Error error = new AssertionFailedError("Returning an empty string should be valid");
+            error.initCause(e);
+            throw error;
         }
-        abcdeTokener.back();
-        abcdeTokener.back();
-        abcdeTokener.back();
-        assertEquals("DE", abcdeTokener.next(2));
-        assertEquals('F', abcdeTokener.next());
     }
 
     public void testNextCleanComments() throws JSONException {
@@ -241,6 +241,24 @@
         assertEquals('\0', tokener.nextClean());
     }
 
+    public void testNextCleanNestedCStyleComments() throws JSONException {
+        JSONTokener tokener = new JSONTokener("A /* B /* C */ D */ E");
+        assertEquals('A', tokener.nextClean());
+        assertEquals('D', tokener.nextClean());
+        assertEquals('*', tokener.nextClean());
+        assertEquals('/', tokener.nextClean());
+        assertEquals('E', tokener.nextClean());
+    }
+
+    public void testNextCleanCommentsTrailingSingleSlash() throws JSONException {
+        JSONTokener tokener = new JSONTokener(" / S /");
+        assertEquals('/', tokener.nextClean());
+        assertEquals('S', tokener.nextClean());
+        assertEquals('/', tokener.nextClean());
+        assertEquals("nextClean doesn't consume a trailing slash",
+                '\0', tokener.nextClean());
+    }
+
     public void testNextCleanTrailingOpenComment() throws JSONException {
         try {
             new JSONTokener("  /* ").nextClean();
@@ -256,55 +274,54 @@
         assertEquals('B', new JSONTokener("  // \r  B ").nextClean());
     }
 
+    public void testNextCleanSkippedWhitespace() throws JSONException {
+        assertEquals("character tabulation", 'A', new JSONTokener("\tA").nextClean());
+        assertEquals("line feed",            'A', new JSONTokener("\nA").nextClean());
+        assertEquals("carriage return",      'A', new JSONTokener("\rA").nextClean());
+        assertEquals("space",                'A', new JSONTokener(" A").nextClean());
+    }
+
     /**
      * Tests which characters tokener treats as ignorable whitespace. See Kevin Bourrillion's
      * <a href="https://spreadsheets.google.com/pub?key=pd8dAQyHbdewRsnE5x5GzKQ">list
      * of whitespace characters</a>.
      */
-    public void testNextCleanWhitespace() throws JSONException {
-        // This behaviour contradicts the JSON spec. It claims the only space
-        // characters are space, tab, newline and carriage return. But it treats
-        // many characters like whitespace! These are the same whitespace
-        // characters used by String.trim(), with the exception of '\0'.
-        assertEquals("character tabulation",      'A', new JSONTokener("\u0009A").nextClean());
-        assertEquals("line feed",                 'A', new JSONTokener("\nA").nextClean());
-        assertEquals("line tabulation",           'A', new JSONTokener("\u000bA").nextClean());
-        assertEquals("form feed",                 'A', new JSONTokener("\u000cA").nextClean());
-        assertEquals("carriage return",           'A', new JSONTokener("\rA").nextClean());
-        assertEquals("information separator 4",   'A', new JSONTokener("\u001cA").nextClean());
-        assertEquals("information separator 3",   'A', new JSONTokener("\u001dA").nextClean());
-        assertEquals("information separator 2",   'A', new JSONTokener("\u001eA").nextClean());
-        assertEquals("information separator 1",   'A', new JSONTokener("\u001fA").nextClean());
-        assertEquals("space",                     'A', new JSONTokener("\u0020A").nextClean());
-        for (char c = '\u0002'; c < ' '; c++) {
-            assertEquals('A', new JSONTokener(new String(new char[] { ' ', c, 'A' })).nextClean());
-        }
+    public void testNextCleanRetainedWhitespace() throws JSONException {
+        assertNotClean("null",                      '\u0000');
+        assertNotClean("next line",                 '\u0085');
+        assertNotClean("non-breaking space",        '\u00a0');
+        assertNotClean("ogham space mark",          '\u1680');
+        assertNotClean("mongolian vowel separator", '\u180e');
+        assertNotClean("en quad",                   '\u2000');
+        assertNotClean("em quad",                   '\u2001');
+        assertNotClean("en space",                  '\u2002');
+        assertNotClean("em space",                  '\u2003');
+        assertNotClean("three-per-em space",        '\u2004');
+        assertNotClean("four-per-em space",         '\u2005');
+        assertNotClean("six-per-em space",          '\u2006');
+        assertNotClean("figure space",              '\u2007');
+        assertNotClean("punctuation space",         '\u2008');
+        assertNotClean("thin space",                '\u2009');
+        assertNotClean("hair space",                '\u200a');
+        assertNotClean("zero-width space",          '\u200b');
+        assertNotClean("left-to-right mark",        '\u200e');
+        assertNotClean("right-to-left mark",        '\u200f');
+        assertNotClean("line separator",            '\u2028');
+        assertNotClean("paragraph separator",       '\u2029');
+        assertNotClean("narrow non-breaking space", '\u202f');
+        assertNotClean("medium mathematical space", '\u205f');
+        assertNotClean("ideographic space",         '\u3000');
+        assertNotClean("line tabulation",           '\u000b');
+        assertNotClean("form feed",                 '\u000c');
+        assertNotClean("information separator 4",   '\u001c');
+        assertNotClean("information separator 3",   '\u001d');
+        assertNotClean("information separator 2",   '\u001e');
+        assertNotClean("information separator 1",   '\u001f');
+    }
 
-        // These characters are neither whitespace in the JSON spec nor the implementation
-        assertEquals("null",                      '\u0000', new JSONTokener("\u0000A").nextClean());
-        assertEquals("next line",                 '\u0085', new JSONTokener("\u0085A").nextClean());
-        assertEquals("non-breaking space",        '\u00a0', new JSONTokener("\u00a0A").nextClean());
-        assertEquals("ogham space mark",          '\u1680', new JSONTokener("\u1680A").nextClean());
-        assertEquals("mongolian vowel separator", '\u180e', new JSONTokener("\u180eA").nextClean());
-        assertEquals("en quad",                   '\u2000', new JSONTokener("\u2000A").nextClean());
-        assertEquals("em quad",                   '\u2001', new JSONTokener("\u2001A").nextClean());
-        assertEquals("en space",                  '\u2002', new JSONTokener("\u2002A").nextClean());
-        assertEquals("em space",                  '\u2003', new JSONTokener("\u2003A").nextClean());
-        assertEquals("three-per-em space",        '\u2004', new JSONTokener("\u2004A").nextClean());
-        assertEquals("four-per-em space",         '\u2005', new JSONTokener("\u2005A").nextClean());
-        assertEquals("six-per-em space",          '\u2006', new JSONTokener("\u2006A").nextClean());
-        assertEquals("figure space",              '\u2007', new JSONTokener("\u2007A").nextClean());
-        assertEquals("punctuation space",         '\u2008', new JSONTokener("\u2008A").nextClean());
-        assertEquals("thin space",                '\u2009', new JSONTokener("\u2009A").nextClean());
-        assertEquals("hair space",                '\u200a', new JSONTokener("\u200aA").nextClean());
-        assertEquals("zero-width space",          '\u200b', new JSONTokener("\u200bA").nextClean());
-        assertEquals("left-to-right mark",        '\u200e', new JSONTokener("\u200eA").nextClean());
-        assertEquals("right-to-left mark",        '\u200f', new JSONTokener("\u200fA").nextClean());
-        assertEquals("line separator",            '\u2028', new JSONTokener("\u2028A").nextClean());
-        assertEquals("paragraph separator",       '\u2029', new JSONTokener("\u2029A").nextClean());
-        assertEquals("narrow non-breaking space", '\u202f', new JSONTokener("\u202fA").nextClean());
-        assertEquals("medium mathematical space", '\u205f', new JSONTokener("\u205fA").nextClean());
-        assertEquals("ideographic space",         '\u3000', new JSONTokener("\u3000A").nextClean());
+    private void assertNotClean(String name, char c) throws JSONException {
+        assertEquals("The character " + name + " is not whitespace according to the JSON spec.",
+                c, new JSONTokener(new String(new char[] { c, 'A' })).nextClean());
     }
 
     public void testNextString() throws JSONException {
@@ -374,6 +391,7 @@
         try {
             new JSONTokener("abc\\u002\"").nextString('"');
             fail();
+        } catch (NumberFormatException e) {
         } catch (JSONException e) {
         }
         try {
@@ -433,15 +451,6 @@
         assertEquals("ABC", tokener.nextTo("\n"));
         assertEquals("", tokener.nextTo("\n"));
 
-        // Bogus behaviour: the tokener stops after \0 always
-        tokener = new JSONTokener(" \0\t \fABC \n DEF");
-        assertEquals("", tokener.nextTo("D"));
-        assertEquals('\t', tokener.next());
-        assertEquals("ABC", tokener.nextTo("D"));
-        tokener = new JSONTokener("ABC\0DEF");
-        assertEquals("ABC", tokener.nextTo("\0"));
-        assertEquals("DEF", tokener.nextTo("\0"));
-
         tokener = new JSONTokener("");
         try {
             tokener.nextTo(null);
@@ -450,6 +459,32 @@
         }
     }
 
+    public void testNextToTrimming() {
+        assertEquals("ABC", new JSONTokener("\t ABC \tDEF").nextTo("DE"));
+        assertEquals("ABC", new JSONTokener("\t ABC \tDEF").nextTo('D'));
+    }
+
+    public void testNextToTrailing() {
+        assertEquals("ABC DEF", new JSONTokener("\t ABC DEF \t").nextTo("G"));
+        assertEquals("ABC DEF", new JSONTokener("\t ABC DEF \t").nextTo('G'));
+    }
+
+    public void testNextToDoesntStopOnNull() {
+        String message = "nextTo() shouldn't stop after \\0 characters";
+        JSONTokener tokener = new JSONTokener(" \0\t \fABC \n DEF");
+        assertEquals(message, "ABC", tokener.nextTo("D"));
+        assertEquals(message, '\n', tokener.next());
+        assertEquals(message, "", tokener.nextTo("D"));
+    }
+
+    public void testNextToConsumesNull() {
+        String message = "nextTo shouldn't consume \\0.";
+        JSONTokener tokener = new JSONTokener("ABC\0DEF");
+        assertEquals(message, "ABC", tokener.nextTo("\0"));
+        assertEquals(message, '\0', tokener.next());
+        assertEquals(message, "DEF", tokener.nextTo("\0"));
+    }
+
     public void testSkipPast() {
         JSONTokener tokener = new JSONTokener("ABCDEF");
         tokener.skipPast("ABC");
@@ -509,11 +544,6 @@
         tokener.skipTo('A');
         assertEquals('F', tokener.next());
 
-        tokener = new JSONTokener("ABC\0DEF");
-        tokener.skipTo('F');
-        // bogus behaviour: skipTo gives up when it sees '\0'
-        assertEquals('A', tokener.next());
-
         tokener = new JSONTokener("ABC\nDEF");
         tokener.skipTo('F');
         assertEquals('F', tokener.next());
@@ -527,6 +557,12 @@
         assertEquals('D', tokener.next());
     }
 
+    public void testSkipToStopsOnNull() {
+        JSONTokener tokener = new JSONTokener("ABC\0DEF");
+        tokener.skipTo('F');
+        assertEquals("skipTo shouldn't stop when it sees '\\0'", 'F', tokener.next());
+    }
+
     public void testDehexchar() {
         assertEquals( 0, JSONTokener.dehexchar('0'));
         assertEquals( 1, JSONTokener.dehexchar('1'));
@@ -558,8 +594,4 @@
             assertEquals("dehexchar " + c, -1, JSONTokener.dehexchar((char) c));
         }
     }
-
-    public void testNextValue() {
-        fail("TODO");
-    }
 }
diff --git a/json/src/test/java/org/json/ParsingTest.java b/json/src/test/java/org/json/ParsingTest.java
new file mode 100644
index 0000000..16b9116
--- /dev/null
+++ b/json/src/test/java/org/json/ParsingTest.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.json;
+
+import junit.framework.TestCase;
+import junit.framework.AssertionFailedError;
+
+import java.util.*;
+
+public class ParsingTest extends TestCase {
+
+    public void testParsingNoObjects() {
+        try {
+            new JSONTokener("").nextValue();
+            fail();
+        } catch (JSONException e) {
+        }
+    }
+
+    public void testParsingLiterals() throws JSONException {
+        assertParsed(Boolean.TRUE, "true");
+        assertParsed(Boolean.FALSE, "false");
+        assertParsed(JSONObject.NULL, "null");
+        assertParsed(JSONObject.NULL, "NULL");
+        assertParsed(Boolean.FALSE, "False");
+        assertParsed(Boolean.TRUE, "truE");
+    }
+
+    public void testParsingQuotedStrings() throws JSONException {
+        assertParsed("abc", "\"abc\"");
+        assertParsed("123", "\"123\"");
+        assertParsed("foo\nbar", "\"foo\\nbar\"");
+        assertParsed("foo bar", "\"foo\\u0020bar\"");
+        assertParsed("\"{}[]/\\:,=;#", "\"\\\"{}[]/\\\\:,=;#\"");
+    }
+
+    public void testParsingSingleQuotedStrings() throws JSONException {
+        assertParsed("abc", "'abc'");
+        assertParsed("123", "'123'");
+        assertParsed("foo\nbar", "'foo\\nbar'");
+        assertParsed("foo bar", "'foo\\u0020bar'");
+        assertParsed("\"{}[]/\\:,=;#", "'\\\"{}[]/\\\\:,=;#'");
+    }
+
+    public void testParsingUnquotedStrings() throws JSONException {
+        assertParsed("abc", "abc");
+        assertParsed("123abc", "123abc");
+        assertParsed("123e0x", "123e0x");
+        assertParsed("123e", "123e");
+        assertParsed("123ee21", "123ee21");
+        assertParsed("0xFFFFFFFFFFFFFFFFF", "0xFFFFFFFFFFFFFFFFF");
+    }
+
+    /**
+     * Unfortunately the original implementation attempts to figure out what
+     * Java number type best suits an input value.
+     */
+    public void testParsingNumbersThatAreBestRepresentedAsLongs() throws JSONException {
+        assertParsed(9223372036854775807L, "9223372036854775807");
+        assertParsed(9223372036854775806L, "9223372036854775806");
+        assertParsed(-9223372036854775808L, "-9223372036854775808");
+        assertParsed(-9223372036854775807L, "-9223372036854775807");
+    }
+
+    public void testParsingNumbersThatAreBestRepresentedAsIntegers() throws JSONException {
+        assertParsed(0, "0");
+        assertParsed(5, "5");
+        assertParsed(-2147483648, "-2147483648");
+        assertParsed(2147483647, "2147483647");
+    }
+
+    public void testParsingNegativeZero() throws JSONException {
+        assertParsed(0, "-0");
+    }
+
+    public void testParsingIntegersWithAdditionalPrecisionYieldDoubles() throws JSONException {
+        assertParsed(1d, "1.00");
+        assertParsed(1d, "1.0");
+        assertParsed(0d, "0.0");
+        assertParsed(-0d, "-0.0");
+    }
+
+    public void testParsingNumbersThatAreBestRepresentedAsDoubles() throws JSONException {
+        assertParsed(9.223372036854776E18, "9223372036854775808");
+        assertParsed(-9.223372036854776E18, "-9223372036854775809");
+        assertParsed(1.7976931348623157E308, "1.7976931348623157e308");
+        assertParsed(2.2250738585072014E-308, "2.2250738585072014E-308");
+        assertParsed(4.9E-324, "4.9E-324");
+        assertParsed(4.9E-324, "4.9e-324");
+    }
+
+    public void testParsingOctalNumbers() throws JSONException {
+        assertParsed(5, "05");
+        assertParsed(8, "010");
+        assertParsed(1046, "02026");
+    }
+
+    public void testParsingHexNumbers() throws JSONException {
+        assertParsed(5, "0x5");
+        assertParsed(16, "0x10");
+        assertParsed(8230, "0x2026");
+        assertParsed(180150010, "0xABCDEFA");
+        assertParsed(2077093803, "0x7BCDEFAB");
+    }
+
+    public void testParsingLargeHexValues() throws JSONException {
+        assertParsed(Integer.MAX_VALUE, "0x7FFFFFFF");
+        String message = "Hex values are parsed as Strings if their signed " +
+                "value is greater than Integer.MAX_VALUE.";
+        assertParsed(message, 0x80000000L, "0x80000000");
+    }
+
+    public void test64BitHexValues() throws JSONException {
+        assertParsed("Large hex longs shouldn't be yield ints or strings", 
+                -1L, "0xFFFFFFFFFFFFFFFF");
+    }
+
+    public void testParsingWithCommentsAndWhitespace() throws JSONException {
+        assertParsed("baz", "  // foo bar \n baz");
+        assertParsed(5, "  /* foo bar \n baz */ 5");
+        assertParsed(5, "  /* foo bar \n baz */ 5 // quux");
+        assertParsed(5, "  5   ");
+        assertParsed(5, "  5  \r\n\t ");
+        assertParsed(5, "\r\n\t   5 ");
+    }
+
+    public void testParsingArrays() throws JSONException {
+        assertParsed(array(), "[]");
+        assertParsed(array(5, 6, true), "[5,6,true]");
+        assertParsed(array(5, 6, array()), "[5,6,[]]");
+        assertParsed(array(5, 6, 7), "[5;6;7]");
+        assertParsed(array(5, 6, 7), "[5  , 6 \t; \r\n 7\n]");
+        assertParsed(array(5, 6, 7, null), "[5,6,7,]");
+        assertParsed(array(null, null), "[,]");
+        assertParsed(array(5, null, null, null, 5), "[5,,,,5]");
+        assertParsed(array(null, 5), "[,5]");
+        assertParsed(array(null, null, null), "[,,]");
+        assertParsed(array(null, null, null, 5), "[,,,5]");
+    }
+
+    public void testParsingObjects() throws JSONException {
+        assertParsed(object("foo", 5), "{\"foo\": 5}");
+        assertParsed(object("foo", 5), "{foo: 5}");
+        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5, \"bar\": \"baz\"}");
+        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\": 5; \"bar\": \"baz\"}");
+        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"= 5; \"bar\"= \"baz\"}");
+        assertParsed(object("foo", 5, "bar", "baz"), "{\"foo\"=> 5; \"bar\"=> \"baz\"}");
+        assertParsed(object("foo", object(), "bar", array()), "{\"foo\"=> {}; \"bar\"=> []}");
+        assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\": {\"foo\": [5, 6]}}");
+        assertParsed(object("foo", object("foo", array(5, 6))), "{\"foo\":\n\t{\t \"foo\":[5,\r6]}}");
+    }
+
+    public void testSyntaxProblemUnterminatedObject() {
+        assertParseFail("{");
+        assertParseFail("{\"foo\"");
+        assertParseFail("{\"foo\":");
+        assertParseFail("{\"foo\":bar");
+        assertParseFail("{\"foo\":bar,");
+        assertParseFail("{\"foo\":bar,\"baz\"");
+        assertParseFail("{\"foo\":bar,\"baz\":");
+        assertParseFail("{\"foo\":bar,\"baz\":true");
+        assertParseFail("{\"foo\":bar,\"baz\":true,");
+    }
+
+    public void testSyntaxProblemEmptyString() {
+        assertParseFail("");
+    }
+
+    public void testSyntaxProblemUnterminatedArray() {
+        assertParseFail("[");
+        assertParseFail("[,");
+        assertParseFail("[,,");
+        assertParseFail("[true");
+        assertParseFail("[true,");
+        assertParseFail("[true,,");
+    }
+
+    public void testSyntaxProblemMalformedObject() {
+        assertParseFail("{:}");
+        assertParseFail("{\"key\":}");
+        assertParseFail("{:true}");
+        assertParseFail("{\"key\":true:}");
+        assertParseFail("{null:true}");
+        assertParseFail("{true:true}");
+        assertParseFail("{0xFF:true}");
+    }
+
+    private void assertParseFail(String malformedJson) {
+        try {
+            new JSONTokener(malformedJson).nextValue();
+            fail("Successfully parsed: \"" + malformedJson + "\"");
+        } catch (JSONException e) {
+        } catch (StackOverflowError e) {
+            fail("Stack overflowed on input: \"" + malformedJson + "\"");
+        }
+    }
+
+    private JSONArray array(Object... elements) {
+        return new JSONArray(Arrays.asList(elements));
+    }
+
+    private JSONObject object(Object... keyValuePairs) throws JSONException {
+        JSONObject result = new JSONObject();
+        for (int i = 0; i < keyValuePairs.length; i+=2) {
+            result.put((String) keyValuePairs[i], keyValuePairs[i+1]);
+        }
+        return result;
+    }
+
+    private void assertParsed(String message, Object expected, String json) throws JSONException {
+        Object actual = new JSONTokener(json).nextValue();
+        actual = canonicalize(actual);
+        expected = canonicalize(expected);
+        assertEquals("For input \"" + json + "\" " + message, expected, actual);
+    }
+
+    private void assertParsed(Object expected, String json) throws JSONException {
+        assertParsed("", expected, json);
+    }
+
+    /**
+     * Since they don't implement equals or hashCode properly, this recursively
+     * replaces JSONObjects with an equivalent HashMap, and JSONArrays with the
+     * equivalent ArrayList.
+     */
+    private Object canonicalize(Object input) throws JSONException {
+        if (input instanceof JSONArray) {
+            JSONArray array = (JSONArray) input;
+            List<Object> result = new ArrayList<Object>();
+            for (int i = 0; i < array.length(); i++) {
+                result.add(canonicalize(array.opt(i)));
+            }
+            return result;
+        } else if (input instanceof JSONObject) {
+            JSONObject object = (JSONObject) input;
+            Map<String, Object> result = new HashMap<String, Object>();
+            for (Iterator<?> i = object.keys(); i.hasNext(); ) {
+                String key = (String) i.next();
+                result.put(key, canonicalize(object.get(key)));
+            }
+            return result;
+        } else {
+            return input;
+        }
+    }
+}
diff --git a/json/src/test/java/org/json/SelfUseTest.java b/json/src/test/java/org/json/SelfUseTest.java
index e3d428b..15a0824 100644
--- a/json/src/test/java/org/json/SelfUseTest.java
+++ b/json/src/test/java/org/json/SelfUseTest.java
@@ -1,11 +1,11 @@
-/**
+/*
  * Copyright (C) 2010 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
@@ -19,9 +19,9 @@
 import junit.framework.TestCase;
 
 /**
- * These tests checks self use; ie. when methods delegate to non-final methods.
- * For the most part we doesn't attempt to cover self-use, except in those cases
- * where our clean room implementation does it.
+ * These tests checks self use calls. For the most part we doesn't attempt to
+ * cover self-use, except in those cases where our clean room implementation
+ * does it.
  *
  * <p>This black box test was written without inspecting the non-free org.json
  * sourcecode.
@@ -36,6 +36,8 @@
     private int arrayGetCalls = 0;
     private int arrayOptCalls = 0;
     private int arrayOptTypeCalls = 0;
+    private int tokenerNextCalls = 0;
+    private int tokenerNextValueCalls = 0;
 
     private final JSONObject object = new JSONObject() {
         @Override public JSONObject put(String name, Object value) throws JSONException {
@@ -107,6 +109,18 @@
         }
     };
 
+    private final JSONTokener tokener = new JSONTokener("{\"foo\": [true]}") {
+        @Override public char next() {
+            tokenerNextCalls++;
+            return super.next();
+        }
+        @Override public Object nextValue() throws JSONException {
+            tokenerNextValueCalls++;
+            return super.nextValue();
+        }
+    };
+
+
     public void testObjectPut() throws JSONException {
         object.putOpt("foo", "bar");
         assertEquals(1, objectPutCalls);
@@ -201,4 +215,15 @@
         assertEquals(0, arrayOptTypeCalls);
     }
 
+    public void testNextExpecting() throws JSONException {
+        tokener.next('{');
+        assertEquals(1, tokenerNextCalls);
+        tokener.next('\"');
+        assertEquals(2, tokenerNextCalls);
+    }
+
+    public void testNextValue() throws JSONException {
+        tokener.nextValue();
+        assertEquals(4, tokenerNextValueCalls);
+    }
 }
