http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
new file mode 100755
index 0000000..f621811
--- /dev/null
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
@@ -0,0 +1,182 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.json;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+import org.junit.*;
+
+@SuppressWarnings({"rawtypes","serial","javadoc"})
+public class CommonParserTest {
+
+       
//====================================================================================================
+       // testFromSerializer
+       
//====================================================================================================
+       @Test
+       public void testFromSerializer() throws Exception {
+               ReaderParser p = 
JsonParser.DEFAULT.clone().setClassLoader(getClass().getClassLoader()).addToDictionary(A1.class);
+
+               Map m = null;
+               m = (Map)p.parse("{a:1}", Object.class);
+               assertEquals(1, m.get("a"));
+               m = (Map)p.parse("{a:1,b:\"foo bar\"}", Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals("foo bar", m.get("b"));
+               m = (Map)p.parse("{a:1,b:\"foo bar\",c:false}", Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals(false, m.get("c"));
+               m = (Map)p.parse(" { a : 1 , b : 'foo' , c : false } ", 
Object.class);
+               assertEquals(1, m.get("a"));
+               assertEquals("foo", m.get("b"));
+               assertEquals(false, m.get("c"));
+
+               m = 
(Map)p.parse("{x:\"org.apache.juneau.test.Person\",addresses:[{x:\"org.apache.juneau.test.Address\",city:\"city
 A\",state:\"state A\",street:\"street A\",zip:12345}]}", Object.class);
+               assertEquals("org.apache.juneau.test.Person", m.get("x"));
+               List l = (List)m.get("addresses");
+               assertNotNull(l);
+               m = (Map)l.get(0);
+               assertNotNull(m);
+               assertEquals("org.apache.juneau.test.Address", m.get("x"));
+               assertEquals("city A", m.get("city"));
+               assertEquals("state A", m.get("state"));
+               assertEquals("street A", m.get("street"));
+               assertEquals(12345, m.get("zip"));
+
+               ObjectList jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
+               assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
+               assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
+
+               // Verify that all the following return null.
+               assertNull(p.parse((CharSequence)null, Object.class));
+               assertNull(p.parse("", Object.class));
+               assertNull(p.parse("   ", Object.class));
+               assertNull(p.parse("   \t", Object.class));
+               assertNull(p.parse("   /*foo*/", Object.class));
+               assertNull(p.parse("   /*foo*/   ", Object.class));
+               assertNull(p.parse("   //foo   ", Object.class));
+
+               try {
+                       jl = 
(ObjectList)p.parse("[{attribute:'value'},{attribute:'value'}]", Object.class);
+                       assertEquals("value", 
jl.getObjectMap(0).getString("attribute"));
+                       assertEquals("value", 
jl.getObjectMap(1).getString("attribute"));
+               } catch (Exception e) {
+                       fail(e.getLocalizedMessage());
+               }
+
+               A1 b = new A1();
+               A2 tl = new A2();
+               tl.add(new A3("name0","value0"));
+               tl.add(new A3("name1","value1"));
+               b.list = tl;
+               String json = new 
JsonSerializer().setProperty(SERIALIZER_addBeanTypeProperties, 
true).addToDictionary(A1.class).serialize(b);
+               b = (A1)p.parse(json, Object.class);
+               assertEquals("value1", b.list.get(1).value);
+
+               json = JsonSerializer.DEFAULT.serialize(b);
+               b = p.parse(json, A1.class);
+               assertEquals("value1", b.list.get(1).value);
+       }
+
+       @Bean(typeName="A1")
+       public static class A1 {
+               public A2 list;
+       }
+
+       public static class A2 extends LinkedList<A3> {
+       }
+
+       public static class A3 {
+               public String name, value;
+               public A3(){}
+               public A3(String name, String value) {
+                       this.name = name;
+                       this.value = value;
+               }
+       }
+
+       
//====================================================================================================
+       // Correct handling of unknown properties.
+       
//====================================================================================================
+       @Test
+       public void testCorrectHandlingOfUnknownProperties() throws Exception {
+               ReaderParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               B b;
+
+               String in =  "{a:1,unknown:3,b:2}";
+               b = p.parse(in, B.class);
+               assertEquals(b.a, 1);
+               assertEquals(b.b, 2);
+
+               try {
+                       p = new JsonParser();
+                       p.parse(in, B.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {}
+       }
+
+       public static class B {
+               public int a, b;
+       }
+
+       
//====================================================================================================
+       // Writing to Collection properties with no setters.
+       
//====================================================================================================
+       @Test
+       public void testCollectionPropertiesWithNoSetters() throws Exception {
+               JsonParser p = JsonParser.DEFAULT;
+               String json = "{ints:[1,2,3],beans:[{a:1,b:2}]}";
+               C t = p.parse(json, C.class);
+               assertEquals(t.getInts().size(), 3);
+               assertEquals(t.getBeans().get(0).b, 2);
+       }
+
+       public static class C {
+               private Collection<Integer> ints = new LinkedList<Integer>();
+               private List<B> beans = new LinkedList<B>();
+               public Collection<Integer> getInts() {
+                       return ints;
+               }
+               public List<B> getBeans() {
+                       return beans;
+               }
+       }
+
+       
//====================================================================================================
+       // Parser listeners.
+       
//====================================================================================================
+       @Test
+       public void testParserListeners() throws Exception {
+               final List<String> events = new LinkedList<String>();
+               JsonParser p = new 
JsonParser().setProperty(BEAN_ignoreUnknownBeanProperties, true);
+               p.addListener(
+                       new ParserListener() {
+                               @Override /* ParserListener */
+                               public <T> void onUnknownProperty(String 
propertyName, Class<T> beanClass, T bean, int line, int col) {
+                                       events.add(propertyName + "," + line + 
"," + col);
+                               }
+                       }
+               );
+
+               String json = "{a:1,unknownProperty:\"/foo\",b:2}";
+               p.parse(json, B.class);
+               assertEquals(1, events.size());
+               assertEquals("unknownProperty,1,5", events.get(0));
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
new file mode 100755
index 0000000..c443e31
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
@@ -0,0 +1,501 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.json;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.TestUtils.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.net.*;
+import java.net.URI;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testbeans.*;
+import org.junit.*;
+
+@SuppressWarnings({"serial","javadoc"})
+public class CommonTest {
+
+       
//====================================================================================================
+       // Trim nulls from beans
+       
//====================================================================================================
+       @Test
+       public void testTrimNullsFromBeans() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               A t1 = A.create(), t2;
+
+               s.setProperty(SERIALIZER_trimNullProperties, false);
+               String r = s.serialize(t1);
+               assertEquals("{s1:null,s2:'s2'}", r);
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimNullProperties, true);
+               r = s.serialize(t1);
+               assertEquals("{s2:'s2'}", r);
+               t2 = p.parse(r, A.class);
+               assertEqualObjects(t1, t2);
+       }
+
+       public static class A {
+               public String s1, s2;
+
+               public static A create() {
+                       A t = new A();
+                       t.s2 = "s2";
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty maps
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyMaps() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               B t1 = B.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:{},f2:{f2a:null,f2b:{s2:'s2'}}}", r);
+               t2 = p.parse(r, B.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyMaps, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:{f2a:null,f2b:{s2:'s2'}}}", r);
+               t2 = p.parse(r, B.class);
+               assertNull(t2.f1);
+       }
+
+       public static class B {
+               public TreeMap<String,A> f1, f2;
+
+               public static B create() {
+                       B t = new B();
+                       t.f1 = new TreeMap<String,A>();
+                       t.f2 = new 
TreeMap<String,A>(){{put("f2a",null);put("f2b",A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty lists
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyLists() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               C t1 = C.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, C.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, C.class);
+               assertNull(t2.f1);
+       }
+
+       public static class C {
+               public List<A> f1, f2;
+
+               public static C create() {
+                       C t = new C();
+                       t.f1 = new LinkedList<A>();
+                       t.f2 = new 
LinkedList<A>(){{add(null);add(A.create());}};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // Trim empty arrays
+       
//====================================================================================================
+       @Test
+       public void testTrimEmptyArrays() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+               JsonParser p = JsonParser.DEFAULT;
+               D t1 = D.create(), t2;
+               String r;
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, false);
+               r = s.serialize(t1);
+               assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, D.class);
+               assertEqualObjects(t1, t2);
+
+               s.setProperty(SERIALIZER_trimEmptyCollections, true);
+               r = s.serialize(t1);
+               assertEquals("{f2:[null,{s2:'s2'}]}", r);
+               t2 = p.parse(r, D.class);
+               assertNull(t2.f1);
+       }
+
+       public static class D {
+               public A[] f1, f2;
+
+               public static D create() {
+                       D t = new D();
+                       t.f1 = new A[]{};
+                       t.f2 = new A[]{null, A.create()};
+                       return t;
+               }
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperies() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               E1 t = new E1();
+               String r;
+
+               r = s.serialize(t);
+               
assertEquals("{x1:{f1:1},x2:{f1:1},x3:[{f1:1}],x4:[{f1:1}],x5:[{f1:1}],x6:[{f1:1}]}",
 r);
+               r = s.getSchemaSerializer().serialize(t);
+               assertTrue(r.indexOf("f2") == -1);
+       }
+
+       public static class E1 {
+               @BeanProperty(properties="f1") public E2 x1 = new E2();
+               @BeanProperty(properties="f1") public Map<String,Integer> x2 = 
new LinkedHashMap<String,Integer>() {{
+                       put("f1",1); put("f2",2);
+               }};
+               @BeanProperty(properties="f1") public E2[] x3 = {new E2()};
+               @BeanProperty(properties="f1") public List<E2> x4 = new 
LinkedList<E2>() {{
+                       add(new E2());
+               }};
+               @BeanProperty(properties="f1") public ObjectMap[] x5 = {new 
ObjectMap().append("f1",1).append("f2",2)};
+               @BeanProperty(properties="f1") public List<ObjectMap> x6 = new 
LinkedList<ObjectMap>() {{
+                       add(new ObjectMap().append("f1",1).append("f2",2));
+               }};
+       }
+
+       public static class E2 {
+               public int f1 = 1;
+               public int f2 = 2;
+       }
+
+       
//====================================================================================================
+       // @BeanProperty.properties annotation on list of beans.
+       
//====================================================================================================
+       @Test
+       public void testBeanPropertyProperiesOnListOfBeans() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               List<F> l = new LinkedList<F>();
+               F t = new F();
+               t.x1.add(new F());
+               l.add(t);
+               String json = s.serialize(l);
+               assertEquals("[{x1:[{x2:2}],x2:2}]", json);
+       }
+
+       public static class F {
+               @BeanProperty(properties="x2") public List<F> x1 = new 
LinkedList<F>();
+               public int x2 = 2;
+       }
+
+       
//====================================================================================================
+       // Test that URLs and URIs are serialized and parsed correctly.
+       
//====================================================================================================
+       @Test
+       public void testURIAttr() throws Exception {
+               JsonSerializer s = JsonSerializer.DEFAULT_LAX;
+               JsonParser p = JsonParser.DEFAULT;
+
+               G t = new G();
+               t.uri = new URI("http://uri";);
+               t.f1 = new URI("http://f1";);
+               t.f2 = new URL("http://f2";);
+
+               String json = s.serialize(t);
+               t = p.parse(json, G.class);
+               assertEquals("http://uri";, t.uri.toString());
+               assertEquals("http://f1";, t.f1.toString());
+               assertEquals("http://f2";, t.f2.toString());
+       }
+
+       public static class G {
+               public URI uri;
+               public URI f1;
+               public URL f2;
+       }
+
+       
//====================================================================================================
+       // Test URIs with URI_CONTEXT and URI_AUTHORITY
+       
//====================================================================================================
+       @Test
+       public void testUris() throws Exception {
+               WriterSerializer s = new JsonSerializer.Simple();
+               TestURI t = new TestURI();
+               String r;
+               String expected = "";
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.apache.org/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.apache.org/f6/x6',"
+                       +"f7:'http://www.apache.org/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.apache.org/fa/xa#MY_LABEL',"
+                       
+"fb:'http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar',"
+                       
+"fc:'http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar',"
+                       
+"fe:'http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "");  // Same as null.
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr");
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'/cr/f0/x0',"
+                       +"f1:'/cr/f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.apache.org/f3/x3',"
+                       +"f4:'/cr/f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.apache.org/f6/x6',"
+                       +"f7:'http://www.apache.org/f7/x7',"
+                       +"f8:'/cr/f8/x8',"
+                       +"f9:'/cr/f9/x9',"
+                       +"fa:'http://www.apache.org/fa/xa#MY_LABEL',"
+                       
+"fb:'http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar',"
+                       
+"fc:'http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar',"
+                       
+"fe:'http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/cr/");  // Same as 
above
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, "/");
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'/f0/x0',"
+                       +"f1:'/f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.apache.org/f3/x3',"
+                       +"f4:'/f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.apache.org/f6/x6',"
+                       +"f7:'http://www.apache.org/f7/x7',"
+                       +"f8:'/f8/x8',"
+                       +"f9:'/f9/x9',"
+                       +"fa:'http://www.apache.org/fa/xa#MY_LABEL',"
+                       
+"fb:'http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar',"
+                       
+"fc:'http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar',"
+                       
+"fe:'http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_relativeUriBase, null);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo";);
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'http://foo/f2/x2',"
+                       +"f3:'http://www.apache.org/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'http://foo/f5/x5',"
+                       +"f6:'http://www.apache.org/f6/x6',"
+                       +"f7:'http://www.apache.org/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.apache.org/fa/xa#MY_LABEL',"
+                       
+"fb:'http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar',"
+                       
+"fc:'http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar',"
+                       
+"fe:'http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "http://foo/";);
+               r = s.serialize(t);
+               assertEquals(expected, r);
+
+               s.setProperty(SERIALIZER_absolutePathUriBase, "");  // Same as 
null.
+               r = s.serialize(t);
+               expected = "{"
+                       +"f0:'f0/x0',"
+                       +"f1:'f1/x1',"
+                       +"f2:'/f2/x2',"
+                       +"f3:'http://www.apache.org/f3/x3',"
+                       +"f4:'f4/x4',"
+                       +"f5:'/f5/x5',"
+                       +"f6:'http://www.apache.org/f6/x6',"
+                       +"f7:'http://www.apache.org/f7/x7',"
+                       +"f8:'f8/x8',"
+                       +"f9:'f9/x9',"
+                       +"fa:'http://www.apache.org/fa/xa#MY_LABEL',"
+                       
+"fb:'http://www.apache.org/fb/xb?label=MY_LABEL&foo=bar',"
+                       
+"fc:'http://www.apache.org/fc/xc?foo=bar&label=MY_LABEL',"
+                       
+"fd:'http://www.apache.org/fd/xd?label2=MY_LABEL&foo=bar',"
+                       
+"fe:'http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'"
+                       +"}";
+               assertEquals(expected, r);
+       }
+
+       
//====================================================================================================
+       // Validate that you cannot update properties on locked serializer.
+       
//====================================================================================================
+       @Test
+       public void testLockedSerializer() throws Exception {
+               JsonSerializer s = new JsonSerializer().lock();
+               try {
+                       s.setProperty(JsonSerializerContext.JSON_simpleMode, 
true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(SerializerContext.SERIALIZER_addBeanTypeProperties, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+               try {
+                       
s.setProperty(BeanContext.BEAN_beanMapPutReturnsOldValue, true);
+                       fail("Locked exception not thrown");
+               } catch (LockedException e) {}
+       }
+
+       
//====================================================================================================
+       // Recursion
+       
//====================================================================================================
+       @Test
+       public void testRecursion() throws Exception {
+               JsonSerializer s = new JsonSerializer.Simple();
+
+               R1 r1 = new R1();
+               R2 r2 = new R2();
+               R3 r3 = new R3();
+               r1.r2 = r2;
+               r2.r3 = r3;
+               r3.r1 = r1;
+
+               // No recursion detection
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       assertTrue(msg.contains("It's recommended you use the 
SerializerContext.SERIALIZER_detectRecursions setting to help locate the 
loop."));
+               }
+
+               // Recursion detection, no ignore
+               s.setProperty(SERIALIZER_detectRecursions, true);
+               try {
+                       s.serialize(r1);
+                       fail("Exception expected!");
+               } catch (Exception e) {
+                       String msg = e.getLocalizedMessage();
+                       
assertTrue(msg.contains("[0]root:org.apache.juneau.json.CommonTest$R1"));
+                       
assertTrue(msg.contains("->[1]r2:org.apache.juneau.json.CommonTest$R2"));
+                       
assertTrue(msg.contains("->[2]r3:org.apache.juneau.json.CommonTest$R3"));
+                       
assertTrue(msg.contains("->[3]r1:org.apache.juneau.json.CommonTest$R1"));
+               }
+
+               s.setProperty(SERIALIZER_ignoreRecursions, true);
+               assertEquals("{name:'foo',r2:{name:'bar',r3:{name:'baz'}}}", 
s.serialize(r1));
+
+               // Make sure this doesn't blow up.
+               s.getSchemaSerializer().serialize(r1);
+       }
+
+       public static class R1 {
+               public String name = "foo";
+               public R2 r2;
+       }
+       public static class R2 {
+               public String name = "bar";
+               public R3 r3;
+       }
+       public static class R3 {
+               public String name = "baz";
+               public R1 r1;
+       }
+
+       
//====================================================================================================
+       // Basic bean
+       
//====================================================================================================
+       @Test
+       public void testBasicBean() throws Exception {
+               JsonSerializer s = new 
JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, 
false).setProperty(BEAN_sortProperties, true);
+
+               J a = new J();
+               a.setF1("J");
+               a.setF2(100);
+               a.setF3(true);
+               assertEquals("C1", "{f1:'J',f2:100,f3:true}", s.serialize(a));
+       }
+
+       public static class J {
+               private String f1 = null;
+               private int f2 = -1;
+               private boolean f3 = false;
+
+               public String getF1() {
+                       return this.f1;
+               }
+
+               public void setF1(String f1) {
+                       this.f1 = f1;
+               }
+
+               public int getF2() {
+                       return this.f2;
+               }
+
+               public void setF2(int f2) {
+                       this.f2 = f2;
+               }
+
+               public boolean isF3() {
+                       return this.f3;
+               }
+
+               public void setF3(boolean f3) {
+                       this.f3 = f3;
+               }
+
+               @Override /* Object */
+               public String toString() {
+                       return ("J(f1: " + this.getF1() + ", f2: " + 
this.getF2() + ")");
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
 
b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
new file mode 100644
index 0000000..a293831
--- /dev/null
+++ 
b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
@@ -0,0 +1,626 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.json;
+
+import static org.junit.Assert.*;
+
+import java.io.*;
+import java.util.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
+
+@RunWith(Parameterized.class)
+@SuppressWarnings({"javadoc"})
+public class JsonParserEdgeCasesTest {
+
+       @Parameterized.Parameters
+       public static Collection<Object[]> getPairs() {
+               return Arrays.asList(new Object[][] {
+                       { 0, "is_structure_500_nested_arrays", 
StringUtils.repeat(500, "[") + StringUtils.repeat(500, "]"), null },
+                       { 1, "ix_object_key_lone_2nd_surrogate", 
"7B225C7544464141223A307D"/*{"buDFAA":0}*/, null },
+                       { 2, "ix_string_1st_surrogate_but_2nd_missing", 
"5B225C7544414441225D"/*["buDADA"]*/, null },
+                       { 3, "ix_string_1st_valid_surrogate_2nd_invalid", 
"5B225C75443838385C7531323334225D"/*["buD888bu1234"]*/, null },
+                       { 4, "ix_string_incomplete_surrogate_and_escape_valid", 
"5B225C75443830305C6E225D"/*["buD800\n"]*/, null },
+                       { 5, "ix_string_incomplete_surrogate_pair", 
"5B225C754464316561225D"/*["buDd1ea"]*/, null },
+                       { 6, "ix_string_incomplete_surrogates_escape_valid", 
"5B225C75443830305C75443830305C6E225D"/*["buD800buD800\n"]*/, null },
+                       { 7, "ix_string_invalid_lonely_surrogate", 
"5B225C7564383030225D"/*["bud800"]*/, null },
+                       { 8, "ix_string_invalid_surrogate", 
"5B225C7564383030616263225D"/*["bud800abc"]*/, null },
+                       { 9, "ix_string_inverted_surrogates_U+1D11E", 
"5B225C75446431655C7544383334225D"/*["buDd1ebuD834"]*/, null },
+                       { 10, "ix_string_lone_second_surrogate", 
"5B225C7544464141225D"/*["buDFAA"]*/, null },
+                       { 11, "ix_string_not_in_unicode_range", 
"5B22F4BFBFBF225D"/*["[fffd][fffd][fffd][fffd]"]*/, "I/O exception occurred.  
exception=MalformedInputException" },
+                       { 12, "ix_string_truncated-utf-8", 
"5B22E0FF225D"/*["[fffd][fffd]"]*/, "I/O exception occurred.  
exception=MalformedInputException" },
+                       { 13, "ix_string_unicode_U+10FFFE_nonchar", 
"5B225C75444246465C7544464645225D"/*["buDBFFbuDFFE"]*/, null },
+                       { 14, "ix_string_unicode_U+1FFFE_nonchar", 
"5B225C75443833465C7544464645225D"/*["buD83FbuDFFE"]*/, null },
+                       { 15, "ix_string_unicode_U+FDD0_nonchar", 
"5B225C7546444430225D"/*["buFDD0"]*/, null },
+                       { 16, "ix_string_unicode_U+FFFE_nonchar", 
"5B225C7546464645225D"/*["buFFFE"]*/, null },
+                       { 17, "ix_string_UTF-16LE_with_BOM", 
"FFFE5B002200E90022005D00"/*[fffd][fffd][[0]"[0][fffd][0]"[0]][0]*/, null },
+                       { 18, "ix_string_UTF-8_invalid_sequence", 
"5B22E697A5D188FA225D"/*["[65e5][448][fffd]"]*/, null },
+                       { 19, "ix_structure_UTF-8_BOM_empty_object", 
"EFBBBF7B7D"/*[feff]{}*/, "Unrecognized syntax" },
+                       { 20, "n_array_1_true_without_comma", "[1 true]", 
"Expected ',' or ']'" },
+                       { 21, "n_array_colon_instead_of_comma", "[\"\": 1]", 
"Expected ',' or ']'" },
+                       { 22, "n_array_comma_after_close", "[\"\"],", 
"Remainder after parse: ','" },
+                       { 23, "n_array_comma_and_number", "[,1]", "Missing 
value detected" },
+                       { 24, "n_array_double_comma", "[1,,2]", "Missing value 
detected" },
+                       { 25, "n_array_double_extra_comma", "[\"x\",,]", null },
+                       { 26, "n_array_extra_close", "[\"x\"]]", "Remainder 
after parse: ']'" },
+                       { 27, "n_array_extra_comma", "[\"\",]", "Unexpected 
trailing comma in array" },
+                       { 28, "n_array_incomplete", "[\"x\"", "Expected ',' or 
']'" },
+                       { 29, "n_array_incomplete_invalid_value", "[x", 
"Unrecognized syntax" },
+                       { 30, "n_array_inner_array_no_comma", "[3[4]]", 
"Expected ',' or ']'" },
+                       { 31, "n_array_items_separated_by_semicolon", "[1:2]", 
"Expected ',' or ']'" },
+                       { 32, "n_array_just_comma", "[,]", null },
+                       { 33, "n_array_just_minus", "[-]", "Invalid number" },
+                       { 34, "n_array_missing_value", "[   , \"\"]", "Missing 
value detected" },
+                       { 35, "n_array_number_and_comma", "[1,]", "Unexpected 
trailing comma in array" },
+                       { 36, "n_array_number_and_several_commas", "[1,,]", 
null },
+                       { 37, "n_array_star_inside", "[*]", "Unrecognized 
syntax" },
+                       { 38, "n_array_unclosed", "[\"\"", "Expected ',' or 
']'" },
+                       { 39, "n_array_unclosed_trailing_comma", "[1,", 
"Unexpected trailing comma in array" },
+                       { 40, "n_array_unclosed_with_object_inside", "[{}", 
"Expected ',' or ']'" },
+                       { 41, "n_incomplete_false", "[fals]", "Unrecognized 
syntax" },
+                       { 42, "n_incomplete_null", "[nul]", "Unrecognized 
syntax" },
+                       { 43, "n_incomplete_true", "[tru]", "Unrecognized 
syntax" },
+                       { 44, "n_number_++", "[++1234]", "Unrecognized syntax" 
},
+                       { 45, "n_number_+1", "[+1]", "Unrecognized syntax" },
+                       { 46, "n_number_+Inf", "[+Inf]", "Unrecognized syntax" 
},
+                       { 47, "n_number_-01", "[-01]", "Invalid JSON number" },
+                       { 48, "n_number_-1.0.", "[-1.0.]", "Invalid number" },
+                       { 49, "n_number_-2.", "[-2.]", "Invalid JSON number" },
+                       { 50, "n_number_-NaN", "[-NaN]", null },
+                       { 51, "n_number_.-1", "[.-1]", "Invalid" },
+                       { 52, "n_number_.2e-3", "[.2e-3]", "Invalid JSON 
number" },
+                       { 53, "n_number_0.1.2", "[0.1.2]", "Invalid number" },
+                       { 54, "n_number_0.3e+", "[0.3e+]", "Invalid number" },
+                       { 55, "n_number_0.3e", "[0.3e]", "Invalid number" },
+                       { 56, "n_number_0.e1", "[0.e1]", "Invalid JSON number" 
},
+                       { 57, "n_number_0_capital_E+", "[0E+]", "Invalid 
number" },
+                       { 58, "n_number_0_capital_E", "[0E]", "Invalid number" 
},
+                       { 59, "n_number_0e+", "[0e+]", "Invalid number" },
+                       { 60, "n_number_0e", "[0e]", "Invalid number" },
+                       { 61, "n_number_1.0e+", "[1.0e+]", "Invalid number" },
+                       { 62, "n_number_1.0e-", "[1.0e-]", "Invalid number" },
+                       { 63, "n_number_1.0e", "[1.0e]", "Invalid number" },
+                       { 64, "n_number_1_000", "[1 000.0]", "Expected ',' or 
']'" },
+                       { 65, "n_number_1eE2", "[1eE2]", "Invalid number" },
+                       { 66, "n_number_2.e+3", "[2.e+3]", "Invalid JSON 
number" },
+                       { 67, "n_number_2.e-3", "[2.e-3]", "Invalid JSON 
number" },
+                       { 68, "n_number_2.e3", "[2.e3]", "Invalid JSON number" 
},
+                       { 69, "n_number_9.e+", "[9.e+]", null },
+                       { 70, "n_number_expression", "[1+2]", "Invalid number" 
},
+                       { 71, "n_number_hex_1_digit", "[0x1]", "Invalid JSON 
number" },
+                       { 72, "n_number_hex_2_digits", "[0x42]", "Invalid JSON 
number" },
+                       { 73, "n_number_Inf", "[Inf]", "Unrecognized syntax" },
+                       { 74, "n_number_infinity", "[Infinity]", "Unrecognized 
syntax" },
+                       { 75, "n_number_invalid+-", "[0e+-1]", "Invalid number" 
},
+                       { 76, "n_number_invalid-negative-real", 
"[-123.123foo]", "Expected ',' or ']'" },
+                       { 77, "n_number_minus_infinity", "[-Infinity]", null },
+                       { 78, "n_number_minus_sign_with_trailing_garbage", 
"[-foo]", "Invalid number" },
+                       { 79, "n_number_minus_space_1", "[- 1]", null },
+                       { 80, "n_number_NaN", "[NaN]", "Unrecognized syntax" },
+                       { 81, "n_number_neg_int_starting_with_zero", "[-012]", 
"Invalid JSON number" },
+                       { 82, "n_number_neg_real_without_int_part", "[-.123]", 
"Invalid JSON number" },
+                       { 83, "n_number_neg_with_garbage_at_end", "[-1x]", 
"Invalid number" },
+                       { 84, "n_number_real_garbage_after_e", "[1ea]", 
"Invalid number" },
+                       { 85, "n_number_real_without_fractional_part", "[1.]", 
"Invalid" },
+                       { 86, "n_number_starting_with_dot", "[.123]", "Invalid 
JSON number" },
+                       { 87, "n_number_U+FF11_fullwidth_digit_one", "[1]", 
"Unrecognized syntax" },
+                       { 88, "n_number_with_alpha", "[1.2a-3]", "Invalid 
number" },
+                       { 89, "n_number_with_alpha_char", 
"[1.8011670033376514H-308]", "Expected ',' or ']'" },
+                       { 90, "n_number_with_leading_zero", "[012]", "Invalid 
JSON number" },
+                       { 91, "n_object_bad_value", "[\"x\", truth]", 
"Unrecognized syntax" },
+                       { 92, "n_object_comma_instead_of_colon", "{\"x\", 
null}", "Could not find ':'" },
+                       { 93, "n_object_double_colon", "{\"x\"::\"b\"}", 
"Unrecognized syntax" },
+                       { 94, "n_object_garbage_at_end", "{\"a\":\"a\" 123}", 
"Could not find '}'" },
+                       { 95, "n_object_key_with_single_quotes", "{key: 
'value'}", "Unquoted attribute detected" },
+                       { 96, "n_object_missing_colon", "{\"a\" b}", "Could not 
find ':'" },
+                       { 97, "n_object_missing_key", "{:\"b\"}", "Unquoted 
attribute detected" },
+                       { 98, "n_object_missing_semicolon", "{\"a\" \"b\"}", 
"Could not find ':'" },
+                       { 99, "n_object_missing_value", "{\"a\":", 
"Unrecognized syntax" },
+                       { 100, "n_object_no-colon", "{\"a\"", "Could not find 
':'" },
+                       { 101, "n_object_non_string_key", "{1:1}", "Unquoted 
attribute detected" },
+                       { 102, 
"n_object_non_string_key_but_huge_number_instead", "{9999E9999:1}", "Unquoted 
attribute detected" },
+                       { 103, "n_object_repeated_null_null", 
"{null:null,null:null}", "Unquoted attribute detected" },
+                       { 104, "n_object_several_trailing_commas", 
"{\"id\":0,,,,,}", null },
+                       { 105, "n_object_single_quote", "{'a':0}", "Invalid 
quote character" },
+                       { 106, "n_object_trailing_comma", "{\"id\":0,}", 
"Unexpected '}' found" },
+                       { 107, "n_object_trailing_comment", 
"{\"a\":\"b\"}/**/", "Javascript comment detected" },
+                       { 108, "n_object_trailing_comment_open", 
"{\"a\":\"b\"}/**//", null },
+                       { 109, "n_object_trailing_comment_slash_open", 
"{\"a\":\"b\"}//", "Javascript comment detected" },
+                       { 110, 
"n_object_trailing_comment_slash_open_incomplete", "{\"a\":\"b\"}/", null },
+                       { 111, "n_object_two_commas_in_a_row", 
"{\"a\":\"b\",,\"c\":\"d\"}", null },
+                       { 112, "n_object_unquoted_key", "{a: \"b\"}", "Unquoted 
attribute detected" },
+                       { 113, "n_object_unterminated-value", "{\"a\":\"a", 
null },
+                       { 114, "n_object_with_single_string", "{ \"foo\" : 
\"bar\", \"a\" }", "Could not find ':'" },
+                       { 115, "n_object_with_trailing_garbage", 
"{\"a\":\"b\"}#", "Remainder after parse" },
+                       { 116, "n_single_space", "", "Empty input" },
+                       { 117, "n_string_single_doublequote", "\"", null },
+                       { 118, "n_string_single_quote", "['single quote']", 
"Invalid quote character" },
+                       { 119, "n_string_single_string_no_double_quotes", 
"abc", "Unrecognized syntax" },
+                       { 120, "n_string_with_trailing_garbage", "\"\"x", 
"Remainder after parse" },
+                       { 121, "n_structure_<.>", "<.>", "Unrecognized syntax" 
},
+                       { 122, "n_structure_<null>", "[<null>]", "Unrecognized 
syntax" },
+                       { 123, "n_structure_array_trailing_garbage", "[1]x", 
"Remainder after parse" },
+                       { 124, "n_structure_array_with_extra_array_close", 
"[1]]", "Remainder after parse" },
+                       { 125, "n_structure_array_with_unclosed_string", 
"[\"asd]", null },
+                       { 126, "n_structure_capitalized_True", "[True]", 
"Unrecognized syntax" },
+                       { 127, "n_structure_close_unopened_array", "1]", 
"Remainder after parse" },
+                       { 128, "n_structure_comma_instead_of_closing_brace", 
"{\"x\": true,", null },
+                       { 129, "n_structure_double_array", "[][]", "Remainder 
after parse" },
+                       { 130, "n_structure_end_array", "]", null },
+                       { 131, "n_structure_lone-open-bracket", "[", "Expected 
one of the following characters: {,[," },
+                       { 132, "n_structure_no_data", "", "Empty input" },
+                       { 133, "n_structure_null-byte-outside-string", "[]", 
"Unrecognized syntax" },
+                       { 134, "n_structure_number_with_trailing_garbage", 
"2@", "Remainder after parse" },
+                       { 135, "n_structure_object_followed_by_closing_object", 
"{}}", "Remainder after parse" },
+                       { 136, "n_structure_object_unclosed_no_value", 
"{\"\":", "Unrecognized syntax" },
+                       { 137, "n_structure_object_with_comment", 
"{\"a\":/*comment*/\"b\"}", "Javascript comment detected" },
+                       { 138, "n_structure_object_with_trailing_garbage", 
"{\"a\": true} \"x\"", "Remainder after parse" },
+                       { 139, "n_structure_open_array_apostrophe", "['", null 
},
+                       { 140, "n_structure_open_array_comma", "[,", null },
+                       { 141, "n_structure_open_array_open_object", "[{", null 
},
+                       { 142, "n_structure_open_array_open_string", "[\"a", 
null },
+                       { 143, "n_structure_open_array_string", "[\"a\"", 
"Expected ',' or ']'" },
+                       { 144, "n_structure_open_object", "{", null },
+                       { 145, "n_structure_open_object_close_array", "{]", 
null },
+                       { 146, "n_structure_open_object_comma", "{,", null },
+                       { 147, "n_structure_open_object_open_array", "{[", null 
},
+                       { 148, "n_structure_open_object_open_string", "{\"a", 
null },
+                       { 149, 
"n_structure_open_object_string_with_apostrophes", "{'a'", null },
+                       { 150, "n_structure_single_star", "*", "Unrecognized 
syntax" },
+                       { 151, "n_structure_trailing_#", "{\"a\":\"b\"}#{}", 
"Remainder after parse" },
+                       { 152, "n_structure_unclosed_array", "[1", "Expected 
',' or ']" },
+                       { 153, "n_structure_unclosed_array_partial_null", "[ 
false, nul", "Unrecognized syntax" },
+                       { 154, "n_structure_unclosed_array_unfinished_false", 
"[ true, fals", "Unrecognized syntax" },
+                       { 155, "n_structure_unclosed_array_unfinished_true", "[ 
false, tru", "Unrecognized syntax" },
+                       { 156, "n_structure_unclosed_object", 
"{\"asd\":\"asd\"", "Could not find '}'" },
+                       { 157, "ns_structure_100000_opening_arrays", 
StringUtils.repeat(100000, "["), "Depth too deep" },
+                       { 158, "ns_structure_open_array_object", 
StringUtils.repeat(50000, "[{\"\":"), "Depth too deep" },
+                       { 159, "nx_array_a_invalid_utf8", 
"5B61E55D"/*[a[fffd]]*/, null },
+                       { 160, "nx_array_invalid_utf8", "5BFF5D"/*[[fffd]]*/, 
null },
+                       { 161, "nx_array_newlines_unclosed", 
"5B2261222C0A340A2C312C"/*["a",[a]4[a],1,*/, null },
+                       { 162, "nx_array_spaces_vertical_tab_formfeed", 
"5B220B61225C665D"/*["[b]a"\f]*/, null },
+                       { 163, "nx_array_unclosed_with_new_lines", 
"5B312C0A310A2C31"/*[1,[a]1[a],1*/, null },
+                       { 164, "nx_multidigit_number_then_00", 
"31323300"/*123[0]*/, null },
+                       { 165, "nx_number_invalid-utf-8-in-bigger-int", 
"5B313233E55D"/*[123[fffd]]*/, null },
+                       { 166, "nx_number_invalid-utf-8-in-exponent", 
"5B316531E55D"/*[1e1[fffd]]*/, null },
+                       { 167, "nx_number_invalid-utf-8-in-int", 
"5B30E55D0A"/*[0[fffd]][a]*/, null },
+                       { 168, "nx_number_real_with_invalid_utf8_after_e", 
"5B3165E55D"/*[1e[fffd]]*/, null },
+                       { 169, "nx_object_bracket_key", 
"7B5B3A202278227D0A"/*{[: "x"}[a]*/, null },
+                       { 170, "nx_object_emoji", 
"7BF09F87A8F09F87AD7D"/*{[d83c][dde8][d83c][dded]}*/, null },
+                       { 171, "nx_object_pi_in_key_and_trailing_comma", 
"7B22B9223A2230222C7D"/*{"[fffd]":"0",}*/, null },
+                       { 172, "nx_string_1_surrogate_then_escape u", 
"5B225C75443830305C75225D"/*["buD800bu"]*/, "Invalid Unicode escape sequence in 
string" },
+                       { 173, "nx_string_1_surrogate_then_escape u1", 
"5B225C75443830305C7531225D"/*["buD800bu1"]*/, "Invalid Unicode escape sequence 
in string" },
+                       { 174, "nx_string_1_surrogate_then_escape u1x", 
"5B225C75443830305C753178225D"/*["buD800bu1x"]*/, "Invalid Unicode escape 
sequence in string" },
+                       { 175, "nx_string_1_surrogate_then_escape", 
"5B225C75443830305C225D"/*["buD800\"]*/, null },
+                       { 176, "nx_string_accentuated_char_no_quotes", 
"5BC3A95D"/*[[e9]]*/, "Unrecognized syntax" },
+                       { 177, "nx_string_backslash_00", 
"5B225C00225D"/*["\[0]"]*/, null },
+                       { 178, "nx_string_escape_x", 
"5B225C783030225D"/*["\x00"]*/, "Invalid escape sequence in string" },
+                       { 179, "nx_string_escaped_backslash_bad", 
"5B225C5C5C225D"/*["\\\"]*/, null },
+                       { 180, "nx_string_escaped_ctrl_char_tab", 
"5B225C09225D"/*["\[9]"]*/, null },
+                       { 181, "nx_string_escaped_emoji", 
"5B225CF09F8C80225D"/*["\[d83c][df00]"]*/, "Invalid escape sequence in string" 
},
+                       { 182, "nx_string_incomplete_escape", 
"5B225C225D"/*["\"]*/, null },
+                       { 183, "nx_string_incomplete_escaped_character", 
"5B225C75303041225D"/*["bu00A"]*/, "Invalid Unicode escape sequence in string" 
},
+                       { 184, "nx_string_incomplete_surrogate", 
"5B225C75443833345C754464225D"/*["buD834buDd"]*/, "Invalid Unicode escape 
sequence in string" },
+                       { 185, "nx_string_incomplete_surrogate_escape_invalid", 
"5B225C75443830305C75443830305C78225D"/*["buD800buD800\x"]*/, "Invalid escape 
sequence" },
+                       { 186, "nx_string_invalid-utf-8-in-escape", 
"5B225C75E5225D"/*["bu[fffd]"]*/, null },
+                       { 187, "nx_string_invalid_backslash_esc", 
"5B225C61225D"/*["\a"]*/, "Invalid escape sequence" },
+                       { 188, "nx_string_invalid_unicode_escape", 
"5B225C7571717171225D"/*["buqqqq"]*/, "Invalid Unicode escape sequence in 
string" },
+                       { 189, "nx_string_invalid_utf-8", 
"5B22FF225D"/*["[fffd]"]*/, "MalformedInputException" },
+                       { 190, "nx_string_invalid_utf8_after_escape", 
"5B225CE5225D"/*["\[fffd]"]*/, null },
+                       { 191, "nx_string_iso_latin_1", 
"5B22E9225D"/*["[fffd]"]*/, "MalformedInputException" },
+                       { 192, "nx_string_leading_uescaped_thinspace", 
"5B5C753030323022617364225D"/*[bu0020"asd"]*/, "Unrecognized syntax" },
+                       { 193, "nx_string_lone_utf8_continuation_byte", 
"5B2281225D"/*["[fffd]"]*/, "MalformedInputException" },
+                       { 194, "nx_string_no_quotes_with_bad_escape", 
"5B5C6E5D"/*[\n]*/, "Unrecognized syntax" },
+                       { 195, "nx_string_overlong_sequence_2_bytes", 
"5B22C0AF225D"/*["[fffd][fffd]"]*/, "MalformedInputException" },
+                       { 196, "nx_string_overlong_sequence_6_bytes", 
"5B22FC83BFBFBFBF225D"/*["[fffd][fffd][fffd][fffd][fffd][fffd]"]*/, 
"MalformedInputException" },
+                       { 197, "nx_string_overlong_sequence_6_bytes_null", 
"5B22FC8080808080225D"/*["[fffd][fffd][fffd][fffd][fffd][fffd]"]*/, 
"MalformedInputException" },
+                       { 198, "nx_string_start_escape_unclosed", 
"5B225C"/*["\*/, null },
+                       { 199, "nx_string_unescaped_crtl_char", 
"5B22610061225D"/*["a[0]a"]*/, null },
+                       { 200, "nx_string_unescaped_newline", 
"5B226E65770A6C696E65225D"/*["new[a]line"]*/, null },
+                       { 201, "nx_string_unescaped_tab", 
"5B2209225D"/*["[9]"]*/, null },
+                       { 202, "nx_string_unicode_CapitalU", 
"225C554136364422"/*"\UA66D"*/, "Invalid escape sequence" },
+                       { 203, "ix_string_UTF8_surrogate_U+D800", 
"5B22EDA080225D"/*["[fffd]"]*/, null },  // Succeeds on Java 8, fails on Java 6 
& 7.
+                       { 204, "nx_structure_ascii-unicode-identifier", 
"61C3A5"/*a[e5]*/, "Unrecognized syntax" },
+                       { 205, "nx_structure_incomplete_UTF8_BOM", 
"EFBB7B7D"/*[fffd]{}*/, null },
+                       { 206, "nx_structure_lone-invalid-utf-8", 
"E5"/*[fffd]*/, null },
+                       { 207, "nx_structure_open_open", 
"5B225C7B5B225C7B5B225C7B5B225C7B"/*["\{["\{["\{["\{*/, "Invalid escape 
sequence" },
+                       { 208, "nx_structure_single_point", "E9"/*[fffd]*/, 
null },
+                       { 209, "nx_structure_U+2060_word_joined", 
"5BE281A05D"/*[[2060]]*/, "Unrecognized syntax" },
+                       { 210, "nx_structure_uescaped_LF_before_string", 
"5B5C753030304122225D"/*[bu000A""]*/, "Unrecognized syntax" },
+                       { 211, "nx_structure_unicode-identifier", 
"C3A5"/*[e5]*/, "Unrecognized syntax" },
+                       { 212, "nx_structure_UTF8_BOM_no_data", 
"EFBBBF"/*[feff]*/, "Unrecognized syntax" },
+                       { 213, "nx_structure_whitespace_formfeed", 
"5B0C5D"/*[[c]]*/, "Unrecognized syntax" },
+                       { 214, "nx_structure_whitespace_U+2060_word_joiner", 
"5BE281A05D"/*[[2060]]*/, "Unrecognized syntax" },
+                       { 215, "y_array_arraysWithSpaces", "[[]   ]", null },
+                       { 216, "y_array_empty-string", "[\"\"]", null },
+                       { 217, "y_array_empty", "[]", null },
+                       { 218, "y_array_ending_with_newline", "[\"a\"]", null },
+                       { 219, "y_array_false", "[false]", null },
+                       { 220, "y_array_heterogeneous", "[null, 1, \"1\", {}]", 
null },
+                       { 221, "y_array_null", "[null]", null },
+                       { 222, "y_array_with_leading_space", "[1]", null },
+                       { 223, "y_array_with_several_null", 
"[1,null,null,null,2]", null },
+                       { 224, "y_array_with_trailing_space", "[2]", null },
+                       { 225, "y_number", "[123e65]", null },
+                       { 226, "y_number_0e+1", "[0e+1]", null },
+                       { 227, "y_number_0e1", "[0e1]", null },
+                       { 228, "y_number_after_space", "[ 4]", null },
+                       { 229, "y_number_double_close_to_zero", 
"[-0.000000000000000000000000000000000000000000000000000000000000000000000000000001]",
 null },
+                       { 230, "y_number_double_huge_neg_exp", 
"[123.456e-789]", null },
+                       { 231, "y_number_huge_exp", 
"[0.4e00669999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999969999999006]",
 null },
+                       { 232, "y_number_int_with_exp", "[20e1]", null },
+                       { 233, "y_number_minus_zero", "[-0]", null },
+                       { 234, "y_number_neg_int_huge_exp", "[-1e+9999]", null 
},
+                       { 235, "y_number_negative_int", "[-123]", null },
+                       { 236, "y_number_negative_one", "[-1]", null },
+                       { 237, "y_number_negative_zero", "[-0]", null },
+                       { 238, "y_number_pos_double_huge_exp", "[1.5e+9999]", 
null },
+                       { 239, "y_number_real_capital_e", "[1E22]", null },
+                       { 240, "y_number_real_capital_e_neg_exp", "[1E-2]", 
null },
+                       { 241, "y_number_real_capital_e_pos_exp", "[1E+2]", 
null },
+                       { 242, "y_number_real_exponent", "[123e45]", null },
+                       { 243, "y_number_real_fraction_exponent", 
"[123.456e78]", null },
+                       { 244, "y_number_real_neg_exp", "[1e-2]", null },
+                       { 245, "y_number_real_neg_overflow", 
"[-123123e100000]", null },
+                       { 246, "y_number_real_pos_exponent", "[1e+2]", null },
+                       { 247, "y_number_real_pos_overflow", "[123123e100000]", 
null },
+                       { 248, "y_number_real_underflow", "[123e-10000000]", 
null },
+                       { 249, "y_number_simple_int", "[123]", null },
+                       { 250, "y_number_simple_real", "[123.456789]", null },
+                       { 251, "y_number_too_big_neg_int", 
"[-123123123123123123123123123123]", null },
+                       { 252, "y_number_too_big_pos_int", 
"[100000000000000000000]", null },
+                       { 253, "y_number_very_big_negative_int", 
"[-237462374673276894279832749832423479823246327846]", null },
+                       { 254, "y_object", "{\"asd\":\"sdf\", 
\"dfg\":\"fgh\"}", null },
+                       { 255, "y_object_basic", "{\"asd\":\"sdf\"}", null },
+                       { 256, "y_object_duplicated_key", 
"{\"a\":\"b\",\"a\":\"c\"}", null },
+                       { 257, "y_object_duplicated_key_and_value", 
"{\"a\":\"b\",\"a\":\"b\"}", null },
+                       { 258, "y_object_empty", "{}", null },
+                       { 259, "y_object_empty_key", "{\"\":0}", null },
+                       { 260, "y_object_extreme_numbers", "{ \"min\": 
-1.0e+28, \"max\": 1.0e+28 }", null },
+                       { 261, "y_object_long_strings", "{\"x\":[{\"id\": 
\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}], \"id\": 
\"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\"}", null },
+                       { 262, "y_object_simple", "{\"a\":[]}", null },
+                       { 263, "y_string_comments", "[\"a/*b*/c/*d//e\"]", null 
},
+                       { 264, "y_string_in_array", "[\"asd\"]", null },
+                       { 265, "y_string_in_array_with_leading_space", "[ 
\"asd\"]", null },
+                       { 266, "y_string_simple_ascii", "[\"asd \"]", null },
+                       { 267, "y_string_space", "\" \"", null },
+                       { 268, "y_structure_lonely_false", "false", null },
+                       { 269, "y_structure_lonely_int", "42", null },
+                       { 270, "y_structure_lonely_negative_real", "-0.1", null 
},
+                       { 271, "y_structure_lonely_null", "null", null },
+                       { 272, "y_structure_lonely_string", "\"asd\"", null },
+                       { 273, "y_structure_lonely_true", "true", null },
+                       { 274, "y_structure_string_empty", "\"\"", null },
+                       { 275, "y_structure_true_in_array", "[true]", null },
+                       { 276, "y_structure_whitespace_array", "[]", null },
+                       { 277, "yx_array_with_1_and_newline", 
"5B310A5D"/*[1[a]]*/, null },
+                       { 278, "yx_object_escaped_null_in_key", 
"7B22666F6F5C7530303030626172223A2034327D"/*{"foobu0000bar": 42}*/, null },
+                       { 279, "yx_object_string_unicode", 
"7B227469746C65223A225C75303431665C75303433655C75303433625C75303434325C75303433655C75303434305C7530343330205C75303431375C75303433355C75303433635C75303433625C75303433355C75303433615C75303433655C75303433665C753034333022207D"/*{"title":"bu041fbu043ebu043bbu0442bu043ebu0440bu0430
 bu0417bu0435bu043cbu043bbu0435bu043abu043ebu043fbu0430" }*/, null },
+                       { 280, "yx_object_with_newlines", 
"7B0A2261223A202262220A7D"/*{[a]"a": "b"[a]}*/, null },
+                       { 281, "yx_string_1_2_3_bytes_UTF-8_sequences", 
"5B225C75303036305C75303132615C7531324142225D"/*["bu0060bu012abu12AB"]*/, null 
},
+                       { 282, "yx_string_accepted_surrogate_pair", 
"5B225C75443830315C7564633337225D"/*["buD801budc37"]*/, null },
+                       { 283, "yx_string_accepted_surrogate_pairs", 
"5B225C75643833645C75646533395C75643833645C7564633864225D"/*["bud83dbude39bud83dbudc8d"]*/,
 null },
+                       { 284, "yx_string_allowed_escapes", 
"5B225C225C5C5C2F5C625C665C6E5C725C74225D"/*["\"\\\/\b\f\n\r\t"]*/, null },
+                       { 285, "yx_string_backslash_and_u_escaped_zero", 
"5B225C5C7530303030225D"/*["\bu0000"]*/, null },
+                       { 286, "yx_string_backslash_doublequotes", 
"5B225C22225D"/*["\""]*/, null },
+                       { 287, "yx_string_double_escape_a", 
"5B225C5C61225D"/*["\\a"]*/, null },
+                       { 288, "yx_string_double_escape_n", 
"5B225C5C6E225D"/*["\\n"]*/, null },
+                       { 289, "yx_string_escaped_control_character", 
"5B225C7530303132225D"/*["bu0012"]*/, null },
+                       { 290, "yx_string_escaped_noncharacter", 
"5B225C7546464646225D"/*["buFFFF"]*/, null },
+                       { 291, "yx_string_last_surrogates_1_and_2", 
"5B225C75444246465C7544464646225D"/*["buDBFFbuDFFF"]*/, null },
+                       { 292, "yx_string_nbsp_uescaped", 
"5B226E65775C75303041306C696E65225D"/*["newbu00A0line"]*/, null },
+                       { 293, "yx_string_nonCharacterInUTF-8_U+10FFFF", 
"5B22F48FBFBF225D"/*["[dbff][dfff]"]*/, null },
+                       { 294, "yx_string_nonCharacterInUTF-8_U+1FFFF", 
"5B22F09BBFBF225D"/*["[d82f][dfff]"]*/, null },
+                       { 295, "yx_string_nonCharacterInUTF-8_U+FFFF", 
"5B22EFBFBF225D"/*["[ffff]"]*/, null },
+                       { 296, "yx_string_null_escape", 
"5B225C7530303030225D"/*["bu0000"]*/, null },
+                       { 297, "yx_string_one-byte-utf-8", 
"5B225C7530303263225D"/*["bu002c"]*/, null },
+                       { 298, "yx_string_pi", "5B22CF80225D"/*["[3c0]"]*/, 
null },
+                       { 299, 
"yx_string_surrogates_U+1D11E_MUSICAL_SYMBOL_G_CLEF", 
"5B225C75443833345C7544643165225D"/*["buD834buDd1e"]*/, null },
+                       { 300, "yx_string_three-byte-utf-8", 
"5B225C7530383231225D"/*["bu0821"]*/, null },
+                       { 301, "yx_string_two-byte-utf-8", 
"5B225C7530313233225D"/*["bu0123"]*/, null },
+                       { 302, "yx_string_u+2028_line_sep", 
"5B22E280A8225D"/*["[2028]"]*/, null },
+                       { 303, "yx_string_u+2029_par_sep", 
"5B22E280A9225D"/*["[2029]"]*/, null },
+                       { 304, "yx_string_uEscape", 
"5B225C75303036315C75333061665C75333045415C7533306239225D"/*["bu0061bu30afbu30EAbu30b9"]*/,
 null },
+                       { 305, "yx_string_uescaped_newline", 
"5B226E65775C75303030416C696E65225D"/*["newbu000Aline"]*/, null },
+                       { 306, "yx_string_unescaped_char_delete", 
"5B227F225D"/*["[7f]"]*/, null },
+                       { 307, "yx_string_unicode", 
"5B225C7541363644225D"/*["buA66D"]*/, null },
+                       { 308, "yx_string_unicode_2", 
"5B22E28D82E388B4E28D82225D"/*["[2342][3234][2342]"]*/, null },
+                       { 309, "yx_string_unicode_escaped_double_quote", 
"5B225C7530303232225D"/*["bu0022"]*/, null },
+                       { 310, "yx_string_unicode_U+200B_ZERO_WIDTH_SPACE", 
"5B225C7532303042225D"/*["bu200B"]*/, null },
+                       { 311, "yx_string_unicode_U+2064_invisible_plus", 
"5B225C7532303634225D"/*["bu2064"]*/, null },
+                       { 312, "yx_string_unicodeEscapedBackslash", 
"5B225C7530303543225D"/*["bu005C"]*/, null },
+                       { 313, "yx_string_utf16BE_no_BOM", 
"005B002200E90022005D"/*[0][[0]"[0][fffd][0]"[0]]*/, null },
+                       { 314, "yx_string_utf16LE_no_BOM", 
"5B002200E90022005D00"/*[[0]"[0][fffd][0]"[0]][0]*/, null },
+                       { 315, "yx_string_utf8", 
"5B22E282ACF09D849E225D"/*["[20ac][d834][dd1e]"]*/, null },
+                       { 316, "yx_string_with_del_character", 
"5B22617F61225D"/*["a[7f]a"]*/, null },
+                       { 317, "yx_structure_trailing_newline", 
"5B2261225D0A"/*["a"][a]*/, null },
+               });
+       }
+
+       private final String name, errorText, jsonReadable;
+       private final Object json;
+       private final char expected;
+       public boolean debug = false;
+
+       public JsonParserEdgeCasesTest(Integer testNum, String name, String 
json, String errorText) throws Exception {
+               this.name = name;
+               this.json = name.charAt(1) == 'x' ? StringUtils.fromHex(json) : 
json;
+               this.jsonReadable = name.charAt(1) == 'x' ? 
StringUtils.fromHexToUTF8(json) : json;
+               this.expected = name.charAt(0);
+               this.errorText = errorText;
+       }
+
+       @Test
+       public void testStrict() throws Exception {
+               Parser p = JsonParser.DEFAULT_STRICT;
+               if (name.contains("utf16LE"))
+                       p = 
p.clone().setProperty(ParserContext.PARSER_inputStreamCharset, "UTF-16LE");
+               else if (name.contains("utf16BE"))
+                       p = 
p.clone().setProperty(ParserContext.PARSER_inputStreamCharset, "UTF-16BE");
+
+               // 'y' tests should always succeed.
+               if (expected == 'y') {
+                       p.parse(json, Object.class);
+
+               // 'n' tests should always fail.
+               } else if (expected == 'n') {
+                       try {
+                               p.parse(json, Object.class);
+                               fail("ParseException expected.  Test="+name+", 
Input=" + jsonReadable);
+                       } catch (ParseException e) {
+                               if (errorText != null)
+                                       assertTrue("Got ParseException but 
didn't contain expected text '"+errorText+"'.  Test="+name+", Input=" + 
jsonReadable + ", Message=" + e.getRootCause().getMessage(), 
e.getRootCause().getMessage().contains(errorText));
+                       } catch (AssertionError e) {
+                               throw e;
+                       } catch (Throwable t) {
+                               fail("Expected ParseException.  Test="+name+", 
Input=" + jsonReadable + ", Exception=" + t.getClass().getName() + "," 
+t.getLocalizedMessage());
+                       }
+
+               // 'i' tests may or may not fail, but should through a 
ParseException and not kill the JVM.
+               } else if (expected == 'i') {
+                       try {
+                               p.parse(json, Object.class);
+                       } catch (ParseException e) {
+                               if (errorText != null)
+                                       assertTrue("Got ParseException but 
didn't contain expected text '"+errorText+"'.  Test="+name+", Input=" + 
jsonReadable + ", Message=" + e.getRootCause().getMessage(), 
e.getRootCause().getMessage().contains(errorText));
+                       } catch (Throwable t) {
+                               fail("Expected ParseException.  Test="+name+", 
Input=" + jsonReadable + ", Exception=" + t.getClass().getName() + "," 
+t.getLocalizedMessage());
+                       }
+               }
+       }
+
+       @Test
+       public void testLax() throws Exception {
+               Parser p = JsonParser.DEFAULT;
+               if (name.contains("utf16LE"))
+                       p = 
p.clone().setProperty(ParserContext.PARSER_inputStreamCharset, "UTF-16LE");
+               else if (name.contains("utf16BE"))
+                       p = 
p.clone().setProperty(ParserContext.PARSER_inputStreamCharset, "UTF-16BE");
+
+               // 'y' tests should always succeed.
+               if (expected == 'y') {
+                       p.parse(json, Object.class);
+
+               // 'n' tests may or may not fail for lax parser.
+               } else if (expected == 'n') {
+                       try {
+                               p.parse(json, Object.class);
+                               //fail("ParseException expected.  
Test="+name+", Input=" + json);
+                       } catch (ParseException e) {
+                               if (errorText != null)
+                                       assertTrue("Got ParseException but 
didn't contain expected text '"+errorText+"'.  Test="+name+", Input=" + 
jsonReadable + ", Message=" + e.getRootCause().getMessage(), 
e.getRootCause().getMessage().contains(errorText));
+                       } catch (AssertionError e) {
+                               throw e;
+                       } catch (Throwable t) {
+                               fail("Expected ParseException.  Test="+name+", 
Input=" + jsonReadable + ", Exception=" + t.getClass().getName() + "," 
+t.getLocalizedMessage());
+                       }
+
+               // 'i' tests may or may not fail, but should through a 
ParseException and not kill the JVM.
+               } else if (expected == 'i') {
+                       try {
+                               p.parse(json, Object.class);
+                       } catch (ParseException e) {
+                               if (errorText != null)
+                                       assertTrue("Got ParseException but 
didn't contain expected text '"+errorText+"'.  Test="+name+", Input=" + 
jsonReadable + ", Message=" + e.getRootCause().getMessage(), 
e.getRootCause().getMessage().contains(errorText));
+                       } catch (Throwable t) {
+                               fail("Expected ParseException.  Test="+name+", 
Input=" + jsonReadable + ", Exception=" + t.getClass().getName() + "," 
+t.getLocalizedMessage());
+                       }
+               }
+       }
+
+
+       public static void main(String[] generateParams) throws Exception {
+               File f = new 
File("src/test/resources/org/apache/juneau/json/jsonTestSuite");
+               int i = 0;
+               String pattern = "\n\t\t'{' {0}, \"{1}\", {2}, {3} '}',";
+               StringBuilder sb = new StringBuilder();
+               for (File fc : f.listFiles()) {
+                       String n = fc.getName();
+                       if (n.endsWith(".json")) {
+                               n = n.replaceAll("\\.json", "");
+                               String contents = specials.get(n);
+                               if (contents == null) {
+                                       if (n.charAt(1) == 'x')
+                                               contents = '"' + 
StringUtils.toHex(IOUtils.readBytes(fc)) + '"' + "/*" + 
StringUtils.decodeHex(IOUtils.read(fc)).replaceAll("\\\\u", "bu") + "*/";
+                                       else
+                                               contents = '"' + 
IOUtils.read(fc).replaceAll("\"", "\\\\\"").trim() + '"';
+                               }
+                               String errorText = errors.get(n);
+                               if (errorText != null)
+                                       errorText = '"' + errorText + '"';
+                               
sb.append(java.text.MessageFormat.format(pattern, i++, 
fc.getName().replace(".json", ""), contents, errorText));
+                       }
+               }
+               System.err.println(sb);
+       }
+
+       public static final Map<String,String> specials = new 
HashMap<String,String>();
+       static {
+               specials.put("is_structure_500_nested_arrays", 
"StringUtils.repeat(500, \"[\") + StringUtils.repeat(500, \"]\")");
+               specials.put("ns_structure_100000_opening_arrays", 
"StringUtils.repeat(100000, \"[\")");
+               specials.put("ns_structure_open_array_object", 
"StringUtils.repeat(50000, \"[{\\\"\\\":\")");
+       }
+
+       public static final Map<String,String> errors = new 
HashMap<String,String>();
+       static {
+               errors.put(/*11*/ "ix_string_not_in_unicode_range", "I/O 
exception occurred.  exception=MalformedInputException");
+               errors.put(/*12*/ "ix_string_truncated-utf-8", "I/O exception 
occurred.  exception=MalformedInputException");
+               errors.put(/*19*/ "ix_structure_UTF-8_BOM_empty_object", 
"Unrecognized syntax");
+               errors.put(/*20*/ "n_array_1_true_without_comma", "Expected ',' 
or ']'");
+               errors.put(/*21*/ "n_array_colon_instead_of_comma", "Expected 
',' or ']'");
+               errors.put(/*22*/ "n_array_comma_after_close", "Remainder after 
parse: ','");
+               errors.put(/*23*/ "n_array_comma_and_number", "Missing value 
detected");
+               errors.put(/*24*/ "n_array_double_comma", "Missing value 
detected");
+               errors.put(/*26*/ "n_array_extra_close", "Remainder after 
parse: ']'");
+               errors.put(/*27*/ "n_array_extra_comma", "Unexpected trailing 
comma in array");
+               errors.put(/*28*/ "n_array_incomplete", "Expected ',' or ']'");
+               errors.put(/*29*/ "n_array_incomplete_invalid_value", 
"Unrecognized syntax");
+               errors.put(/*30*/ "n_array_inner_array_no_comma", "Expected ',' 
or ']'");
+               errors.put(/*31*/ "n_array_items_separated_by_semicolon", 
"Expected ',' or ']'");
+               errors.put(/*33*/ "n_array_just_minus", "Invalid number");
+               errors.put(/*34*/ "n_array_missing_value", "Missing value 
detected");
+               errors.put(/*35*/ "n_array_number_and_comma", "Unexpected 
trailing comma in array");
+               errors.put(/*37*/ "n_array_star_inside", "Unrecognized syntax");
+               errors.put(/*38*/ "n_array_unclosed", "Expected ',' or ']'");
+               errors.put(/*39*/ "n_array_unclosed_trailing_comma", 
"Unexpected trailing comma in array");
+               errors.put(/*40*/ "n_array_unclosed_with_object_inside", 
"Expected ',' or ']'");
+               errors.put(/*41*/ "n_incomplete_false", "Unrecognized syntax");
+               errors.put(/*42*/ "n_incomplete_null", "Unrecognized syntax");
+               errors.put(/*43*/ "n_incomplete_true", "Unrecognized syntax");
+               errors.put(/*44*/ "n_number_++", "Unrecognized syntax");
+               errors.put(/*45*/ "n_number_+1", "Unrecognized syntax");
+               errors.put(/*46*/ "n_number_+Inf", "Unrecognized syntax");
+               errors.put(/*47*/ "n_number_-01", "Invalid JSON number");
+               errors.put(/*48*/ "n_number_-1.0.", "Invalid number");
+               errors.put(/*49*/ "n_number_-2.", "Invalid JSON number");
+               errors.put(/*51*/ "n_number_.-1", "Invalid");
+               errors.put(/*52*/ "n_number_.2e-3", "Invalid JSON number");
+               errors.put(/*53*/ "n_number_0.1.2", "Invalid number");
+               errors.put(/*54*/ "n_number_0.3e+", "Invalid number");
+               errors.put(/*55*/ "n_number_0.3e", "Invalid number");
+               errors.put(/*56*/ "n_number_0.e1", "Invalid JSON number");
+               errors.put(/*57*/ "n_number_0_capital_E+", "Invalid number");
+               errors.put(/*58*/ "n_number_0_capital_E", "Invalid number");
+               errors.put(/*59*/ "n_number_0e+", "Invalid number");
+               errors.put(/*60*/ "n_number_0e", "Invalid number");
+               errors.put(/*61*/ "n_number_1.0e+", "Invalid number");
+               errors.put(/*62*/ "n_number_1.0e-", "Invalid number");
+               errors.put(/*63*/ "n_number_1.0e", "Invalid number");
+               errors.put(/*64*/ "n_number_1_000", "Expected ',' or ']'");
+               errors.put(/*65*/ "n_number_1eE2", "Invalid number");
+               errors.put(/*66*/ "n_number_2.e+3", "Invalid JSON number");
+               errors.put(/*67*/ "n_number_2.e-3", "Invalid JSON number");
+               errors.put(/*68*/ "n_number_2.e3", "Invalid JSON number");
+               errors.put(/*70*/ "n_number_expression", "Invalid number");
+               errors.put(/*71*/ "n_number_hex_1_digit", "Invalid JSON 
number");
+               errors.put(/*72*/ "n_number_hex_2_digits", "Invalid JSON 
number");
+               errors.put(/*73*/ "n_number_Inf", "Unrecognized syntax");
+               errors.put(/*74*/ "n_number_infinity", "Unrecognized syntax");
+               errors.put(/*75*/ "n_number_invalid+-", "Invalid number");
+               errors.put(/*76*/ "n_number_invalid-negative-real", "Expected 
',' or ']'");
+               errors.put(/*78*/ "n_number_minus_sign_with_trailing_garbage", 
"Invalid number");
+               errors.put(/*80*/ "n_number_NaN", "Unrecognized syntax");
+               errors.put(/*81*/ "n_number_neg_int_starting_with_zero", 
"Invalid JSON number");
+               errors.put(/*82*/ "n_number_neg_real_without_int_part", 
"Invalid JSON number");
+               errors.put(/*83*/ "n_number_neg_with_garbage_at_end", "Invalid 
number");
+               errors.put(/*84*/ "n_number_real_garbage_after_e", "Invalid 
number");
+               errors.put(/*85*/ "n_number_real_without_fractional_part", 
"Invalid");
+               errors.put(/*86*/ "n_number_starting_with_dot", "Invalid JSON 
number");
+               errors.put(/*87*/ "n_number_U+FF11_fullwidth_digit_one", 
"Unrecognized syntax");
+               errors.put(/*88*/ "n_number_with_alpha", "Invalid number");
+               errors.put(/*89*/ "n_number_with_alpha_char", "Expected ',' or 
']'");
+               errors.put(/*90*/ "n_number_with_leading_zero", "Invalid JSON 
number");
+               errors.put(/*91*/ "n_object_bad_value", "Unrecognized syntax");
+               errors.put(/*92*/ "n_object_comma_instead_of_colon", "Could not 
find ':'");
+               errors.put(/*93*/ "n_object_double_colon", "Unrecognized 
syntax");
+               errors.put(/*94*/ "n_object_garbage_at_end", "Could not find 
'}'");
+               errors.put(/*95*/ "n_object_key_with_single_quotes", "Unquoted 
attribute detected");
+               errors.put(/*96*/ "n_object_missing_colon", "Could not find 
':'");
+               errors.put(/*97*/ "n_object_missing_key", "Unquoted attribute 
detected");
+               errors.put(/*98*/ "n_object_missing_semicolon", "Could not find 
':'");
+               errors.put(/*99*/ "n_object_missing_value", "Unrecognized 
syntax");
+               errors.put(/*100*/ "n_object_no-colon", "Could not find ':'");
+               errors.put(/*101*/ "n_object_non_string_key", "Unquoted 
attribute detected");
+               errors.put(/*102*/ 
"n_object_non_string_key_but_huge_number_instead", "Unquoted attribute 
detected");
+               errors.put(/*103*/ "n_object_repeated_null_null", "Unquoted 
attribute detected");
+               errors.put(/*105*/ "n_object_single_quote", "Invalid quote 
character");
+               errors.put(/*106*/ "n_object_trailing_comma", "Unexpected '}' 
found");
+               errors.put(/*107*/ "n_object_trailing_comment", "Javascript 
comment detected");
+               errors.put(/*109*/ "n_object_trailing_comment_slash_open", 
"Javascript comment detected");
+               errors.put(/*112*/ "n_object_unquoted_key", "Unquoted attribute 
detected");
+               errors.put(/*114*/ "n_object_with_single_string", "Could not 
find ':'");
+               errors.put(/*115*/ "n_object_with_trailing_garbage", "Remainder 
after parse");
+               errors.put(/*116*/ "n_single_space", "Empty input");
+               errors.put(/*118*/ "n_string_single_quote", "Invalid quote 
character");
+               errors.put(/*119*/ "n_string_single_string_no_double_quotes", 
"Unrecognized syntax");
+               errors.put(/*120*/ "n_string_with_trailing_garbage", "Remainder 
after parse");
+               errors.put(/*121*/ "n_structure_<.>", "Unrecognized syntax");
+               errors.put(/*122*/ "n_structure_<null>", "Unrecognized syntax");
+               errors.put(/*123*/ "n_structure_array_trailing_garbage", 
"Remainder after parse");
+               errors.put(/*124*/ "n_structure_array_with_extra_array_close", 
"Remainder after parse");
+               errors.put(/*126*/ "n_structure_capitalized_True", 
"Unrecognized syntax");
+               errors.put(/*127*/ "n_structure_close_unopened_array", 
"Remainder after parse");
+               errors.put(/*129*/ "n_structure_double_array", "Remainder after 
parse");
+               errors.put(/*131*/ "n_structure_lone-open-bracket", "Expected 
one of the following characters: {,[,");
+               errors.put(/*132*/ "n_structure_no_data", "Empty input");
+               errors.put(/*133*/ "n_structure_null-byte-outside-string", 
"Unrecognized syntax");
+               errors.put(/*134*/ "n_structure_number_with_trailing_garbage", 
"Remainder after parse");
+               errors.put(/*135*/ 
"n_structure_object_followed_by_closing_object", "Remainder after parse");
+               errors.put(/*136*/ "n_structure_object_unclosed_no_value", 
"Unrecognized syntax");
+               errors.put(/*137*/ "n_structure_object_with_comment", 
"Javascript comment detected");
+               errors.put(/*138*/ "n_structure_object_with_trailing_garbage", 
"Remainder after parse");
+               errors.put(/*143*/ "n_structure_open_array_string", "Expected 
',' or ']'");
+               errors.put(/*150*/ "n_structure_single_star", "Unrecognized 
syntax");
+               errors.put(/*151*/ "n_structure_trailing_#", "Remainder after 
parse");
+               errors.put(/*152*/ "n_structure_unclosed_array", "Expected ',' 
or ']");
+               errors.put(/*153*/ "n_structure_unclosed_array_partial_null", 
"Unrecognized syntax");
+               errors.put(/*154*/ 
"n_structure_unclosed_array_unfinished_false", "Unrecognized syntax");
+               errors.put(/*155*/ 
"n_structure_unclosed_array_unfinished_true", "Unrecognized syntax");
+               errors.put(/*156*/ "n_structure_unclosed_object", "Could not 
find '}'");
+               errors.put(/*157*/ "ns_structure_100000_opening_arrays", "Depth 
too deep");
+               errors.put(/*158*/ "ns_structure_open_array_object", "Depth too 
deep");
+               errors.put(/*172*/ "nx_string_1_surrogate_then_escape u", 
"Invalid Unicode escape sequence in string");
+               errors.put(/*173*/ "nx_string_1_surrogate_then_escape u1", 
"Invalid Unicode escape sequence in string");
+               errors.put(/*174*/ "nx_string_1_surrogate_then_escape u1x", 
"Invalid Unicode escape sequence in string");
+               errors.put(/*176*/ "nx_string_accentuated_char_no_quotes", 
"Unrecognized syntax");
+               errors.put(/*178*/ "nx_string_escape_x", "Invalid escape 
sequence in string");
+               errors.put(/*181*/ "nx_string_escaped_emoji", "Invalid escape 
sequence in string");
+               errors.put(/*183*/ "nx_string_incomplete_escaped_character", 
"Invalid Unicode escape sequence in string");
+               errors.put(/*184*/ "nx_string_incomplete_surrogate", "Invalid 
Unicode escape sequence in string");
+               errors.put(/*185*/ 
"nx_string_incomplete_surrogate_escape_invalid", "Invalid escape sequence");
+               errors.put(/*187*/ "nx_string_invalid_backslash_esc", "Invalid 
escape sequence");
+               errors.put(/*188*/ "nx_string_invalid_unicode_escape", "Invalid 
Unicode escape sequence in string");
+               errors.put(/*189*/ "nx_string_invalid_utf-8", 
"MalformedInputException");
+               errors.put(/*191*/ "nx_string_iso_latin_1", 
"MalformedInputException");
+               errors.put(/*192*/ "nx_string_leading_uescaped_thinspace", 
"Unrecognized syntax");
+               errors.put(/*193*/ "nx_string_lone_utf8_continuation_byte", 
"MalformedInputException");
+               errors.put(/*194*/ "nx_string_no_quotes_with_bad_escape", 
"Unrecognized syntax");
+               errors.put(/*195*/ "nx_string_overlong_sequence_2_bytes", 
"MalformedInputException");
+               errors.put(/*196*/ "nx_string_overlong_sequence_6_bytes", 
"MalformedInputException");
+               errors.put(/*197*/ "nx_string_overlong_sequence_6_bytes_null", 
"MalformedInputException");
+               errors.put(/*202*/ "nx_string_unicode_CapitalU", "Invalid 
escape sequence");
+               errors.put(/*203*/ "nx_string_UTF8_surrogate_U+D800", 
"MalformedInputException");
+               errors.put(/*204*/ "nx_structure_ascii-unicode-identifier", 
"Unrecognized syntax");
+               errors.put(/*207*/ "nx_structure_open_open", "Invalid escape 
sequence");
+               errors.put(/*209*/ "nx_structure_U+2060_word_joined", 
"Unrecognized syntax");
+               errors.put(/*210*/ "nx_structure_uescaped_LF_before_string", 
"Unrecognized syntax");
+               errors.put(/*211*/ "nx_structure_unicode-identifier", 
"Unrecognized syntax");
+               errors.put(/*212*/ "nx_structure_UTF8_BOM_no_data", 
"Unrecognized syntax");
+               errors.put(/*213*/ "nx_structure_whitespace_formfeed", 
"Unrecognized syntax");
+               errors.put(/*214*/ 
"nx_structure_whitespace_U+2060_word_joiner", "Unrecognized syntax");
+       }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserTest.java
new file mode 100755
index 0000000..fc61db3
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserTest.java
@@ -0,0 +1,325 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.json;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+@SuppressWarnings({"javadoc"})
+public class JsonParserTest {
+
+       private static final JsonParser p = JsonParser.DEFAULT;
+       private static final JsonParser sp = JsonParser.DEFAULT_STRICT;
+
+
+       
//====================================================================================================
+       // Test invalid input
+       
//====================================================================================================
+       @Test
+       public void testInvalidJson() {
+               try {
+                       p.parse("{\na:1,\nb:xxx\n}", Object.class);
+                       fail("Exception expected.");
+               } catch (ParseException e) {}
+       }
+
+       @Test
+       public void testNonExistentAttribute() throws Exception {
+               String json = "{foo:,bar:}";
+               ObjectMap m = p.parse(json, ObjectMap.class);
+               assertEquals("{foo:null,bar:null}", m.toString());
+       }
+
+       @Test
+       public void testNonStringAsString() throws Exception {
+               String json = "123";
+               String s;
+
+               // Strict mode does not allow unquoted values.
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               s = p.parse(json, String.class);
+               assertEquals("123", s);
+
+               json = " 123 ";
+               // Strict mode does not allow unquoted values.
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               s = p.parse(json, String.class);
+               assertEquals("123", s);
+
+               json = "{\"fa\":123}";
+               try {
+                       sp.parse(json, A.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               A a = p.parse(json, A.class);
+               assertEquals("123", a.fa);
+
+               json = " { \"fa\" : 123 } ";
+               try {
+                       sp.parse(json, A.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Did not find quote 
character"));
+               }
+
+               a = p.parse(json, A.class);
+               assertEquals("123", a.fa);
+
+               json = "'123'";
+               try {
+                       sp.parse(json, String.class);
+                       fail("Exception expected");
+               } catch (Exception e) {
+                       assertTrue(e.getMessage().contains("Invalid quote 
character"));
+               }
+       }
+
+       public static class A {
+               public String fa;
+       }
+
+       @Test
+       public void testStrictMode() throws Exception {
+               JsonParser p = sp;
+
+               // Missing attribute values.
+               String json = "{\"foo\":,\"bar\":}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:7}.  Missing value detected.", 
e.getRootCause().getMessage());
+               }
+
+               // Single quoted values.
+               json = "{\"foo\":'bar'}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:8}.  Invalid quote character \"'\" being 
used.", e.getRootCause().getMessage());
+               }
+
+               // Single quoted attribute name.
+               json = "{'foo':\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:2}.  Invalid quote 
character \"'\" being used.", e.getRootCause().getMessage());
+               }
+
+               // Unquoted attribute name.
+               json = "{foo:\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:1}.  Unquoted attribute 
detected.", e.getRootCause().getMessage());
+               }
+
+               // Concatenated string
+               json = "{\"foo\":\"bar\"+\"baz\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:12}.  String concatenation detected.", 
e.getRootCause().getMessage());
+               }
+
+               // Concatenated string 2
+               json = "{\"foo\":\"bar\" + \"baz\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'Object',line:1,column:13}.  String concatenation detected.", 
e.getRootCause().getMessage());
+               }
+
+               json = "{\"foo\":/*comment*/\"bar\"}";
+               try {
+                       p.parse(json, ObjectMap.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertEquals("Parse exception occurred at 
{currentClass:'ObjectMap<String,Object>',line:1,column:8}.  Javascript comment 
detected.", e.getRootCause().getMessage());
+               }
+       }
+
+       /**
+        * JSON numbers and booleans should be representable as strings and 
converted accordingly.
+        */
+       @Test
+       public void testPrimitivesAsStrings() throws Exception {
+               String json;
+               ReaderParser p = JsonParser.DEFAULT;
+               WriterSerializer s = JsonSerializer.DEFAULT_LAX;
+
+               json = 
"{f1:'1',f2:'1',f3:'true',f4:'true',f5:'1',f6:'1',f7:'1',f8:'1',f9:'1',f10:'1'}";
+               B b = p.parse(json, B.class);
+               
assertEquals("{f1:1,f2:1,f3:true,f4:true,f5:1.0,f6:1.0,f7:1,f8:1,f9:1,f10:1}", 
s.toString(b));
+
+               json = 
"{f1:'',f2:'',f3:'',f4:'',f5:'',f6:'',f7:'',f8:'',f9:'',f10:''}";
+               b = p.parse(json, B.class);
+               
assertEquals("{f1:0,f2:0,f3:false,f4:false,f5:0.0,f6:0.0,f7:0,f8:0,f9:0,f10:0}",
 s.toString(b));
+       }
+
+       public static class B {
+               public int f1;
+               public Integer f2;
+               public boolean f3;
+               public Boolean f4;
+               public float f5;
+               public Float f6;
+               public long f7;
+               public Long f8;
+               public byte f9;
+               public Byte f10;
+       }
+
+       
//====================================================================================================
+       // testInvalidJsonNumbers
+       // Lax parser allows octal and hexadecimal numbers.  Strict parser does 
not.
+       
//====================================================================================================
+       @Test
+       public void testInvalidJsonNumbers() throws Exception {
+               JsonParser p1 = JsonParser.DEFAULT;
+               JsonParser p2 = JsonParser.DEFAULT_STRICT;
+               Number r;
+
+               // Lax allows blank strings interpreted as 0, strict does not.
+               String s = "\"\"";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().contains("Invalid JSON 
number"));
+               }
+
+               // Either should allow 0 or -0.
+               s = "0";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               r = p2.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+
+               s = "-0";
+               r = p1.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+               r = p2.parse(s, Number.class);
+               assertEquals(0, r.intValue());
+               assertTrue(r instanceof Integer);
+
+               // Lax allows 0123 and -0123, strict does not.
+               s = "0123";
+               r = p1.parse(s, Number.class);
+               assertEquals(0123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().contains("Invalid JSON 
number"));
+               }
+               s = "-0123";
+               r = p1.parse(s, Number.class);
+               assertEquals(-0123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().contains("Invalid JSON 
number"));
+               }
+
+               // Lax allows 0x123 and -0x123, strict does not.
+               s = "0x123";
+               r = p1.parse(s, Number.class);
+               assertEquals(0x123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().contains("Invalid JSON 
number"));
+               }
+               s = "-0x123";
+               r = p1.parse(s, Number.class);
+               assertEquals(-0x123, r.intValue());
+               assertTrue(r instanceof Integer);
+               try {
+                       r = p2.parse(s, Number.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       assertTrue(e.getMessage().contains("Invalid JSON 
number"));
+               }
+       }
+
+       
//====================================================================================================
+       // testUnquotedStrings
+       // Lax parser allows unquoted strings if POJO can be converted from a 
string.
+       
//====================================================================================================
+       @Test
+       public void testUnquotedStrings() throws Exception {
+               JsonParser p1 = JsonParser.DEFAULT;
+               JsonParser p2 = JsonParser.DEFAULT_STRICT;
+
+               String s = "foobar";
+               C c = p1.parse(s, C.class);
+               assertEquals("f=foobar", c.toString());
+
+               try {
+                       p2.parse(s, C.class);
+                       fail("Exception expected");
+               } catch (ParseException e) {
+                       // OK
+               }
+       }
+
+       public static class C {
+               String f;
+               public static C valueOf(String s) {
+                       C c = new C();
+                       c.f = s;
+                       return c;
+               }
+               @Override /* Object */
+               public String toString() {
+                       return "f="+f;
+               }
+       }
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/e4dfdf81/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
----------------------------------------------------------------------
diff --git 
a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaTest.java 
b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
new file mode 100755
index 0000000..2567e44
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaTest.java
@@ -0,0 +1,45 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you 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.apache.juneau.json;
+
+import static org.junit.Assert.*;
+
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class JsonSchemaTest {
+
+       
//====================================================================================================
+       // Primitive objects
+       
//====================================================================================================
+       @Test
+       public void testBasic() throws Exception {
+
+               JsonSchemaSerializer s = 
JsonSerializer.DEFAULT_LAX.getSchemaSerializer();
+
+               Object o = new String();
+               assertEquals("{type:'string',description:'java.lang.String'}", 
s.serialize(o));
+
+               o = new Integer(123);
+               assertEquals("{type:'number',description:'java.lang.Integer'}", 
s.serialize(o));
+
+               o = new Float(123);
+               assertEquals("{type:'number',description:'java.lang.Float'}", 
s.serialize(o));
+
+               o = new Double(123);
+               assertEquals("{type:'number',description:'java.lang.Double'}", 
s.serialize(o));
+
+               o = Boolean.TRUE;
+               
assertEquals("{type:'boolean',description:'java.lang.Boolean'}", 
s.serialize(o));
+       }
+}
\ No newline at end of file

Reply via email to