geode-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dschnei...@apache.org
Subject [02/51] [abbrv] geode git commit: GEODE-2142: Adding JSON library from the https://github.com/tdunning/open-json project
Date Tue, 07 Mar 2017 19:21:25 GMT
http://git-wip-us.apache.org/repos/asf/geode/blob/b34e47ff/geode-json/src/test/java/org/json/JSONObjectTest.java
----------------------------------------------------------------------
diff --git a/geode-json/src/test/java/org/json/JSONObjectTest.java b/geode-json/src/test/java/org/json/JSONObjectTest.java
new file mode 100755
index 0000000..393a2d0
--- /dev/null
+++ b/geode-json/src/test/java/org/json/JSONObjectTest.java
@@ -0,0 +1,1198 @@
+/*
+ * 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 org.junit.Test;
+
+import java.beans.IntrospectionException;
+import java.lang.reflect.InvocationTargetException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * This black box test was written without inspecting the non-free org.json sourcecode.
+ */
+public class JSONObjectTest {
+    @Test
+    public void testKeyset() throws Exception {
+        JSONObject x = new JSONObject("{'a':1, 'b':2, 'c':3}");
+        Set<String> k = new TreeSet<String>();
+        for (String kx : Arrays.asList("a", "b", "c")) {
+            k.add(kx);
+        }
+        assertEquals(x.keySet(), k);
+        x = new JSONObject("{}");
+        assertEquals(x.keySet().size(), 0);
+    }
+
+    @Test
+    public void testEmptyObject() throws JSONException {
+        JSONObject object = new JSONObject();
+        assertEquals(0, object.length());
+
+        // bogus (but documented) behaviour: returns null rather than the empty object!
+        assertNull(object.names());
+
+        // returns null rather than an empty array!
+        assertNull(object.toJSONArray(new JSONArray()));
+        assertEquals("{}", object.toString());
+        assertEquals("{}", object.toString(5));
+        try {
+            object.get("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getBoolean("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getDouble("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getInt("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getJSONArray("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getJSONObject("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getLong("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getString("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertFalse(object.has("foo"));
+        assertTrue(object.isNull("foo")); // isNull also means "is not present"
+        assertNull(object.opt("foo"));
+        assertEquals(false, object.optBoolean("foo"));
+        assertEquals(true, object.optBoolean("foo", true));
+        assertEquals(Double.NaN, object.optDouble("foo"), 0);
+        assertEquals(5.0, object.optDouble("foo", 5.0), 0);
+        assertEquals(0, object.optInt("foo"));
+        assertEquals(5, object.optInt("foo", 5));
+        assertEquals(null, object.optJSONArray("foo"));
+        assertEquals(null, object.optJSONObject("foo"));
+        assertEquals(0, object.optLong("foo"));
+        assertEquals(Long.MAX_VALUE - 1, object.optLong("foo", Long.MAX_VALUE - 1));
+        assertEquals("", object.optString("foo")); // empty string is default!
+        assertEquals("bar", object.optString("foo", "bar"));
+        assertNull(object.remove("foo"));
+    }
+
+    @Test
+    public void testEqualsAndHashCode() throws JSONException {
+        JSONObject a = new JSONObject();
+        JSONObject b = new JSONObject();
+
+        // JSON object doesn't override either equals or hashCode (!)
+        assertFalse(a.equals(b));
+        assertEquals(a.hashCode(), System.identityHashCode(a));
+    }
+
+    @Test
+    public void testGet() throws JSONException {
+        JSONObject object = new JSONObject();
+        Object value = new Object();
+        object.put("foo", value);
+        object.put("bar", new Object());
+        object.put("baz", new Object());
+        assertSame(value, object.get("foo"));
+        try {
+            object.get("FOO");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put(null, value);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.get(null);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testPut() throws JSONException {
+        JSONObject object = new JSONObject();
+        assertSame(object, object.put("foo", true));
+        object.put("foo", false);
+        assertEquals(false, object.get("foo"));
+
+        object.put("foo", 5.0d);
+        assertEquals(5.0d, object.get("foo"));
+        object.put("foo", 0);
+        assertEquals(0, object.get("foo"));
+        object.put("bar", Long.MAX_VALUE - 1);
+        assertEquals(Long.MAX_VALUE - 1, object.get("bar"));
+        object.put("baz", "x");
+        assertEquals("x", object.get("baz"));
+        object.put("bar", JSONObject.NULL);
+        assertSame(JSONObject.NULL, object.get("bar"));
+    }
+
+    @Test
+    public void testPutNullRemoves() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "bar");
+        object.put("foo", null);
+        assertEquals(0, object.length());
+        assertFalse(object.has("foo"));
+        try {
+            object.get("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testPutOpt() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "bar");
+        object.putOpt("foo", null);
+        assertEquals("bar", object.get("foo"));
+        object.putOpt(null, null);
+        assertEquals(1, object.length());
+        object.putOpt(null, "bar");
+        assertEquals(1, object.length());
+    }
+
+    @Test
+    public void testPutOptUnsupportedNumbers() throws JSONException {
+        JSONObject object = new JSONObject();
+        try {
+            object.putOpt("foo", Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.putOpt("foo", Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.putOpt("foo", Double.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testRemove() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "bar");
+        assertEquals(null, object.remove(null));
+        assertEquals(null, object.remove(""));
+        assertEquals(null, object.remove("bar"));
+        assertEquals("bar", object.remove("foo"));
+        assertEquals(null, object.remove("foo"));
+    }
+
+    @Test
+    public void testBooleans() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", true);
+        object.put("bar", false);
+        object.put("baz", "true");
+        object.put("quux", "false");
+        assertEquals(4, object.length());
+        assertEquals(true, object.getBoolean("foo"));
+        assertEquals(false, object.getBoolean("bar"));
+        assertEquals(true, object.getBoolean("baz"));
+        assertEquals(false, object.getBoolean("quux"));
+        assertFalse(object.isNull("foo"));
+        assertFalse(object.isNull("quux"));
+        assertTrue(object.has("foo"));
+        assertTrue(object.has("quux"));
+        assertFalse(object.has("missing"));
+        assertEquals(true, object.optBoolean("foo"));
+        assertEquals(false, object.optBoolean("bar"));
+        assertEquals(true, object.optBoolean("baz"));
+        assertEquals(false, object.optBoolean("quux"));
+        assertEquals(false, object.optBoolean("missing"));
+        assertEquals(true, object.optBoolean("foo", true));
+        assertEquals(false, object.optBoolean("bar", true));
+        assertEquals(true, object.optBoolean("baz", true));
+        assertEquals(false, object.optBoolean("quux", true));
+        assertEquals(true, object.optBoolean("missing", true));
+
+        object.put("foo", "truE");
+        object.put("bar", "FALSE");
+        assertEquals(true, object.getBoolean("foo"));
+        assertEquals(false, object.getBoolean("bar"));
+        assertEquals(true, object.optBoolean("foo"));
+        assertEquals(false, object.optBoolean("bar"));
+        assertEquals(true, object.optBoolean("foo", false));
+        assertEquals(false, object.optBoolean("bar", false));
+    }
+
+    // http://code.google.com/p/android/issues/detail?id=16411
+    @Test
+    public void testCoerceStringToBoolean() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "maybe");
+        try {
+            object.getBoolean("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals(false, object.optBoolean("foo"));
+        assertEquals(true, object.optBoolean("foo", true));
+    }
+
+    @Test
+    public void testNumbers() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", Double.MIN_VALUE);
+        object.put("bar", 9223372036854775806L);
+        object.put("baz", Double.MAX_VALUE);
+        object.put("quux", -0d);
+        assertEquals(4, object.length());
+
+        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"));
+
+        // 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"));
+        assertEquals(Double.MAX_VALUE, object.get("baz"));
+        assertEquals(-0d, object.get("quux"));
+        assertEquals(Double.MIN_VALUE, object.getDouble("foo"), 0);
+        assertEquals(9.223372036854776E18, object.getDouble("bar"), 0);
+        assertEquals(Double.MAX_VALUE, object.getDouble("baz"), 0);
+        assertEquals(-0d, object.getDouble("quux"), 0);
+        assertEquals(0, object.getLong("foo"));
+        assertEquals(9223372036854775806L, object.getLong("bar"));
+        assertEquals(Long.MAX_VALUE, object.getLong("baz"));
+        assertEquals(0, object.getLong("quux"));
+        assertEquals(0, object.getInt("foo"));
+        assertEquals(-2, object.getInt("bar"));
+        assertEquals(Integer.MAX_VALUE, object.getInt("baz"));
+        assertEquals(0, object.getInt("quux"));
+        assertEquals(Double.MIN_VALUE, object.opt("foo"));
+        assertEquals(9223372036854775806L, object.optLong("bar"));
+        assertEquals(Double.MAX_VALUE, object.optDouble("baz"), 0);
+        assertEquals(0, object.optInt("quux"));
+        assertEquals(Double.MIN_VALUE, object.opt("foo"));
+        assertEquals(9223372036854775806L, object.optLong("bar"));
+        assertEquals(Double.MAX_VALUE, object.optDouble("baz"), 0);
+        assertEquals(0, object.optInt("quux"));
+        assertEquals(Double.MIN_VALUE, object.optDouble("foo", 5.0d), 0);
+        assertEquals(9223372036854775806L, object.optLong("bar", 1L));
+        assertEquals(Long.MAX_VALUE, object.optLong("baz", 1L));
+        assertEquals(0, object.optInt("quux", -1));
+        assertEquals("4.9E-324", object.getString("foo"));
+        assertEquals("9223372036854775806", object.getString("bar"));
+        assertEquals("1.7976931348623157E308", object.getString("baz"));
+        assertEquals("-0.0", object.getString("quux"));
+    }
+
+    @Test
+    public void testFloats() throws JSONException {
+        JSONObject object = new JSONObject();
+        try {
+            object.put("foo", (Float) Float.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", (Float) Float.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", (Float) Float.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testOtherNumbers() throws JSONException {
+        Number nan = new Number() {
+            public int intValue() {
+                throw new UnsupportedOperationException();
+            }
+
+            public long longValue() {
+                throw new UnsupportedOperationException();
+            }
+
+            public float floatValue() {
+                throw new UnsupportedOperationException();
+            }
+
+            public double doubleValue() {
+                return Double.NaN;
+            }
+
+            @Override
+            public String toString() {
+                return "x";
+            }
+        };
+
+        JSONObject object = new JSONObject();
+        try {
+            object.put("foo", nan);
+            fail("Object.put() accepted a NaN (via a custom Number class)");
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testForeignObjects() throws JSONException {
+        Object foreign = new Object() {
+            @Override
+            public String toString() {
+                return "x";
+            }
+        };
+
+        // foreign object types are accepted and treated as Strings!
+        JSONObject object = new JSONObject();
+        object.put("foo", foreign);
+        assertEquals("{\"foo\":\"x\"}", object.toString());
+    }
+
+    @Test
+    public void testNullKeys() {
+        try {
+            new JSONObject().put(null, false);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONObject().put(null, 0.0d);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONObject().put(null, 5);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONObject().put(null, 5L);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONObject().put(null, "foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testStrings() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "true");
+        object.put("bar", "5.5");
+        object.put("baz", "9223372036854775806");
+        object.put("quux", "null");
+        object.put("height", "5\"8' tall");
+
+        assertTrue(object.toString().contains("\"foo\":\"true\""));
+        assertTrue(object.toString().contains("\"bar\":\"5.5\""));
+        assertTrue(object.toString().contains("\"baz\":\"9223372036854775806\""));
+        assertTrue(object.toString().contains("\"quux\":\"null\""));
+        assertTrue(object.toString().contains("\"height\":\"5\\\"8' tall\""));
+
+        assertEquals("true", object.get("foo"));
+        assertEquals("null", object.getString("quux"));
+        assertEquals("5\"8' tall", object.getString("height"));
+        assertEquals("true", object.opt("foo"));
+        assertEquals("5.5", object.optString("bar"));
+        assertEquals("true", object.optString("foo", "x"));
+        assertFalse(object.isNull("foo"));
+
+        assertEquals(true, object.getBoolean("foo"));
+        assertEquals(true, object.optBoolean("foo"));
+        assertEquals(true, object.optBoolean("foo", false));
+        assertEquals(0, object.optInt("foo"));
+        assertEquals(-2, object.optInt("foo", -2));
+
+        assertEquals(5.5d, object.getDouble("bar"), 0);
+        assertEquals(5L, object.getLong("bar"));
+        assertEquals(5, object.getInt("bar"));
+        assertEquals(5, object.optInt("bar", 3));
+
+        // The last digit of the string is a 6 but getLong returns a 7. It's probably parsing as a
+        // double and then converting that to a long. This is consistent with JavaScript.
+        assertEquals(9223372036854775807L, object.getLong("baz"));
+        assertEquals(9.223372036854776E18, object.getDouble("baz"), 0);
+        assertEquals(Integer.MAX_VALUE, object.getInt("baz"));
+
+        assertFalse(object.isNull("quux"));
+        try {
+            object.getDouble("quux");
+            fail();
+        } catch (JSONException e) {
+            // expected
+        }
+        assertEquals(Double.NaN, object.optDouble("quux"), 0);
+        assertEquals(-1.0d, object.optDouble("quux", -1.0d), 0);
+
+        object.put("foo", "TRUE");
+        assertEquals(true, object.getBoolean("foo"));
+    }
+
+    @Test
+    public void testJSONObjects() throws JSONException {
+        JSONObject object = new JSONObject();
+
+        JSONArray a = new JSONArray();
+        JSONObject b = new JSONObject();
+        object.put("foo", a);
+        object.put("bar", b);
+
+        assertSame(a, object.getJSONArray("foo"));
+        assertSame(b, object.getJSONObject("bar"));
+        try {
+            object.getJSONObject("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.getJSONArray("bar");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals(a, object.optJSONArray("foo"));
+        assertEquals(b, object.optJSONObject("bar"));
+        assertEquals(null, object.optJSONArray("bar"));
+        assertEquals(null, object.optJSONObject("foo"));
+    }
+
+    @Test
+    public void testNullCoercionToString() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", JSONObject.NULL);
+        assertEquals("null", object.getString("foo"));
+    }
+
+    @Test
+    public void testArrayCoercion() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "[true]");
+        try {
+            object.getJSONArray("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testObjectCoercion() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "{}");
+        try {
+            object.getJSONObject("foo");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testAccumulateValueChecking() throws JSONException {
+        JSONObject object = new JSONObject();
+        try {
+            object.accumulate("foo", Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        object.accumulate("foo", 1);
+        try {
+            object.accumulate("foo", Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        object.accumulate("foo", 2);
+        try {
+            object.accumulate("foo", Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testToJSONArray() throws JSONException {
+        JSONObject object = new JSONObject();
+        Object value = new Object();
+        object.put("foo", true);
+        object.put("bar", 5.0d);
+        object.put("baz", -0.0d);
+        object.put("quux", value);
+
+        JSONArray names = new JSONArray();
+        names.put("baz");
+        names.put("quux");
+        names.put("foo");
+
+        JSONArray array = object.toJSONArray(names);
+        assertEquals(-0.0d, array.get(0));
+        assertEquals(value, array.get(1));
+        assertEquals(true, array.get(2));
+
+        object.put("foo", false);
+        assertEquals(true, array.get(2));
+    }
+
+    @Test
+    public void testToJSONArrayMissingNames() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", true);
+        object.put("bar", 5.0d);
+        object.put("baz", JSONObject.NULL);
+
+        JSONArray names = new JSONArray();
+        names.put("bar");
+        names.put("foo");
+        names.put("quux");
+        names.put("baz");
+
+        JSONArray array = object.toJSONArray(names);
+        assertEquals(4, array.length());
+
+        assertEquals(5.0d, array.get(0));
+        assertEquals(true, array.get(1));
+        try {
+            array.get(2);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals(JSONObject.NULL, array.get(3));
+    }
+
+    @Test
+    public void testToJSONArrayNull() throws JSONException {
+        JSONObject object = new JSONObject();
+        assertEquals(null, object.toJSONArray(null));
+        object.put("foo", 5);
+        try {
+            object.toJSONArray(null);
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testToJSONArrayEndsUpEmpty() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        JSONArray array = new JSONArray();
+        array.put("bar");
+        assertEquals(1, object.toJSONArray(array).length());
+    }
+
+    @Test
+    public void testToJSONArrayNonString() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        object.put("null", 10);
+        object.put("false", 15);
+
+        JSONArray names = new JSONArray();
+        names.put(JSONObject.NULL);
+        names.put(false);
+        names.put("foo");
+
+        // 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));
+        assertEquals(15, array.get(1));
+        assertEquals(5, array.get(2));
+    }
+
+    @Test
+    public void testPutUnsupportedNumbers() throws JSONException {
+        JSONObject object = new JSONObject();
+        try {
+            object.put("foo", Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", Double.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testPutUnsupportedNumbersAsObjects() throws JSONException {
+        JSONObject object = new JSONObject();
+        try {
+            object.put("foo", (Double) Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", (Double) Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            object.put("foo", (Double) Double.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    /**
+     * Although JSONObject is usually defensive about which numbers it accepts,
+     * it doesn't check inputs in its constructor.
+     */
+    @Test
+    public void testCreateWithUnsupportedNumbers() throws JSONException {
+        Map<String, Object> contents = new HashMap<String, Object>();
+        contents.put("foo", Double.NaN);
+        contents.put("bar", Double.NEGATIVE_INFINITY);
+        contents.put("baz", Double.POSITIVE_INFINITY);
+
+        JSONObject object = new JSONObject(contents);
+        assertEquals(Double.NaN, object.get("foo"));
+        assertEquals(Double.NEGATIVE_INFINITY, object.get("bar"));
+        assertEquals(Double.POSITIVE_INFINITY, object.get("baz"));
+    }
+
+    @Test
+    public void testToStringWithUnsupportedNumbers() {
+        // when the object contains an unsupported number, toString returns null!
+        JSONObject object = new JSONObject(Collections.singletonMap("foo", Double.NaN));
+        assertEquals(null, object.toString());
+    }
+
+    @Test
+    public void testMapConstructorCopiesContents() throws JSONException {
+        Map<String, Object> contents = new HashMap<String, Object>();
+        contents.put("foo", 5);
+        JSONObject object = new JSONObject(contents);
+        contents.put("foo", 10);
+        assertEquals(5, object.get("foo"));
+    }
+
+    @Test
+    public void testMapConstructorWithBogusEntries() {
+        Map<Object, Object> contents = new HashMap<Object, Object>();
+        contents.put(5, 5);
+
+        try {
+            new JSONObject(contents);
+            fail("JSONObject constructor doesn't validate its input!");
+        } catch (Exception ignored) {
+        }
+    }
+
+    @Test
+    public void testTokenerConstructor() throws JSONException {
+        JSONObject object = new JSONObject(new JSONTokener("{\"foo\": false}"));
+        assertEquals(1, object.length());
+        assertEquals(false, object.get("foo"));
+    }
+
+    @Test
+    public void testTokenerConstructorWrongType() throws JSONException {
+        try {
+            new JSONObject(new JSONTokener("[\"foo\", false]"));
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testTokenerConstructorNull() throws JSONException {
+        try {
+            new JSONObject((JSONTokener) null);
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+    }
+
+    @Test
+    public void testTokenerConstructorParseFail() {
+        try {
+            new JSONObject(new JSONTokener("{"));
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testStringConstructor() throws JSONException {
+        JSONObject object = new JSONObject("{\"foo\": false}");
+        assertEquals(1, object.length());
+        assertEquals(false, object.get("foo"));
+    }
+
+    @Test
+    public void testStringConstructorWrongType() throws JSONException {
+        try {
+            new JSONObject("[\"foo\", false]");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testStringConstructorNull() throws JSONException {
+        try {
+            new JSONObject((String) null);
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+    }
+
+    @Test
+    public void testStringConstructorParseFail() {
+        try {
+            new JSONObject("{");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    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"));
+    }
+
+    @Test
+    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"));
+    }
+
+    @Test
+    public void testAccumulateMutatesInPlace() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        object.accumulate("foo", 6);
+        JSONArray array = object.getJSONArray("foo");
+        assertEquals("[5,6]", array.toString());
+        object.accumulate("foo", 7);
+        assertEquals("[5,6,7]", array.toString());
+    }
+
+    @Test
+    public void testAccumulateExistingArray() throws JSONException {
+        JSONArray array = new JSONArray();
+        JSONObject object = new JSONObject();
+        object.put("foo", array);
+        object.accumulate("foo", 5);
+        assertEquals("[5]", array.toString());
+    }
+
+    @Test
+    public void testAccumulatePutArray() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.accumulate("foo", 5);
+        assertEquals("{\"foo\":5}", object.toString());
+        object.accumulate("foo", new JSONArray());
+        assertEquals("{\"foo\":[5,[]]}", object.toString());
+    }
+
+    @Test
+    public void testAccumulateNull() {
+        JSONObject object = new JSONObject();
+        try {
+            object.accumulate(null, 5);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testEmptyStringKey() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("", 5);
+        assertEquals(5, object.get(""));
+        assertEquals("{\"\":5}", object.toString());
+    }
+
+    @Test
+    public void testNullValue() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", JSONObject.NULL);
+        object.put("bar", null);
+
+        // there are two ways to represent null; each behaves differently!
+        assertTrue(object.has("foo"));
+        assertFalse(object.has("bar"));
+        assertTrue(object.isNull("foo"));
+        assertTrue(object.isNull("bar"));
+    }
+
+    @Test
+    public void testNullValue_equalsAndHashCode() {
+        //noinspection ObjectEqualsNull
+        assertTrue(JSONObject.NULL.equals(null)); // guaranteed by javadoc
+        // not guaranteed by javadoc, but seems like a good idea
+        assertEquals(Objects.hashCode(null), JSONObject.NULL.hashCode());
+    }
+
+    @Test
+    public void testHas() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        assertTrue(object.has("foo"));
+        assertFalse(object.has("bar"));
+        assertFalse(object.has(null));
+    }
+
+    @Test
+    public void testOptNull() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", "bar");
+        assertEquals(null, object.opt(null));
+        assertEquals(false, object.optBoolean(null));
+        assertEquals(Double.NaN, object.optDouble(null), 0);
+        assertEquals(0, object.optInt(null));
+        assertEquals(0L, object.optLong(null));
+        assertEquals(null, object.optJSONArray(null));
+        assertEquals(null, object.optJSONObject(null));
+        assertEquals("", object.optString(null));
+        assertEquals(true, object.optBoolean(null, true));
+        assertEquals(0.0d, object.optDouble(null, 0.0d), 0);
+        assertEquals(1, object.optInt(null, 1));
+        assertEquals(1L, object.optLong(null, 1L));
+        assertEquals("baz", object.optString(null, "baz"));
+    }
+
+    @Test
+    public void testToStringWithIndentFactor() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", new JSONArray(Arrays.asList(5, 6)));
+        object.put("bar", new JSONObject());
+        String foobar = "{\n" +
+                "     \"foo\": [\n" +
+                "          5,\n" +
+                "          6\n" +
+                "     ],\n" +
+                "     \"bar\": {}\n" +
+                "}";
+        String barfoo = "{\n" +
+                "     \"bar\": {},\n" +
+                "     \"foo\": [\n" +
+                "          5,\n" +
+                "          6\n" +
+                "     ]\n" +
+                "}";
+        String string = object.toString(5);
+        assertTrue(string, foobar.equals(string) || barfoo.equals(string));
+    }
+
+    @Test
+    public void testNames() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        object.put("bar", 6);
+        object.put("baz", 7);
+        JSONArray array = object.names();
+        assertTrue(array.toString().contains("foo"));
+        assertTrue(array.toString().contains("bar"));
+        assertTrue(array.toString().contains("baz"));
+    }
+
+    @Test
+    public void testKeysEmptyObject() {
+        JSONObject object = new JSONObject();
+        assertFalse(object.keys().hasNext());
+        try {
+            object.keys().next();
+            fail();
+        } catch (NoSuchElementException ignored) {
+        }
+    }
+
+    @Test
+    public void testKeys() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        object.put("bar", 6);
+        object.put("foo", 7);
+
+        @SuppressWarnings("unchecked")
+        Iterator<String> keys = object.keys();
+        Set<String> result = new HashSet<String>();
+        assertTrue(keys.hasNext());
+        result.add(keys.next());
+        assertTrue(keys.hasNext());
+        result.add(keys.next());
+        assertFalse(keys.hasNext());
+        assertEquals(new HashSet<String>(Arrays.asList("foo", "bar")), result);
+
+        try {
+            keys.next();
+            fail();
+        } catch (NoSuchElementException ignored) {
+        }
+    }
+
+    @Test
+    public void testMutatingKeysMutatesObject() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        Iterator keys = object.keys();
+        keys.next();
+        keys.remove();
+        assertEquals(0, object.length());
+    }
+
+    @Test
+    public void testQuote() {
+        // covered by JSONStringerTest.testEscaping
+    }
+
+    @Test
+    public void testQuoteNull() throws JSONException {
+        assertEquals("\"\"", JSONObject.quote(null));
+    }
+
+    @Test
+    public void testNumberToString() throws JSONException {
+        assertEquals("5", JSONObject.numberToString(5));
+        assertEquals("-0", JSONObject.numberToString(-0.0d));
+        assertEquals("9223372036854775806", JSONObject.numberToString(9223372036854775806L));
+        assertEquals("4.9E-324", JSONObject.numberToString(Double.MIN_VALUE));
+        assertEquals("1.7976931348623157E308", JSONObject.numberToString(Double.MAX_VALUE));
+        try {
+            JSONObject.numberToString(Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            JSONObject.numberToString(Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            JSONObject.numberToString(Double.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals("0.001", JSONObject.numberToString(new BigDecimal("0.001")));
+        assertEquals("9223372036854775806",
+                JSONObject.numberToString(new BigInteger("9223372036854775806")));
+        try {
+            JSONObject.numberToString(null);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void test_wrap() throws Exception {
+        assertEquals(JSONObject.NULL, JSONObject.wrap(null));
+
+        JSONArray a = new JSONArray();
+        assertEquals(a, JSONObject.wrap(a));
+
+        JSONObject o = new JSONObject();
+        assertEquals(o, JSONObject.wrap(o));
+
+        assertEquals(JSONObject.NULL, JSONObject.wrap(JSONObject.NULL));
+
+        assertTrue(JSONObject.wrap(new byte[0]) instanceof JSONArray);
+        assertTrue(JSONObject.wrap(new ArrayList<String>()) instanceof JSONArray);
+        assertTrue(JSONObject.wrap(new HashMap<String, String>()) instanceof JSONObject);
+        assertTrue(JSONObject.wrap(0.0) instanceof Double);
+        assertTrue(JSONObject.wrap("hello") instanceof String);
+    }
+
+    // https://code.google.com/p/android/issues/detail?id=55114
+    @Test
+    public void test_toString_listAsMapValue() throws Exception {
+        ArrayList<Object> list = new ArrayList<Object>();
+        list.add("a");
+        list.add(new ArrayList<String>());
+        Map<String, Object> map = new TreeMap<String, Object>();
+        map.put("x", "l");
+        map.put("y", list);
+        assertEquals("{\"x\":\"l\",\"y\":[\"a\",[]]}", new JSONObject(map).toString());
+    }
+
+    @Test
+    public void testAppendExistingInvalidKey() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("foo", 5);
+        try {
+            object.append("foo", 6);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testAppendExistingArray() throws JSONException {
+        JSONArray array = new JSONArray();
+        JSONObject object = new JSONObject();
+        object.put("foo", array);
+        object.append("foo", 5);
+        assertEquals("[5]", array.toString());
+    }
+
+    @Test
+    public void testAppendPutArray() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.append("foo", 5);
+        assertEquals("{\"foo\":[5]}", object.toString());
+        object.append("foo", new JSONArray());
+        assertEquals("{\"foo\":[5,[]]}", object.toString());
+    }
+
+    @Test
+    public void testAppendNull() {
+        JSONObject object = new JSONObject();
+        try {
+            object.append(null, 5);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    // https://code.google.com/p/android/issues/detail?id=103641
+    @Test
+    public void testInvalidUnicodeEscape() {
+        try {
+            new JSONObject("{\"q\":\"\\u\", \"r\":[]}");
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testBeanThings() throws IllegalAccessException, IntrospectionException, InvocationTargetException {
+        Foo f = new Foo();
+        assertEquals("{\"a\":1,\"b\":1,\"c\":\"c\",\"d\":[{\"e\":\"echo\"}]}", new JSONObject(f).toString());
+    }
+
+    @Test
+    public void testGetNames() throws Exception {
+        assertArrayEquals(new String[]{"a", "b", "c", "d"}, JSONObject.getNames(new JSONObject(new Foo())));
+    }
+
+    private static class Foo {
+        public double getA() {
+            return 1.0;
+        }
+
+        public int getB() {
+            return 1;
+        }
+
+        public String getC() {
+            return "c";
+        }
+
+        public List<Bar> getD() {
+            ArrayList<Bar> r = new ArrayList<Bar>();
+            r.add(new Bar());
+            return r;
+        }
+    }
+
+    private static class Bar {
+        public String getE() {
+            return "echo";
+        }
+    }
+
+    @Test
+    public void testEnumWrapper() throws Exception {
+        Object y = JSONObject.wrap(E.A);
+        assertEquals("A", y);
+        assertTrue(y instanceof String);
+    }
+
+    enum E {
+        A {
+            int key() {
+                return 1;
+            }
+        }, B {
+            int key() {
+                return 2;
+            }
+        };
+        int key() {
+            return -1;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/b34e47ff/geode-json/src/test/java/org/json/JSONStringerTest.java
----------------------------------------------------------------------
diff --git a/geode-json/src/test/java/org/json/JSONStringerTest.java b/geode-json/src/test/java/org/json/JSONStringerTest.java
new file mode 100755
index 0000000..7c7362d
--- /dev/null
+++ b/geode-json/src/test/java/org/json/JSONStringerTest.java
@@ -0,0 +1,421 @@
+/*
+ * 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 org.junit.Test;
+
+import java.util.concurrent.TimeUnit;
+
+import static org.junit.Assert.*;
+
+/**
+ * This black box test was written without inspecting the non-free org.json sourcecode.
+ */
+public class JSONStringerTest {
+
+    @Test
+    public void testJSONFunctionHackTest() {
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.key("key");
+        stringer.value(new JSONFunctionTestObject("window.test('foo' + \"bar\")"));
+        stringer.endObject();
+        assertEquals("{\"key\":window.test('foo' + \"bar\")}", stringer.toString());
+    }
+
+    @Test
+    public void testEmptyStringer() {
+        // why isn't this the empty string?
+        assertNull(new JSONStringer().toString());
+    }
+
+    @Test
+    public void testValueJSONNull() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(JSONObject.NULL);
+        stringer.endArray();
+        assertEquals("[null]", stringer.toString());
+    }
+
+    @Test
+    public void testEmptyObject() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.endObject();
+        assertEquals("{}", stringer.toString());
+    }
+
+    @Test
+    public void testEmptyArray() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.endArray();
+        assertEquals("[]", stringer.toString());
+    }
+
+    @Test
+    public void testArray() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(false);
+        stringer.value(5.0);
+        stringer.value(5L);
+        stringer.value("five");
+        stringer.value(null);
+        stringer.endArray();
+        assertEquals("[false,5,5,\"five\",null]", stringer.toString());
+    }
+
+    @Test
+    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());
+    }
+
+    @Test
+    public void testKeyValue() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.key("a").value(false);
+        stringer.key("b").value(5.0);
+        stringer.key("c").value(5L);
+        stringer.key("d").value("five");
+        stringer.key("e").value(null);
+        stringer.endObject();
+        assertEquals("{\"a\":false," +
+                "\"b\":5," +
+                "\"c\":5," +
+                "\"d\":\"five\"," +
+                "\"e\":null}", stringer.toString());
+    }
+
+    /**
+     * Test what happens when extreme values are emitted. Such values are likely
+     * to be rounded during parsing.
+     */
+    @Test
+    public void testNumericRepresentations() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(Long.MAX_VALUE);
+        stringer.value(Double.MIN_VALUE);
+        stringer.endArray();
+        assertEquals("[9223372036854775807,4.9E-324]", stringer.toString());
+    }
+
+    @Test
+    public void testWeirdNumbers() throws JSONException {
+        try {
+            new JSONStringer().array().value(Double.NaN);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().array().value(Double.NEGATIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().array().value(Double.POSITIVE_INFINITY);
+            fail();
+        } catch (JSONException ignored) {
+        }
+
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(-0.0d);
+        stringer.value(0.0d);
+        stringer.endArray();
+        assertEquals("[-0,0]", stringer.toString());
+    }
+
+    @Test
+    public void testMismatchedScopes() {
+        try {
+            new JSONStringer().key("a");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().value("a");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().endObject();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().endArray();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().array().endObject();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().object().endArray();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().object().key("a").key("a");
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONStringer().object().value(false);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testNullKey() {
+        try {
+            new JSONStringer().object().key(null);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testRepeatedKey() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.key("a").value(true);
+        stringer.key("a").value(false);
+        stringer.endObject();
+        // JSONStringer doesn't attempt to detect duplicates
+        assertEquals("{\"a\":true,\"a\":false}", stringer.toString());
+    }
+
+    @Test
+    public void testEmptyKey() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.key("").value(false);
+        stringer.endObject();
+        assertEquals("{\"\":false}", stringer.toString()); // legit behaviour!
+    }
+
+    @Test
+    public void testEscaping() throws JSONException {
+        assertEscapedAllWays("a", "a");
+        assertEscapedAllWays("a\\\"", "a\"");
+        assertEscapedAllWays("\\\"", "\"");
+        assertEscapedAllWays(":", ":");
+        assertEscapedAllWays(",", ",");
+        assertEscapedAllWays("\\b", "\b");
+        assertEscapedAllWays("\\f", "\f");
+        assertEscapedAllWays("\\n", "\n");
+        assertEscapedAllWays("\\r", "\r");
+        assertEscapedAllWays("\\t", "\t");
+        assertEscapedAllWays(" ", " ");
+        assertEscapedAllWays("\\\\", "\\");
+        assertEscapedAllWays("{", "{");
+        assertEscapedAllWays("}", "}");
+        assertEscapedAllWays("[", "[");
+        assertEscapedAllWays("]", "]");
+        assertEscapedAllWays("\\u0000", "\0");
+        assertEscapedAllWays("\\u0019", "\u0019");
+        assertEscapedAllWays(" ", "\u0020");
+        assertEscapedAllWays("<\\/foo>", "</foo>");
+    }
+
+    private void assertEscapedAllWays(String escaped, String original) throws JSONException {
+        assertEquals("{\"" + escaped + "\":false}",
+                new JSONStringer().object().key(original).value(false).endObject().toString());
+        assertEquals("{\"a\":\"" + escaped + "\"}",
+                new JSONStringer().object().key("a").value(original).endObject().toString());
+        assertEquals("[\"" + escaped + "\"]",
+                new JSONStringer().array().value(original).endArray().toString());
+        assertEquals("\"" + escaped + "\"", JSONObject.quote(original));
+    }
+
+    @Test
+    public void testJSONArrayAsValue() throws JSONException {
+        JSONArray array = new JSONArray();
+        array.put(false);
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.value(array);
+        stringer.endArray();
+        assertEquals("[[false]]", stringer.toString());
+    }
+
+    @Test
+    public void testJSONObjectAsValue() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("a", false);
+        JSONStringer stringer = new JSONStringer();
+        stringer.object();
+        stringer.key("b").value(object);
+        stringer.endObject();
+        assertEquals("{\"b\":{\"a\":false}}", stringer.toString());
+    }
+
+    @Test
+    public void testArrayNestingMaxDepthSupports20() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.array();
+        }
+        for (int i = 0; i < 20; i++) {
+            stringer.endArray();
+        }
+        assertEquals("[[[[[[[[[[[[[[[[[[[[]]]]]]]]]]]]]]]]]]]]", stringer.toString());
+
+        stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.array();
+        }
+    }
+
+    @Test
+    public void testObjectNestingMaxDepthSupports20() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.object();
+            stringer.key("a");
+        }
+        stringer.value(false);
+        for (int i = 0; i < 20; i++) {
+            stringer.endObject();
+        }
+        assertEquals("{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":" +
+                "{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":{\"a\":false" +
+                "}}}}}}}}}}}}}}}}}}}}", stringer.toString());
+
+        stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.object();
+            stringer.key("a");
+        }
+    }
+
+    @Test
+    public void testMixedMaxDepthSupports20() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        for (int i = 0; i < 20; i += 2) {
+            stringer.array();
+            stringer.object();
+            stringer.key("a");
+        }
+        stringer.value(false);
+        for (int i = 0; i < 20; i += 2) {
+            stringer.endObject();
+            stringer.endArray();
+        }
+        assertEquals("[{\"a\":[{\"a\":[{\"a\":[{\"a\":[{\"a\":" +
+                "[{\"a\":[{\"a\":[{\"a\":[{\"a\":[{\"a\":false" +
+                "}]}]}]}]}]}]}]}]}]}]", stringer.toString());
+
+        stringer = new JSONStringer();
+        for (int i = 0; i < 20; i += 2) {
+            stringer.array();
+            stringer.object();
+            stringer.key("a");
+        }
+    }
+
+    @Test
+    public void testMaxDepthWithArrayValue() throws JSONException {
+        JSONArray array = new JSONArray();
+        array.put(false);
+
+        JSONStringer stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.array();
+        }
+        stringer.value(array);
+        for (int i = 0; i < 20; i++) {
+            stringer.endArray();
+        }
+        assertEquals("[[[[[[[[[[[[[[[[[[[[[false]]]]]]]]]]]]]]]]]]]]]", stringer.toString());
+    }
+
+    @Test
+    public void testMaxDepthWithObjectValue() throws JSONException {
+        JSONObject object = new JSONObject();
+        object.put("a", false);
+        JSONStringer stringer = new JSONStringer();
+        for (int i = 0; i < 20; i++) {
+            stringer.object();
+            stringer.key("b");
+        }
+        stringer.value(object);
+        for (int i = 0; i < 20; i++) {
+            stringer.endObject();
+        }
+        assertEquals("{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":" +
+                "{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":{\"b\":" +
+                "{\"a\":false}}}}}}}}}}}}}}}}}}}}}", stringer.toString());
+    }
+
+    @Test
+    public void testMultipleRoots() throws JSONException {
+        JSONStringer stringer = new JSONStringer();
+        stringer.array();
+        stringer.endArray();
+        try {
+            stringer.object();
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    @Test
+    public void testEnums() {
+        JSONObject x = new JSONObject();
+        x.put("a", TimeUnit.SECONDS);
+        x.put("b", "xyx");
+        JSONStringer s = new JSONStringer();
+        s.array();
+        s.value(x);
+        s.endArray();
+        assertEquals("[{\"a\":\"SECONDS\",\"b\":\"xyx\"}]", s.toString());
+    }
+
+    @Test
+    public void testJsonString() {
+        JSONObject x = new JSONObject();
+        x.put("a", new Goo());
+        JSONStringer s = new JSONStringer();
+        s.array();
+        s.value(x);
+        s.endArray();
+        // note lack of quotes
+        assertEquals("[{\"a\":fffooo}]", s.toString());
+    }
+
+    private static class Goo implements JSONString {
+        @Override
+        public String toJSONString() {
+            return "fffooo";
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/geode/blob/b34e47ff/geode-json/src/test/java/org/json/JSONTokenerTest.java
----------------------------------------------------------------------
diff --git a/geode-json/src/test/java/org/json/JSONTokenerTest.java b/geode-json/src/test/java/org/json/JSONTokenerTest.java
new file mode 100755
index 0000000..9975177
--- /dev/null
+++ b/geode-json/src/test/java/org/json/JSONTokenerTest.java
@@ -0,0 +1,621 @@
+/*
+ * 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.AssertionFailedError;
+import junit.framework.TestCase;
+
+/**
+ * This black box test was written without inspecting the non-free org.json sourcecode.
+ */
+public class JSONTokenerTest extends TestCase {
+
+    public void testNulls() throws JSONException {
+        // JSONTokener accepts null, only to fail later on almost all APIs!
+        new JSONTokener((String) null).back();
+
+        try {
+            new JSONTokener((String) null).more();
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).next();
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).next(3);
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).next('A');
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).nextClean();
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).nextString('"');
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).nextTo('A');
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).nextTo("ABC");
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).nextValue();
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).skipPast("ABC");
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        try {
+            new JSONTokener((String) null).skipTo('A');
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+
+        //noinspection ThrowableResultOfMethodCallIgnored
+        assertEquals("foo! at character 0 of null",
+                new JSONTokener((String) null).syntaxError("foo!").getMessage());
+
+        assertEquals(" at character 0 of null", new JSONTokener((String) null).toString());
+    }
+
+    public void testEmptyString() throws JSONException {
+        JSONTokener backTokener = new JSONTokener("");
+        backTokener.back();
+        assertEquals(" at character 0 of ", backTokener.toString());
+        assertFalse(new JSONTokener("").more());
+        assertEquals('\0', new JSONTokener("").next());
+        try {
+            new JSONTokener("").next(3);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONTokener("").next('A');
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals('\0', new JSONTokener("").nextClean());
+        try {
+            new JSONTokener("").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals("", new JSONTokener("").nextTo('A'));
+        assertEquals("", new JSONTokener("").nextTo("ABC"));
+        try {
+            new JSONTokener("").nextValue();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        new JSONTokener("").skipPast("ABC");
+        assertEquals('\0', new JSONTokener("").skipTo('A'));
+        //noinspection ThrowableResultOfMethodCallIgnored
+        assertEquals("foo! at character 0 of ",
+                new JSONTokener("").syntaxError("foo!").getMessage());
+        assertEquals(" at character 0 of ", new JSONTokener("").toString());
+    }
+
+    public void testCharacterNavigation() throws JSONException {
+        JSONTokener abcdeTokener = new JSONTokener("ABCDE");
+        assertEquals('A', abcdeTokener.next());
+        assertEquals('B', abcdeTokener.next('B'));
+        assertEquals("CD", abcdeTokener.next(2));
+        try {
+            abcdeTokener.next(2);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals('E', abcdeTokener.nextClean());
+        assertEquals('\0', abcdeTokener.next());
+        assertFalse(abcdeTokener.more());
+        abcdeTokener.back();
+        assertTrue(abcdeTokener.more());
+        assertEquals('E', abcdeTokener.next());
+    }
+
+    public void testBackNextAndMore() throws JSONException {
+        JSONTokener abcTokener = new JSONTokener("ABC");
+        assertTrue(abcTokener.more());
+        abcTokener.next();
+        abcTokener.next();
+        assertTrue(abcTokener.more());
+        abcTokener.next();
+        assertFalse(abcTokener.more());
+        abcTokener.back();
+        assertTrue(abcTokener.more());
+        abcTokener.next();
+        assertFalse(abcTokener.more());
+        abcTokener.back();
+        abcTokener.back();
+        abcTokener.back();
+        abcTokener.back(); // you can back up before the beginning of a String!
+        assertEquals('A', abcTokener.next());
+    }
+
+    public void testNextMatching() throws JSONException {
+        JSONTokener abcdTokener = new JSONTokener("ABCD");
+        assertEquals('A', abcdTokener.next('A'));
+        try {
+            abcdTokener.next('C'); // although it failed, this op consumes a character of input
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals('C', abcdTokener.next('C'));
+        assertEquals('D', abcdTokener.next('D'));
+        try {
+            abcdTokener.next('E');
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    public void testNextN() throws JSONException {
+        JSONTokener abcdeTokener = new JSONTokener("ABCDEF");
+        assertEquals("", abcdeTokener.next(0));
+        try {
+            abcdeTokener.next(7);
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals("ABC", abcdeTokener.next(3));
+        try {
+            abcdeTokener.next(4);
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    public void testNextNWithAllRemaining() throws JSONException {
+        JSONTokener tokener = new JSONTokener("ABCDEF");
+        tokener.next(3);
+        try {
+            tokener.next(3);
+        } catch (JSONException e) {
+            AssertionFailedError error = new AssertionFailedError("off-by-one error?");
+            error.initCause(e);
+            throw error;
+        }
+    }
+
+    public void testNext0() throws JSONException {
+        JSONTokener tokener = new JSONTokener("ABCDEF");
+        tokener.next(5);
+        tokener.next();
+        try {
+            tokener.next(0);
+        } catch (JSONException e) {
+            Error error = new AssertionFailedError("Returning an empty string should be valid");
+            error.initCause(e);
+            throw error;
+        }
+    }
+
+    public void testNextCleanComments() throws JSONException {
+        JSONTokener tokener = new JSONTokener(
+                "  A  /*XX*/B/*XX//XX\n//XX\nXX*/C//X//X//X\nD/*X*///X\n");
+        assertEquals('A', tokener.nextClean());
+        assertEquals('B', tokener.nextClean());
+        assertEquals('C', tokener.nextClean());
+        assertEquals('D', tokener.nextClean());
+        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());
+    }
+
+    /**
+     * Some applications rely on parsing '#' to lead an end-of-line comment.
+     * http://b/2571423
+     */
+    public void testNextCleanHashComments() throws JSONException {
+        JSONTokener tokener = new JSONTokener("A # B */ /* C */ \nD #");
+        assertEquals('A', tokener.nextClean());
+        assertEquals('D', tokener.nextClean());
+        assertEquals('\0', 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();
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals('\0', new JSONTokener("  // ").nextClean());
+    }
+
+    public void testNextCleanNewlineDelimiters() throws JSONException {
+        assertEquals('B', new JSONTokener("  // \r\n  B ").nextClean());
+        assertEquals('B', new JSONTokener("  // \n  B ").nextClean());
+        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 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');
+    }
+
+    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 {
+        assertEquals("", new JSONTokener("'").nextString('\''));
+        assertEquals("", new JSONTokener("\"").nextString('\"'));
+        assertEquals("ABC", new JSONTokener("ABC'DEF").nextString('\''));
+        assertEquals("ABC", new JSONTokener("ABC'''DEF").nextString('\''));
+
+        // nextString permits slash-escaping of arbitrary characters!
+        assertEquals("ABC", new JSONTokener("A\\B\\C'DEF").nextString('\''));
+
+        JSONTokener tokener = new JSONTokener(" 'abc' 'def' \"ghi\"");
+        tokener.next();
+        assertEquals('\'', tokener.next());
+        assertEquals("abc", tokener.nextString('\''));
+        tokener.next();
+        assertEquals('\'', tokener.next());
+        assertEquals("def", tokener.nextString('\''));
+        tokener.next();
+        assertEquals('"', tokener.next());
+        assertEquals("ghi", tokener.nextString('\"'));
+        assertFalse(tokener.more());
+    }
+
+    public void testNextStringNoDelimiter() throws JSONException {
+        try {
+            new JSONTokener("").nextString('\'');
+            fail();
+        } catch (JSONException ignored) {
+        }
+
+        JSONTokener tokener = new JSONTokener(" 'abc");
+        tokener.next();
+        tokener.next();
+        try {
+            tokener.next('\'');
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    public void testNextStringEscapedQuote() throws JSONException {
+        try {
+            new JSONTokener("abc\\").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+
+        // we're mixing Java escaping like \" and JavaScript escaping like \\\"
+        // which makes these tests extra tricky to read!
+        assertEquals("abc\"def", new JSONTokener("abc\\\"def\"ghi").nextString('"'));
+        assertEquals("abc\\def", new JSONTokener("abc\\\\def\"ghi").nextString('"'));
+        assertEquals("abc/def", new JSONTokener("abc\\/def\"ghi").nextString('"'));
+        assertEquals("abc\bdef", new JSONTokener("abc\\bdef\"ghi").nextString('"'));
+        assertEquals("abc\fdef", new JSONTokener("abc\\fdef\"ghi").nextString('"'));
+        assertEquals("abc\ndef", new JSONTokener("abc\\ndef\"ghi").nextString('"'));
+        assertEquals("abc\rdef", new JSONTokener("abc\\rdef\"ghi").nextString('"'));
+        assertEquals("abc\tdef", new JSONTokener("abc\\tdef\"ghi").nextString('"'));
+    }
+
+    public void testNextStringUnicodeEscaped() throws JSONException {
+        // we're mixing Java escaping like \\ and JavaScript escaping like \\u
+        assertEquals("abc def", new JSONTokener("abc\\u0020def\"ghi").nextString('"'));
+        assertEquals("abcU0020def", new JSONTokener("abc\\U0020def\"ghi").nextString('"'));
+
+        // JSON requires 4 hex characters after a unicode escape
+        try {
+            new JSONTokener("abc\\u002\"").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONTokener("abc\\u").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+        try {
+            new JSONTokener("abc\\u    \"").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+        assertEquals("abc\"def", new JSONTokener("abc\\u0022def\"ghi").nextString('"'));
+        try {
+            new JSONTokener("abc\\u000G\"").nextString('"');
+            fail();
+        } catch (JSONException ignored) {
+        }
+    }
+
+    public void testNextStringNonQuote() throws JSONException {
+        assertEquals("AB", new JSONTokener("ABC").nextString('C'));
+        assertEquals("ABCD", new JSONTokener("AB\\CDC").nextString('C'));
+        assertEquals("AB\nC", new JSONTokener("AB\\nCn").nextString('n'));
+    }
+
+    public void testNextTo() throws JSONException {
+        assertEquals("ABC", new JSONTokener("ABCDEFG").nextTo("DHI"));
+        assertEquals("ABCDEF", new JSONTokener("ABCDEF").nextTo(""));
+
+        JSONTokener tokener = new JSONTokener("ABC\rDEF\nGHI\r\nJKL");
+        assertEquals("ABC", tokener.nextTo("M"));
+        assertEquals('\r', tokener.next());
+        assertEquals("DEF", tokener.nextTo("M"));
+        assertEquals('\n', tokener.next());
+        assertEquals("GHI", tokener.nextTo("M"));
+        assertEquals('\r', tokener.next());
+        assertEquals('\n', tokener.next());
+        assertEquals("JKL", tokener.nextTo("M"));
+
+        tokener = new JSONTokener("ABCDEFGHI");
+        assertEquals("ABC", tokener.nextTo("DEF"));
+        assertEquals("", tokener.nextTo("DEF"));
+        assertEquals('D', tokener.next());
+        assertEquals("", tokener.nextTo("DEF"));
+        assertEquals('E', tokener.next());
+        assertEquals("", tokener.nextTo("DEF"));
+        assertEquals('F', tokener.next());
+        assertEquals("GHI", tokener.nextTo("DEF"));
+        assertEquals("", tokener.nextTo("DEF"));
+
+        tokener = new JSONTokener(" \t \fABC \t DEF");
+        assertEquals("ABC", tokener.nextTo("DEF"));
+        assertEquals('D', tokener.next());
+
+        tokener = new JSONTokener(" \t \fABC \n DEF");
+        assertEquals("ABC", tokener.nextTo("\n"));
+        assertEquals("", tokener.nextTo("\n"));
+
+        tokener = new JSONTokener("");
+        try {
+            tokener.nextTo(null);
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+    }
+
+    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");
+        assertEquals('D', tokener.next());
+        tokener.skipPast("EF");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABCDEF");
+        tokener.skipPast("ABCDEF");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABCDEF");
+        tokener.skipPast("G");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABC\0ABC");
+        tokener.skipPast("ABC");
+        assertEquals('\0', tokener.next());
+        assertEquals('A', tokener.next());
+
+        tokener = new JSONTokener("\0ABC");
+        tokener.skipPast("ABC");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABC\nDEF");
+        tokener.skipPast("DEF");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABC");
+        tokener.skipPast("ABCDEF");
+        assertEquals('\0', tokener.next());
+
+        tokener = new JSONTokener("ABCDABCDABCD");
+        tokener.skipPast("ABC");
+        assertEquals('D', tokener.next());
+        tokener.skipPast("ABC");
+        assertEquals('D', tokener.next());
+        tokener.skipPast("ABC");
+        assertEquals('D', tokener.next());
+
+        tokener = new JSONTokener("");
+        try {
+            tokener.skipPast(null);
+            fail();
+        } catch (NullPointerException ignored) {
+        }
+    }
+
+    public void testSkipTo() {
+        JSONTokener tokener = new JSONTokener("ABCDEF");
+        tokener.skipTo('A');
+        assertEquals('A', tokener.next());
+        tokener.skipTo('D');
+        assertEquals('D', tokener.next());
+        tokener.skipTo('G');
+        assertEquals('E', tokener.next());
+        tokener.skipTo('A');
+        assertEquals('F', tokener.next());
+
+        tokener = new JSONTokener("ABC\nDEF");
+        tokener.skipTo('F');
+        assertEquals('F', tokener.next());
+
+        tokener = new JSONTokener("ABCfDEF");
+        tokener.skipTo('F');
+        assertEquals('F', tokener.next());
+
+        tokener = new JSONTokener("ABC/* DEF */");
+        tokener.skipTo('D');
+        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 testBomIgnoredAsFirstCharacterOfDocument() throws JSONException {
+        JSONTokener tokener = new JSONTokener("\ufeff[]");
+        JSONArray array = (JSONArray) tokener.nextValue();
+        assertEquals(0, array.length());
+    }
+
+    public void testBomTreatedAsCharacterInRestOfDocument() throws JSONException {
+        JSONTokener tokener = new JSONTokener("[\ufeff]");
+        JSONArray array = (JSONArray) tokener.nextValue();
+        assertEquals(1, array.length());
+    }
+
+    public void testDehexchar() {
+        assertEquals( 0, JSONTokener.dehexchar('0'));
+        assertEquals( 1, JSONTokener.dehexchar('1'));
+        assertEquals( 2, JSONTokener.dehexchar('2'));
+        assertEquals( 3, JSONTokener.dehexchar('3'));
+        assertEquals( 4, JSONTokener.dehexchar('4'));
+        assertEquals( 5, JSONTokener.dehexchar('5'));
+        assertEquals( 6, JSONTokener.dehexchar('6'));
+        assertEquals( 7, JSONTokener.dehexchar('7'));
+        assertEquals( 8, JSONTokener.dehexchar('8'));
+        assertEquals( 9, JSONTokener.dehexchar('9'));
+        assertEquals(10, JSONTokener.dehexchar('A'));
+        assertEquals(11, JSONTokener.dehexchar('B'));
+        assertEquals(12, JSONTokener.dehexchar('C'));
+        assertEquals(13, JSONTokener.dehexchar('D'));
+        assertEquals(14, JSONTokener.dehexchar('E'));
+        assertEquals(15, JSONTokener.dehexchar('F'));
+        assertEquals(10, JSONTokener.dehexchar('a'));
+        assertEquals(11, JSONTokener.dehexchar('b'));
+        assertEquals(12, JSONTokener.dehexchar('c'));
+        assertEquals(13, JSONTokener.dehexchar('d'));
+        assertEquals(14, JSONTokener.dehexchar('e'));
+        assertEquals(15, JSONTokener.dehexchar('f'));
+
+        for (int c = 0; c <= 0xFFFF; c++) {
+            if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f')) {
+                continue;
+            }
+            assertEquals("dehexchar " + c, -1, JSONTokener.dehexchar((char) c));
+        }
+    }
+}


Mime
View raw message