You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2016/08/09 17:15:44 UTC

[23/44] incubator-juneau git commit: Rename CT_* testcases.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
new file mode 100755
index 0000000..6ad9c0f
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -0,0 +1,1012 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import javax.xml.datatype.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.json.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+import org.apache.juneau.transforms.*;
+import org.junit.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings({"unchecked","hiding","serial","unused"})
+public class RoundTripBeanMapsTest extends RoundTripTest {
+
+	public RoundTripBeanMapsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@Override /* RoundTripTest */
+	public Map<Class<?>,Class<?>> getImplClasses() {
+		Map<Class<?>,Class<?>> m = new HashMap<Class<?>,Class<?>>();
+		m.put(IBean.class, CBean.class);
+		return m;
+	}
+
+	//====================================================================================================
+	// IBean/ABean/Bean
+	//====================================================================================================
+	@Test
+	public void testImplClasses() throws Exception {
+		IBean bean = new CBean();
+
+		bean.setF1("bar");
+		bean = roundTrip(bean, IBean.class);
+		assertEquals("bar", bean.getF1());
+
+		bean.setF1("baz");
+		bean = roundTrip(bean, ABean.class);
+		assertEquals("baz", bean.getF1());
+
+		bean.setF1("bing");
+		bean = roundTrip(bean, CBean.class);
+		assertEquals("bing", bean.getF1());
+	}
+
+	//====================================================================================================
+	// IBean[]/ABean[]/Bean[]
+	//====================================================================================================
+	@Test
+	public void testImplArrayClasses() throws Exception {
+		IBean[] bean = new CBean[]{new CBean()};
+
+		bean[0].setF1("bar");
+		bean = roundTrip(bean, IBean[].class);
+		assertEquals("bar", bean[0].getF1());
+
+		bean[0].setF1("baz");
+		bean = roundTrip(bean, ABean[].class);
+		assertEquals("baz", bean[0].getF1());
+
+		bean[0].setF1("bing");
+		bean = roundTrip(bean, CBean[].class);
+		assertEquals("bing", bean[0].getF1());
+	}
+
+	//====================================================================================================
+	// List<IBean/ABean/Bean>
+	//====================================================================================================
+	@Test
+	public void testImplListClasses() throws Exception {
+		List<IBean> l = new LinkedList<IBean>() {{
+			add(new CBean());
+		}};
+
+		l.get(0).setF1("bar");
+		l = roundTripCollection(l, List.class, IBean.class);
+		assertEquals("bar", l.get(0).getF1());
+		l = roundTripCollection(l, LinkedList.class, IBean.class);
+		assertEquals("bar", l.get(0).getF1());
+
+		l.get(0).setF1("baz");
+		l = roundTripCollection(l, List.class, ABean.class);
+		assertEquals("baz", l.get(0).getF1());
+		l = roundTripCollection(l, LinkedList.class, ABean.class);
+		assertEquals("baz", l.get(0).getF1());
+
+		l.get(0).setF1("bing");
+		l = roundTripCollection(l, List.class, CBean.class);
+		assertEquals("bing", l.get(0).getF1());
+		l = roundTripCollection(l, LinkedList.class, CBean.class);
+		assertEquals("bing", l.get(0).getF1());
+	}
+
+	//====================================================================================================
+	// Map<String,IBean/ABean/Bean>
+	//====================================================================================================
+	@Test
+	public void testImplMap() throws Exception {
+		Map<String,IBean> l = new LinkedHashMap<String,IBean>() {{
+			put("foo", new CBean());
+		}};
+
+		l.get("foo").setF1("bar");
+		l = roundTripMap(l, Map.class, String.class, IBean.class);
+		assertEquals("bar", l.get("foo").getF1());
+		l = roundTripMap(l, LinkedHashMap.class, String.class, IBean.class);
+		assertEquals("bar", l.get("foo").getF1());
+
+		l.get("foo").setF1("baz");
+		l = roundTripMap(l, Map.class, String.class, ABean.class);
+		assertEquals("baz", l.get("foo").getF1());
+		l = roundTripMap(l, LinkedHashMap.class, String.class, ABean.class);
+		assertEquals("baz", l.get("foo").getF1());
+
+		l.get("foo").setF1("bing");
+		l = roundTripMap(l, Map.class, String.class, CBean.class);
+		assertEquals("bing", l.get("foo").getF1());
+		l = roundTripMap(l, LinkedHashMap.class, String.class, CBean.class);
+		assertEquals("bing", l.get("foo").getF1());
+	}
+
+	//====================================================================================================
+	// Map<String,IBean/ABean/Bean>
+	//====================================================================================================
+	@Test
+	public void testImplMap2() throws Exception {
+		A b = new A(1);
+		b = roundTrip(b);
+		if (returnOriginalObject || p == null)
+			return;
+		assertEquals(0, b.f1);
+		assertEquals(0, b.f2);
+		assertEquals(1, b.f3);
+		assertEquals(1, b.f4);
+		assertEquals(0, b.getF5());
+		assertEquals(1, b.getF6());
+	}
+
+	public static interface IBean {
+		public String getF1();
+		public void setF1(String f1);
+	}
+
+	public static abstract class ABean implements IBean {
+		@Override /* IBean */
+		public abstract String getF1();
+		@Override /* IBean */
+		public abstract void setF1(String f1);
+	}
+
+	public static class CBean extends ABean {
+		private String f1 = "foo";
+		@Override /* IBean */
+		public String getF1() {
+			return f1;
+		}
+		@Override /* IBean */
+		public void setF1(String f1) {
+			this.f1 = f1;
+		}
+	}
+
+	public static class A {
+
+		@BeanIgnore
+		public int f1, f2;
+		public int f3, f4;
+
+		private int f5, f6;
+
+		@BeanIgnore
+		public int getF5() {
+			return f5;
+		}
+		public void setF5(int f5) {
+			this.f5 = f5;
+		}
+
+		public int getF6() {
+			return f6;
+		}
+		public void setF6(int f6) {
+			this.f6 = f6;
+		}
+
+		public A() {}
+
+		public A(int v) {
+			f1 = f2 = f3 = f4 = f5 = f6 = v;
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(subTypes=xxx)
+	//====================================================================================================
+	@Test
+	public void testSubTypesUsingAnnotation() throws Exception {
+		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addTransforms(XMLGregorianCalendarTransform.class);
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().clone().addTransforms(XMLGregorianCalendarTransform.class);
+		Parser p = getParser().clone().addTransforms(XMLGregorianCalendarTransform.class);
+
+		B1 b1 = B1.create();
+		Object r = s.serialize(b1);
+		B b = p.parse(r, B.class);
+		assertTrue(b instanceof B1);
+		assertObjectEquals("{subType:'B1',f0:'f0',f1:'f1'}", b, js);
+
+		B2 b2 = B2.create();
+		r = s.serialize(b2);
+		b = p.parse(r, B.class);
+		assertTrue(b instanceof B2);
+		assertObjectEquals("{subType:'B2',f0:'f0',f2:1}", b, js);
+
+		B3 b3 = B3.create();
+		r = s.serialize(b3);
+		b = p.parse(r, B.class);
+		assertTrue(b instanceof B3);
+		assertObjectEquals("{subType:'B3',f0:'f0',f3:'2001-01-01T12:34:56.789Z'}", b, js);
+}
+
+	@Bean(
+		subTypeProperty="subType",
+		subTypes={
+			@BeanSubType(type=B1.class, id="B1"),
+			@BeanSubType(type=B2.class, id="B2"),
+			@BeanSubType(type=B3.class, id="B3")
+		}
+	)
+	public abstract static class B {
+		public String f0 = "f0";
+	}
+
+	public static class B1 extends B {
+		public String f1;
+		public static B1 create() {
+			B1 b = new B1();
+			b.f0 = "f0";
+			b.f1 = "f1";
+			return b;
+		}
+	}
+
+	public static class B2 extends B {
+		public int f2;
+		public static B2 create() {
+			B2 b = new B2();
+			b.f0 = "f0";
+			b.f2 = 1;
+			return b;
+		}
+	}
+
+	public static class B3 extends B {
+		public XMLGregorianCalendar f3;
+		public static B3 create() throws Exception {
+			B3 b = new B3();
+			b.f0 = "f0";
+			b.f3 = DatatypeFactory.newInstance().newXMLGregorianCalendar("2001-01-01T12:34:56.789Z");
+			return b;
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(subTypes=xxx) using BeanTransform
+	//====================================================================================================
+	@Test
+	public void testSubTypesUsingBeanTransform() throws Exception {
+		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addTransforms(XMLGregorianCalendarTransform.class);
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().clone().addTransforms(CTransform.class, XMLGregorianCalendarTransform.class);
+		Parser p = getParser().clone().addTransforms(CTransform.class, XMLGregorianCalendarTransform.class);
+
+		C1 c1 = C1.create();
+		Object r = s.serialize(c1);
+		C c = p.parse(r, C.class);
+		assertTrue(c instanceof C1);
+		assertObjectEquals("{f0:'f0',f1:'f1'}", c, js);
+
+		C2 c2 = C2.create();
+		r = s.serialize(c2);
+		c = p.parse(r, C.class);
+		assertTrue(c instanceof C2);
+		assertObjectEquals("{f0:'f0',f2:1}", c, js);
+
+		C3 c3 = C3.create();
+		r = s.serialize(c3);
+		c = p.parse(r, C.class);
+		assertTrue(c instanceof C3);
+		assertObjectEquals("{f0:'f0',f3:'2001-01-01T12:34:56.789Z'}", c, js);
+	}
+
+	public abstract static class C {
+		public String f0;
+	}
+
+	public static class C1 extends C {
+		public String f1;
+		public static C1 create() {
+			C1 c = new C1();
+			c.f0 = "f0";
+			c.f1 = "f1";
+			return c;
+		}
+	}
+
+	public static class C2 extends C {
+		public int f2;
+		public static C2 create() {
+			C2 c = new C2();
+			c.f0 = "f0";
+			c.f2 = 1;
+			return c;
+		}
+	}
+
+	public static class C3 extends C {
+		public XMLGregorianCalendar f3;
+		public static C3 create() throws Exception {
+			C3 c = new C3();
+			c.f0 = "f0";
+			c.f3 = DatatypeFactory.newInstance().newXMLGregorianCalendar("2001-01-01T12:34:56.789Z");
+			return c;
+		}
+	}
+
+	public static class CTransform extends BeanTransform<C> {
+		public CTransform() {
+			setSubTypeProperty("subType");
+			addSubType(C1.class, "C1");
+			addSubType(C2.class, "C2");
+			addSubType(C3.class, "C3");
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(subTypeProperty=xxx) with real bean property
+	//====================================================================================================
+	@Test
+	public void testSubTypePropertyWithRealPropertyUsingAnnotation() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+
+		BA1 ba1 = BA1.create();
+		Object r = s.serialize(ba1);
+		BA b = p.parse(r, BA.class);
+		assertTrue(b instanceof BA1);
+		assertEquals("BA1", b.subType);
+		assertObjectEquals("{subType:'BA1',f0a:'f0a',f0b:'f0b',f1:'f1'}", b);
+	}
+
+	@Bean(
+		subTypeProperty="subType",
+		subTypes={
+			@BeanSubType(type=BA1.class, id="BA1"),
+			@BeanSubType(type=BA2.class, id="BA2")
+		}
+	)
+	public abstract static class BA {
+		public String f0a, subType, f0b;
+	}
+
+	public static class BA1 extends BA {
+		public String f1;
+		public static BA1 create() {
+			BA1 b = new BA1();
+			b.f0a = "f0a";
+			b.f0b = "f0b";
+			b.f1 = "f1";
+			b.subType = "xxx";// Should be ignored.
+			return b;
+		}
+	}
+
+	public static class BA2 extends BA {
+		public String f2;
+	}
+
+
+	//====================================================================================================
+	// Test @Bean(subTypes=xxx) with real bean property using BeanTransform
+	//====================================================================================================
+	@Test
+	public void testSubTypePropertyWithRealPropertyUsingBeanTransform() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().clone().addTransforms(CATransform.class);
+		Parser p = getParser().clone().addTransforms(CATransform.class);
+
+		CA1 c1 = CA1.create();
+		Object r = s.serialize(c1);
+		CA c = p.parse(r, CA.class);
+		assertTrue(c instanceof CA1);
+		assertEquals("CA1", c.subType);
+		assertObjectEquals("{f0a:'f0a',subType:'CA1',f0b:'f0b',f1:'f1'}", c);
+	}
+
+	public abstract static class CA {
+		public String f0a, subType, f0b;
+	}
+
+	public static class CA1 extends CA {
+		public String f1;
+		public static CA1 create() {
+			CA1 c = new CA1();
+			c.f0a = "f0a";
+			c.f0b = "f0b";
+			c.f1 = "f1";
+			c.subType = "xxx";// Should be ignored.
+			return c;
+		}
+	}
+
+	public static class CA2 extends CA {
+		public String f2;
+	}
+
+	public static class CATransform extends BeanTransform<CA> {
+		public CATransform() {
+			setSubTypeProperty("subType");
+			addSubType(CA1.class, "CA1");
+			addSubType(CA2.class, "CA2");
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(properties=xxx)
+	//====================================================================================================
+	@Test
+	public void testPropertiesUsingAnnotation() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+
+		D1 d = new D1().init();
+		Object r = s.serialize(d);
+		d = p.parse(r, D1.class);
+		assertNull(d.f1);
+		assertObjectEquals("{f3:'f3',f2:'f2'}", d);
+	}
+
+	@Bean(properties={"f3","f2"})
+	public static class D1 {
+		public String f1, f2, f3;
+		public D1 init() {
+			f1 = "f1";
+			f2 = "f2";
+			f3 = "f3";
+			return this;
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(properties=xxx) using BeanTransform
+	//====================================================================================================
+	@Test
+	public void testPropertiesUsingTransform() throws Exception {
+		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addTransforms(D2Transform.class);
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().clone().addTransforms(D2Transform.class);
+		Parser p = getParser().clone().addTransforms(D2Transform.class);
+
+		D2 d = new D2().init();
+		Object r = s.serialize(d);
+		d = p.parse(r, D2.class);
+		assertNull(d.f1);
+		assertObjectEquals("{f3:'f3',f2:'f2'}", d, js);
+	}
+
+	public static class D2 {
+		public String f1, f2, f3;
+		public D2 init() {
+			f1 = "f1";
+			f2 = "f2";
+			f3 = "f3";
+			return this;
+		}
+	}
+	public static class D2Transform extends BeanTransform<D2> {
+		public D2Transform() {
+			setProperties("f3","f2");
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(excludeProperties=xxx)
+	//====================================================================================================
+	@Test
+	public void testExcludePropertiesUsingAnnotation() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+
+		E1 e = new E1().init();
+		Object r = s.serialize(e);
+		e = p.parse(r, E1.class);
+		assertObjectEquals("{f1:'f1',f3:'f3'}", e);
+	}
+
+	@Bean(excludeProperties={"f2"})
+	public static class E1 {
+		public String f1, f2, f3;
+		public E1 init() {
+			f1 = "f1";
+			f2 = "f2";
+			f3 = "f3";
+			return this;
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(excludeProperties=xxx) using BeanTransform
+	//====================================================================================================
+	@Test
+	public void testExcludePropertiesUsingTransform() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().clone().addTransforms(E2Transform.class);
+		Parser p = getParser().clone().addTransforms(E2Transform.class);
+
+		E2 e = new E2().init();
+		Object r = s.serialize(e);
+		e = p.parse(r, E2.class);
+		assertObjectEquals("{f1:'f1',f3:'f3'}", e);
+	}
+
+	public static class E2 {
+		public String f1, f2, f3;
+		public E2 init() {
+			f1 = "f1";
+			f2 = "f2";
+			f3 = "f3";
+			return this;
+		}
+	}
+	public static class E2Transform extends BeanTransform<E2> {
+		public E2Transform() {
+			setExcludeProperties("f2");
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(interfaceClass=xxx)
+	//====================================================================================================
+	@Test
+	public void testInterfaceClassUsingAnnotation() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+
+		FA2 t = new FA2().init();
+		Object r = s.serialize(t);
+		t = p.parse(r, FA2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+	}
+
+	@Bean(interfaceClass=FA1.class)
+	public static class FA1 {
+		public String f1;
+	}
+
+	public static class FA2 extends FA1 {
+		public String f2;
+		public FA2 init() {
+			f1 = "f1";
+			f2 = "f2";
+			return this;
+		}
+	}
+
+	//====================================================================================================
+	// Test @Bean(interfaceClass=xxx) using BeanTransform
+	//====================================================================================================
+	@Test
+	public void testInterfaceClassUsingTransform() throws Exception {
+		Serializer s;
+		Parser p;
+		FB2 t;
+		Object r;
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		// --- Transform defined on parent class ---
+		s = getSerializer().clone().addTransforms(FB1Transform.class);
+		p = getParser().clone().addTransforms(FB1Transform.class);
+
+		t = new FB2().init();
+		r = s.serialize(t);
+		t = p.parse(r, FB2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+
+		// --- Transform defined on child class class ---
+		s = getSerializer().clone().addTransforms(FB2Transform.class);
+		p = getParser().clone().addTransforms(FB2Transform.class);
+
+		t = new FB2().init();
+		r = s.serialize(t);
+		t = p.parse(r, FB2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+
+		// --- Transform defined as plain class ---
+		s = getSerializer().clone().addTransforms(FB1.class);
+		p = getParser().clone().addTransforms(FB1.class);
+
+		t = new FB2().init();
+		r = s.serialize(t);
+		t = p.parse(r, FB2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+	}
+
+	public static class FB1 {
+		public String f1;
+	}
+
+	public static class FB2 extends FB1 {
+		public String f2;
+		public FB2 init() {
+			f1 = "f1";
+			f2 = "f2";
+			return this;
+		}
+	}
+	public static class FB1Transform extends BeanTransform<FB1> {
+		public FB1Transform() {
+			setInterfaceClass(FB1.class);
+		}
+	}
+	public static class FB2Transform extends BeanTransform<FB2> {
+		public FB2Transform() {
+			setInterfaceClass(FB1.class);
+		}
+	}
+
+	//====================================================================================================
+	// testMemberClass
+	//====================================================================================================
+	@Test
+	public void testMemberClass() throws Exception {
+		G t = G.create();
+		t = roundTrip(t, G.class);
+	}
+
+	public static class G {
+		public int a1;
+		public G1 g1;
+
+		public static G create() {
+			G g = new G();
+			g.a1 = 1;
+			g.g1.a2 = 2;
+			g.g1.g2.a3 = 3;
+			return g;
+		}
+
+		public G() {
+			g1 = new G1();
+		}
+
+		public class G1 {
+			public int a2;
+			public G2 g2;
+
+			public G1() {
+				g2 = new G2();
+			}
+
+			public class G2 {
+				public int a3;
+			}
+		}
+	}
+
+	//====================================================================================================
+	// testMemberClassWithMapClass
+	//====================================================================================================
+	@Test
+	public void testMemberClassWithMapClass() throws Exception {
+		H t = H.create();
+		t = roundTrip(t, H.class);
+	}
+
+	public static class H extends LinkedHashMap<String,H.H1> {
+
+		static H create() {
+			H h = new H();
+			h.add("foo", 1, 2);
+			return h;
+		}
+
+		H add(String key, int a2, int a3) {
+			H1 h1 = new H1();
+			h1.a2 = a2;
+			h1.h2.a3 = a3;
+			put(key, h1);
+			return this;
+		}
+
+		public class H1 {
+			public int a2;
+			public H2 h2;
+
+			public H1() {
+				h2 = new H2();
+			}
+
+			public class H2 {
+				public int a3;
+			}
+		}
+	}
+
+	//====================================================================================================
+	// testMemberClassWithListClass
+	//====================================================================================================
+	@Test
+	public void testMemberClassWithListClass() throws Exception {
+		I t = I.create();
+		t = roundTrip(t, I.class);
+	}
+
+	public static class I extends LinkedList<I.I1> {
+
+		static I create() {
+			I i = new I();
+			i.add(1, 2);
+			return i;
+		}
+
+		I add(int a2, int a3) {
+			I1 i1 = new I1();
+			i1.a2 = a2;
+			i1.i2.a3 = a3;
+			super.add(i1);
+			return this;
+		}
+
+		public class I1 {
+			public int a2;
+			public I2 i2;
+
+			public I1() {
+				i2 = new I2();
+			}
+
+			public class I2 {
+				public int a3;
+			}
+		}
+	}
+
+	//====================================================================================================
+	// testMemberClassWithStringConstructor
+	//====================================================================================================
+	@Test
+	public void testMemberClassWithStringConstructor() throws Exception {
+		J t = J.create();
+		t = roundTrip(t, J.class);
+	}
+
+	public static class J {
+		public J2 j2;
+
+		static J create() {
+			J j = new J();
+			j.init();
+			return j;
+		}
+
+		private void init() {
+			j2 = new J2("2");
+		}
+
+		public class J2 {
+			int a2;
+
+			public J2(String arg) {
+				this.a2 = Integer.parseInt(arg);
+			}
+
+			@Override /* Object */
+			public String toString() {
+				return String.valueOf(a2);
+			}
+		}
+	}
+
+	//====================================================================================================
+	// testBeanPropertyPrecedence
+	//====================================================================================================
+	@Test
+	public void testBeanPropertyPrecedence() throws Exception {
+		K t = K.create();
+		t = roundTrip(t, K.class);
+	}
+	public static enum KEnum { FOO, BAR, BAZ }
+
+	public static class K {
+		private KEnum a, b, c;
+
+		static K create() {
+			K t = new K();
+			t.a = KEnum.FOO;
+			t.b = KEnum.BAR;
+			t.c = KEnum.BAZ;
+			return t;
+		}
+
+		@BeanIgnore
+		public KEnum getA() {
+			return KEnum.FOO;
+		}
+
+		@BeanProperty(name="a")
+		public String getA2() {
+			return a.toString();
+		}
+
+		// This method should not be interpreted as the setter for this
+		// property because it doesn't match the getter return type above.
+		public void setA(KEnum a) {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public void setA(String a) {
+			this.a = KEnum.valueOf(a);
+		}
+
+		public KEnum getB() {
+			return b;
+		}
+
+		public void setB(String b) {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public void setB(Object b) {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public void setB(KEnum b) {
+			this.b = b;
+		}
+
+		public KEnum getC() {
+			return c;
+		}
+
+		public void setC(KEnum c) {
+			this.c = c;
+		}
+
+		public void setC(String c) {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public void setC(Object c) {
+			throw new RuntimeException("Should not be called!");
+		}
+	}
+
+	//====================================================================================================
+	// testWrapperAttrAnnotationOnBean
+	//====================================================================================================
+	@Test
+	public void testWrapperAttrAnnotationOnBean() throws Exception {
+		L t = L.create();
+		t = roundTrip(t, L.class);
+
+		Map<String,L> m = new LinkedHashMap<String,L>();
+		m.put("bar", L.create());
+		roundTripMap(m, LinkedHashMap.class, String.class, L.class);
+	}
+
+	@Json(wrapperAttr="foo")
+	public static class L {
+		public int f1;
+
+		static L create() {
+			L l = new L();
+			l.f1 = 1;
+			return l;
+		}
+	}
+
+	//====================================================================================================
+	// testWrapperAttrAnnotationOnNonBean
+	//====================================================================================================
+	@Test
+	public void testWrapperAttrAnnotationOnNonBean() throws Exception {
+		M t = M.create();
+		t = roundTrip(t, M.class);
+
+		Map<String,M> m = new LinkedHashMap<String,M>();
+		m.put("bar", M.create());
+		roundTripMap(m, LinkedHashMap.class, String.class, M.class);
+	}
+
+	@Json(wrapperAttr="foo")
+	public static class M {
+		int f1;
+
+		static M create() {
+			M m = new M();
+			m.f1 = 1;
+			return m;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return String.valueOf(f1);
+		}
+
+		public static M valueOf(String s) {
+			M m = new M();
+			m.f1 = Integer.parseInt(s);
+			return m;
+		}
+	}
+
+	//====================================================================================================
+	// Test parsing into top-level non-static inner classes with outer context.
+	//====================================================================================================
+	@Test
+	public void testParsingIntoTopLevelNonStaticInnerClasses() throws Exception {
+		N n = new N(1);
+
+		if (returnOriginalObject)
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+
+		Object r = s.serialize(n.n2);
+		n = new N(2);
+		ParserSession session = p.createSession(r, null, null, n);
+
+		N.N2 n2 = p.parse(session, BeanContext.DEFAULT.getClassMeta(N.N2.class));
+
+		// The inner N2.f1 field should be the value of the outer object passed in through the context.
+		assertEquals(2, n2.f1);
+	}
+
+	public static class N {
+		public int f1;
+		public N2 n2;
+
+		public N(int f1) {
+			this.f1 = f1;
+			n2 = new N2();
+		}
+		public class N2 {
+			private int f1 = N.this.f1;
+			public int dummy = 1;
+		}
+	}
+
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
new file mode 100644
index 0000000..49df439
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
@@ -0,0 +1,53 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+public class RoundTripClassesTest extends RoundTripTest {
+
+	public RoundTripClassesTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@SuppressWarnings("serial")
+	@Test
+	public void classObjects() throws Exception {
+		Object o = String.class;
+		o = roundTrip(o);
+		assertTrue(o == String.class);
+
+		o = new Class[]{String.class};
+		o = roundTrip(o);
+		assertObjectEquals("['java.lang.String']", o);
+
+		o = new LinkedList<Class<?>>(){{add(String.class);add(Integer.class);}};
+		o = roundTrip(o);
+		assertObjectEquals("['java.lang.String','java.lang.Integer']", o);
+
+		o = new LinkedHashMap<Class<?>,Class<?>>(){{put(String.class,String.class);}};
+		o = roundTrip(o);
+		assertObjectEquals("{'java.lang.String':'java.lang.String'}", o);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
new file mode 100755
index 0000000..2bee742
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
@@ -0,0 +1,50 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+
+import org.apache.juneau.dto.jsonschema.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings("hiding")
+public class RoundTripDTOsTest extends RoundTripTest {
+
+	public RoundTripDTOsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// org.apache.juneau.test.dto.jsonschema
+	//====================================================================================================
+	@Test
+	public void testJsonSchema1() throws Exception {
+		Schema s = JsonSchemaTest.getTest1();
+		Schema s2 = roundTrip(s, Schema.class);
+		assertEqualObjects(s, s2);
+	}
+
+	@Test
+	public void testJsonSchema2() throws Exception {
+		Schema s = JsonSchemaTest.getTest2();
+		Schema s2 = roundTrip(s, Schema.class);
+		assertEqualObjects(s, s2);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
new file mode 100755
index 0000000..d34221c
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
@@ -0,0 +1,246 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings({"hiding","serial"})
+public class RoundTripEnumTest extends RoundTripTest {
+
+	public RoundTripEnumTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// Enum object
+	//====================================================================================================
+	@Test
+	public void testEnumA() throws Exception {
+		AEnum t = AEnum.FOO;
+		assertObjectEquals("'FOO'", t);
+		t = roundTrip(t, AEnum.class);
+		assertEquals(AEnum.FOO, t);
+	}
+
+	@Test
+	public void testEnumB() throws Exception {
+		WriterSerializer s = new JsonSerializer.Simple().addTransforms(getTransforms());
+		BEnum t = BEnum.FOO;
+		assertEquals("'xfoo'", s.serialize(t));
+		t = roundTrip(t, BEnum.class);
+		assertEquals(BEnum.FOO, t);
+	}
+
+	//====================================================================================================
+	// Enum[] object
+	//====================================================================================================
+	@Test
+	public void testEnumArrayA() throws Exception {
+		AEnum[] t = {AEnum.FOO,AEnum.BAR,null};
+		assertObjectEquals("['FOO','BAR',null]", t);
+		t = roundTrip(t, AEnum[].class);
+		assertEquals(AEnum.FOO, t[0]);
+		assertEquals(AEnum.BAR, t[1]);
+		assertNull(t[2]);
+	}
+
+	@Test
+	public void testEnumArrayB() throws Exception {
+		BEnum[] t = {BEnum.FOO,BEnum.BAR,null};
+		assertObjectEquals("['xfoo','xbar',null]", t);
+		t = roundTrip(t, BEnum[].class);
+		assertEquals(BEnum.FOO, t[0]);
+		assertEquals(BEnum.BAR, t[1]);
+		assertNull(t[2]);
+	}
+
+	//====================================================================================================
+	// Enum[][] object
+	//====================================================================================================
+	@Test
+	public void testEnum2dArrayA() throws Exception {
+		AEnum[][] t = {{AEnum.FOO,AEnum.BAR,null},null};
+		assertObjectEquals("[['FOO','BAR',null],null]", t);
+		t = roundTrip(t, AEnum[][].class);
+		assertEquals(AEnum.FOO, t[0][0]);
+		assertEquals(AEnum.BAR, t[0][1]);
+		assertNull(t[0][2]);
+		assertNull(t[1]);
+	}
+
+	@Test
+	public void testEnum2dArrayB() throws Exception {
+		BEnum[][] t = {{BEnum.FOO,BEnum.BAR,null},null};
+		assertObjectEquals("[['xfoo','xbar',null],null]", t);
+		t = roundTrip(t, BEnum[][].class);
+		assertEquals(BEnum.FOO, t[0][0]);
+		assertEquals(BEnum.BAR, t[0][1]);
+		assertNull(t[0][2]);
+		assertNull(t[1]);
+	}
+
+	//====================================================================================================
+	// Bean with Enum fields
+	//====================================================================================================
+	@Test
+	public void testBeansWithEnumA() throws Exception {
+		A t1 = new A().init(), t2;
+		t2 = roundTrip(t1, A.class);
+		assertEqualObjects(t1, t2);
+		assertEquals(AEnum.FOO, t2.f3[0]);
+		assertNull(t2.f3[1]);
+		assertEquals(AEnum.FOO, t2.f4[0][0]);
+		assertNull(t2.f4[0][1]);
+		assertNull(t2.f4[1]);
+	}
+
+	@Test
+	public void testBeansWithEnumB() throws Exception {
+		B t1 = new B().init(), t2;
+		t2 = roundTrip(t1, B.class);
+		assertEqualObjects(t1, t2);
+		assertEquals(BEnum.FOO, t2.f3[0]);
+		assertNull(t2.f3[1]);
+		assertEquals(BEnum.FOO, t2.f4[0][0]);
+		assertNull(t2.f4[0][1]);
+		assertNull(t2.f4[1]);
+	}
+
+
+	/** Normal Enum */
+	public enum AEnum {
+		FOO,BAR,BAZ
+	}
+
+	/** Enum with custom serialized values */
+	public enum BEnum {
+		FOO("xfoo"), BAR("xbar"), BAZ("xbaz");
+
+		private String val;
+
+		private BEnum(String val) {
+			this.val = val;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return val;
+		}
+
+		public static BEnum fromString(String val) {
+			if (val.equals("xfoo"))
+				return FOO;
+			if (val.equals("xbar"))
+				return BAR;
+			if (val.equals("xbaz"))
+				return BAZ;
+			return null;
+		}
+	}
+
+	public static class A {
+
+		// Should have 'enum' attribute.
+		public AEnum f1;
+
+		private AEnum f2;
+		public AEnum getF2() {return f2;}
+		public void setF2(AEnum f2) {this.f2 = f2;}
+
+		public AEnum[] f3;
+		public AEnum[][] f4;
+
+		// Should not have 'uniqueSet' attribute.
+		public List<AEnum> f5 = new LinkedList<AEnum>();
+
+		private List<AEnum> f6 = new LinkedList<AEnum>();
+		public List<AEnum> getF6() {return f6;}
+		public void setF6(List<AEnum> f6) {this.f6 = f6;}
+
+		// Should have 'uniqueSet' attribute.
+		public Set<AEnum> f7 = new HashSet<AEnum>();
+
+		private Set<AEnum> f8 = new HashSet<AEnum>();
+		public Set<AEnum> getF8() {return f8;}
+		public void setF8(Set<AEnum> f8) {this.f8 = f8;}
+
+		public Map<AEnum,AEnum> f9 = new LinkedHashMap<AEnum,AEnum>();
+
+		public A init() {
+			f1 = AEnum.FOO;
+			f2 = AEnum.BAR;
+			f3 = new AEnum[]{AEnum.FOO,null};
+			f4 = new AEnum[][]{{AEnum.FOO,null},null};
+			f5 = new ArrayList<AEnum>(){{add(AEnum.FOO);}};
+			f6 = new ArrayList<AEnum>(){{add(AEnum.FOO);}};
+			f7 = new HashSet<AEnum>(){{add(AEnum.FOO);}};
+			f8 = new HashSet<AEnum>(){{add(AEnum.FOO);}};
+
+			return this;
+		}
+	}
+
+	public static class B {
+
+		// Should have 'enum' attribute.
+		public BEnum f1;
+
+		private BEnum f2;
+		public BEnum getF2() {return f2;}
+		public void setF2(BEnum f2) {this.f2 = f2;}
+
+		public BEnum[] f3;
+		public BEnum[][] f4;
+
+		// Should not have 'uniqueSet' attribute.
+		public List<BEnum> f5 = new LinkedList<BEnum>();
+
+		private List<BEnum> f6 = new LinkedList<BEnum>();
+		public List<BEnum> getF6() {return f6;}
+		public void setF6(List<BEnum> f6) {this.f6 = f6;}
+
+		// Should have 'uniqueSet' attribute.
+		public Set<BEnum> f7 = new HashSet<BEnum>();
+
+		private Set<BEnum> f8 = new HashSet<BEnum>();
+		public Set<BEnum> getF8() {return f8;}
+		public void setF8(Set<BEnum> f8) {this.f8 = f8;}
+
+		public Map<BEnum,BEnum> f9 = new LinkedHashMap<BEnum,BEnum>();
+
+		public B init() {
+			f1 = BEnum.FOO;
+			f2 = BEnum.BAR;
+			f3 = new BEnum[]{BEnum.FOO,null};
+			f4 = new BEnum[][]{{BEnum.FOO,null},null};
+			f5 = new ArrayList<BEnum>(){{add(BEnum.FOO);}};
+			f6 = new ArrayList<BEnum>(){{add(BEnum.FOO);}};
+			f7 = new HashSet<BEnum>(){{add(BEnum.FOO);}};
+			f8 = new HashSet<BEnum>(){{add(BEnum.FOO);}};
+
+			return this;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
new file mode 100755
index 0000000..51a6eb0
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
@@ -0,0 +1,97 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+public class RoundTripGenericsTest extends RoundTripTest {
+
+	public RoundTripGenericsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// testBeansWithUnboundTypeVars
+	//====================================================================================================
+	@SuppressWarnings("rawtypes")
+	@Test
+	public void testBeansWithUnboundTypeVars() throws Exception {
+
+		if (returnOriginalObject)
+			return;
+
+		// Unbound type variables should be interpreted as Object.
+		// During parsing, these become ObjectMaps.
+		Pair pair = new Pair<Source,Target>(new Source().init(), new Target().init());
+		pair = roundTrip(pair);
+		assertSortedObjectEquals("{s:{s1:'a1'},t:{t1:'b1'}}", pair);
+		assertEquals("ObjectMap", pair.getS().getClass().getSimpleName());
+		assertEquals("ObjectMap", pair.getT().getClass().getSimpleName());
+
+		// If you specify a concrete class, the type variables become bound and
+		// the property types correctly resolve.
+		pair = roundTrip(pair, RealPair.class);
+		assertSortedObjectEquals("{s:{s1:'a1'},t:{t1:'b1'}}", pair);
+		assertEquals("Source", pair.getS().getClass().getSimpleName());
+		assertEquals("Target", pair.getT().getClass().getSimpleName());
+	}
+
+	// Class with unbound type variables.
+	@Bean(properties={"s","t"})
+	public static class Pair<S,T> {
+		private S s;
+		private T t;
+
+		public Pair() {}
+
+		public Pair(S s, T t) {
+			this.s = s;
+			this.t = t;
+		}
+
+		// Getters/setters
+		public S getS() { return s; }
+		public void setS(S s) { this.s = s; }
+		public T getT() { return t; }
+		public void setT(T t) { this.t = t; }
+	}
+
+	// Sublcass with bound type variables.
+	public static class RealPair extends Pair<Source,Target> {}
+
+	public static class Source {
+		public String s1;
+		public Source init() {
+			this.s1 = "a1";
+			return this;
+		}
+	}
+
+	public static class Target {
+		public String t1;
+		public Target init() {
+			this.t1 = "b1";
+			return this;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
new file mode 100755
index 0000000..9e46375
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
@@ -0,0 +1,193 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.a.rttests.RoundTripTest.Flags.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.apache.juneau.urlencoding.UonSerializerContext.*;
+import static org.apache.juneau.xml.XmlSerializerContext.*;
+
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.html.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.msgpack.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+import org.junit.runners.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@Ignore
+@SuppressWarnings({"hiding","serial"})
+public class RoundTripLargeObjectsTest extends RoundTripTest {
+
+	private static final int NUM_RUNS = 10;
+	private static final int SIZE_PARAM = 20000;
+
+	public RoundTripLargeObjectsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@Parameterized.Parameters
+	public static Collection<Object[]> getPairs() {
+		return Arrays.asList(new Object[][] {
+			// Full round-trip testing
+			{ /* 0 */
+				"Json DEFAULT",
+				new JsonSerializer().setProperty(SERIALIZER_trimNullProperties, false),
+				JsonParser.DEFAULT,
+				0
+			},
+			{ /* 1 */
+				"Json DEFAULT_LAX",
+				new JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, false),
+				JsonParser.DEFAULT,
+				0
+			},
+			{ /* 2 */
+				"Json DEFAULT_SQ",
+				new JsonSerializer.Simple().setProperty(SERIALIZER_trimNullProperties, false),
+				JsonParser.DEFAULT,
+				0
+			},
+			{ /* 3 */
+				"Xml DEFAULT w/namespaces,validation",
+				new XmlSerializer.XmlJsonSq().setProperty(SERIALIZER_trimNullProperties, false).setProperty(XML_addNamespaceUrisToRoot, true).setProperty(SERIALIZER_useIndentation, true),
+				XmlParser.DEFAULT,
+				CHECK_XML_WHITESPACE | VALIDATE_XML
+			},
+			{ /* 4 */
+				"Xml DEFAULT wo/namespaces,validation",
+				new XmlSerializer.SimpleXmlJsonSq().setProperty(SERIALIZER_trimNullProperties, false),
+				XmlParser.DEFAULT,
+				CHECK_XML_WHITESPACE
+			},
+			{ /* 5 */
+				"Html",
+				new HtmlSerializer().setProperty(SERIALIZER_trimNullProperties, false),
+				HtmlParser.DEFAULT,
+				CHECK_XML_WHITESPACE
+			},
+			{ /* 6 */
+				"UrlEncoding",
+				new UrlEncodingSerializer().setProperty(SERIALIZER_trimNullProperties, false).setProperty(UON_simpleMode, false),
+				UrlEncodingParser.DEFAULT,
+				0
+			},
+			{ /* 7 */
+				"Uon",
+				new UonSerializer().setProperty(SERIALIZER_trimNullProperties, false).setProperty(UON_simpleMode, false),
+				UonParser.DEFAULT,
+				0
+			},
+			{ /* 8 */
+				"MsgPack",
+				new MsgPackSerializer().setProperty(SERIALIZER_trimNullProperties, false).setProperty(UON_simpleMode, false),
+				MsgPackParser.DEFAULT,
+				0
+			},
+//			{ /* 9 */
+//				"Rdf.Xml",
+//				new RdfSerializer.Xml().setProperty(SERIALIZER_trimNullProperties, false).setProperty(RDF_addLiteralTypes, true),
+//				RdfParser.DEFAULT_XML,
+//				0
+//			},
+//			{ /* 10 */
+//				"Rdf.XmlAbbrev",
+//				new RdfSerializer.XmlAbbrev().setProperty(SERIALIZER_trimNullProperties, false).setProperty(RDF_addLiteralTypes, true),
+//				RdfParser.DEFAULT_XML,
+//				0
+//			},
+//			{ /* 11 */
+//				"Rdf.Turtle",
+//				new RdfSerializer.Turtle().setProperty(SERIALIZER_trimNullProperties, false).setProperty(RDF_addLiteralTypes, true),
+//				RdfParser.DEFAULT_TURTLE,
+//				0
+//			},
+//			{ /* 12 */
+//				"Rdf.NTriple",
+//				new RdfSerializer.NTriple().setProperty(SERIALIZER_trimNullProperties, false).setProperty(RDF_addLiteralTypes, true),
+//				RdfParser.DEFAULT_NTRIPLE,
+//				0
+//			},
+//			{ /* 13 */
+//				"Rdf.N3",
+//				new RdfSerializer.N3().setProperty(SERIALIZER_trimNullProperties, false).setProperty(RDF_addLiteralTypes, true),
+//				RdfParser.DEFAULT_N3,
+//				0
+//			},
+		});
+	}
+
+	//====================================================================================================
+	// test
+	//====================================================================================================
+	@Test
+	public void testLargeMap() throws Exception {
+		long startTime;
+		int numRuns = NUM_RUNS;
+
+		A a = A.create();
+		Serializer s = getSerializer();
+		Parser p = getParser();
+		System.err.println("\n---Speed test on " + label + "---");
+		Object r = "";
+
+		// Initialization run.
+		r = s.serialize(a);
+		System.err.println(MessageFormat.format("Serialized size: {0,number} ", (r instanceof String ? r.toString().length() : ((byte[])r).length)));
+		p.parse(r, A.class);
+
+		startTime = System.currentTimeMillis();
+		for (int i = 0; i < numRuns; i++)
+			r = s.serialize(a);
+		System.err.println(MessageFormat.format("Average serialize time: {0,number}ms", (System.currentTimeMillis()-startTime)/numRuns));
+		startTime = System.currentTimeMillis();
+		for (int i = 0; i < numRuns; i++)
+			a = p.parse(r, A.class);
+		System.err.println(MessageFormat.format("Average parsed time: {0,number}ms", (System.currentTimeMillis()-startTime)/numRuns));
+	}
+
+	public static class A {
+		public A1Map a1Map;
+		public A1List a1List;
+		public A1[] a1Array;
+
+		static A create() {
+			A a = new A();
+			a.a1Map = new A1Map();
+			a.a1List = new A1List();
+			for (int i = 0; i < SIZE_PARAM; i++) {
+				a.a1Map.put(String.valueOf(i), new A1());
+				a.a1List.add(new A1());
+			}
+			a.a1Array = a.a1List.toArray(new A1[0]);
+			return a;
+		}
+	}
+
+	public static class A1 {
+		public String f1 = "a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j123456789";
+	}
+
+	public static class A1Map extends LinkedHashMap<String,A1> {}
+
+	public static class A1List extends LinkedList<A1> {}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
new file mode 100755
index 0000000..dbc7dff
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
@@ -0,0 +1,215 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.html.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transforms.*;
+import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings({"unchecked","deprecation"})
+public class RoundTripMapsTest extends RoundTripTest {
+
+	public RoundTripMapsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@Override /* RoundTripTest */
+	public Class<?>[] getTransforms() {
+		return new Class<?>[]{
+			ByteArrayBase64Transform.class,
+			DateTransform.ISO8601DTZ.class,
+			CalendarLongTransform.class,
+		};
+	}
+
+	//====================================================================================================
+	// Map<Integer,String> test
+	//====================================================================================================
+	@Test
+	public void testMapIntegerString() throws Exception {
+		Map<Integer,String> t = new TreeMap<Integer,String>();
+		t.put(1, "a");
+		t.put(2, null);
+		t = roundTripMap(t, TreeMap.class, Integer.class, String.class);
+		assertEquals("a", t.get(1));
+		assertNull(null, t.get(2));
+
+		t = new HashMap<Integer,String>();
+		t.put(1, "a");
+		t.put(2, null);
+		t.put(null, "b");
+		t = roundTripMap(t, HashMap.class, Integer.class, String.class);
+		assertEquals("a", t.get(1));
+		assertNull(t.get(2));
+		assertEquals("b", t.get(null));
+	}
+
+	//====================================================================================================
+	// Map<Boolean,String> test
+	//====================================================================================================
+	@Test
+	public void testMapBooleanString() throws Exception {
+		Map<Boolean,String> t = new TreeMap<Boolean,String>();
+		t.put(true, "a");
+		t.put(false, null);
+		t = roundTripMap(t, TreeMap.class, Boolean.class, String.class);
+		assertEquals("a", t.get(true));
+		assertNull(null, t.get(false));
+
+		t = new HashMap<Boolean,String>();
+		t.put(true, "a");
+		t.put(false, null);
+		t.put(null, "b");
+		t = roundTripMap(t, HashMap.class, Boolean.class, String.class);
+		assertEquals("a", t.get(true));
+		assertNull(t.get(false));
+		assertEquals("b", t.get(null));
+	}
+
+	//====================================================================================================
+	// Map<byte[],String> test
+	//====================================================================================================
+	@Test
+	public void testMapByteArrayString() throws Exception {
+
+		// Note, you cannot really test maps with byte[] keys since byte[] does not test for equality.
+		// So just test serialization.
+		String e;
+		Object r;
+
+		Map<byte[],String> t = new LinkedHashMap<byte[],String>();
+		t.put(new byte[]{1,2,3}, "a");
+		t.put(new byte[]{4,5,6}, null);
+		t.put(null, "b");
+
+		s = new JsonSerializer.Simple().addTransforms(getTransforms()).setProperty(SERIALIZER_trimNullProperties, false);
+		e = "{AQID:'a',BAUG:null,null:'b'}";
+		r = s.serialize(t);
+		assertEquals(e, r);
+
+		s = new XmlSerializer.SimpleXmlJsonSq().addTransforms(getTransforms()).setProperty(SERIALIZER_trimNullProperties, false);
+		e = "<object><AQID>a</AQID><BAUG nil='true'/><_x0000_>b</_x0000_></object>";
+		r = s.serialize(t);
+		assertEquals(e, r);
+
+		s = new HtmlSerializer.Sq().addTransforms(getTransforms()).setProperty(SERIALIZER_trimNullProperties, false);
+		e = "<table type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>AQID</string></td><td><string>a</string></td></tr><tr><td><string>BAUG</string></td><td><null/></td></tr><tr><td><null/></td><td><string>b</string></td></tr></table>";
+		r = s.serialize(t);
+		assertEquals(e, r);
+
+		s = new UonSerializer.Encoding().addTransforms(getTransforms()).setProperty(SERIALIZER_trimNullProperties, false);
+		e = "$o(AQID=a,BAUG=%00,%00=b)";
+		r = s.serialize(t);
+		assertEquals(e, r);
+
+		s = new UrlEncodingSerializer().addTransforms(getTransforms()).setProperty(SERIALIZER_trimNullProperties, false);
+		e = "AQID=a&BAUG=%00&%00=b";
+		r = s.serialize(t);
+		assertEquals(e, r);
+	}
+
+	//====================================================================================================
+	// Map<Date,String> test
+	//====================================================================================================
+	@Test
+	public void testMapDateString() throws Exception {
+		Date td1 = new Date(1,2,3,4,5,6);
+		Date td2 = new Date(2,3,4,5,6,7);
+
+		Map<Date,String> t = new TreeMap<Date,String>();
+		t.put(td1, "a");
+		t.put(td2, null);
+		t = roundTripMap(t, TreeMap.class, Date.class, String.class);
+		assertEquals("a", t.get(td1));
+		assertNull(null, t.get(td2));
+
+		t = new HashMap<Date,String>();
+		t.put(td1, "a");
+		t.put(td2, null);
+		t.put(null, "b");
+		t = roundTripMap(t, HashMap.class, Date.class, String.class);
+		assertEquals("a", t.get(td1));
+		assertNull(t.get(td2));
+		assertEquals("b", t.get(null));
+	}
+
+	//====================================================================================================
+	// Map<Calendar,String> test
+	//====================================================================================================
+	@Test
+	public void testMapCalendarString() throws Exception {
+		Calendar td1 = new GregorianCalendar();
+		td1.setTime(new Date(1,2,3,4,5,6));
+		Calendar td2 = new GregorianCalendar();
+		td2.setTime(new Date(2,3,4,5,6,7));
+
+		Map<Calendar,String> t = new TreeMap<Calendar,String>();
+		t.put(td1, "a");
+		t.put(td2, null);
+		t = roundTripMap(t, TreeMap.class, GregorianCalendar.class, String.class);
+		assertEquals("a", t.get(td1));
+		assertNull(null, t.get(td2));
+
+		t = new HashMap<Calendar,String>();
+		t.put(td1, "a");
+		t.put(td2, null);
+		t.put(null, "b");
+		t = roundTripMap(t, HashMap.class, GregorianCalendar.class, String.class);
+		assertEquals("a", t.get(td1));
+		assertNull(t.get(td2));
+		assertEquals("b", t.get(null));
+	}
+
+	//====================================================================================================
+	// Map<Enum,String> test
+	//====================================================================================================
+	@Test
+	public void testMapEnumString() throws Exception {
+
+		Map<TestEnum,String> t = new TreeMap<TestEnum,String>();
+		t.put(TestEnum.FOO, "a");
+		t.put(TestEnum.BAR, null);
+		t = roundTripMap(t, TreeMap.class, TestEnum.class, String.class);
+		assertEquals("a", t.get(TestEnum.FOO));
+		assertNull(null, t.get(TestEnum.BAR));
+
+		t = new HashMap<TestEnum,String>();
+		t.put(TestEnum.FOO, "a");
+		t.put(TestEnum.BAR, null);
+		t.put(null, "b");
+		t = roundTripMap(t, HashMap.class, TestEnum.class, String.class);
+		assertEquals("a", t.get(TestEnum.FOO));
+		assertNull(t.get(TestEnum.BAR));
+		assertEquals("b", t.get(null));
+	}
+
+	public enum TestEnum {
+		FOO,BAR,BAZ
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
new file mode 100644
index 0000000..e7848d9
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
@@ -0,0 +1,54 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.text.*;
+import java.util.*;
+
+import org.apache.juneau.dto.jsonschema.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings("hiding")
+public class RoundTripNumericConstructorsTest extends RoundTripTest {
+
+	public RoundTripNumericConstructorsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// Test parsing numbers to dates.
+	//====================================================================================================
+	@Test
+	public void testParseNumberToDate() throws Exception {
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer();
+		Parser p = getParser();
+		Date d = new Date(100, 1, 1);
+
+		Object r = s.serialize(d.getTime());
+		Date d2 = p.parse(r, Date.class);
+		assertEquals(d.getTime(), d2.getTime());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
new file mode 100755
index 0000000..557f600
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
@@ -0,0 +1,272 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+/**
+ * Tests to ensure the valueOf(String), fromString(String), parse(String), and parseString(String) methods
+ * are used correctly by parsers.
+ */
+@SuppressWarnings("unused")
+public class RoundTripObjectsAsStringsTest extends RoundTripTest {
+
+	public RoundTripObjectsAsStringsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// testBasic
+	//====================================================================================================
+	@Test
+	public void testBasic() throws Exception {
+		A t = new A().init();
+		t = roundTrip(t);
+		assertObjectEquals("{a1:{f:'1'},a2:{f:'2'},a3:{f:'3'},a4:{f:'4'}}", t);
+	}
+
+	public static class A {
+		public A1 a1;
+		public A2 a2;
+		public A3 a3;
+		public A4 a4;
+
+		public A init() {
+			a1 = new A1();
+			a1.f = "1";
+			a2 = new A2();
+			a2.f = "2";
+			a3 = new A3();
+			a3.f = "3";
+			a4 = new A4();
+			a4.f = "4";
+			return this;
+		}
+	}
+
+	public static class A1 {
+		public String f;
+		public static A1 fromString(String s) {
+			A1 x = new A1();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "A1-" + f;
+		}
+	}
+
+	public static class A2 {
+		public String f;
+		public static A2 valueOf(String s) {
+			A2 x = new A2();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "A2-" + f;
+		}
+	}
+
+	public static class A3 {
+		public String f;
+		public static A3 parse(String s) {
+			A3 x = new A3();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "A3-" + f;
+		}
+	}
+
+	public static class A4 {
+		public String f;
+		public static A4 parseString(String s) {
+			A4 x = new A4();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "A4-" + f;
+		}
+	}
+
+	//====================================================================================================
+	// testEnumWithOverriddenStringValue
+	// The B1 enum should serialize as "X1" but the B2 enum should serialize as "X-1".
+	//====================================================================================================
+	@Test
+	public void testEnumWithOverriddenStringValue() throws Exception {
+		B t = new B().init();
+		if (! returnOriginalObject) {
+			Object r = getSerializer().serialize(t);
+			assertTrue(TestUtils.toString(r).contains("X-2"));
+		}
+		t = roundTrip(t);
+		assertObjectEquals("{b1:'X1',b2:'X-2'}", t);
+	}
+
+	public static class B {
+		public B1 b1;
+		public B2 b2;
+
+		public B init() {
+			b1 = B1.X1;
+			b2 = B2.X2;
+			return this;
+		}
+
+	}
+
+	public static enum B1 {
+		X1(1),
+		X2(2),
+		X3(3);
+
+		private int i;
+		B1(int i) {
+			this.i = i;
+		}
+	}
+
+	public static enum B2 {
+		X1(1),
+		X2(2),
+		X3(3);
+
+		private int i;
+		B2(int i) {
+			this.i = i;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return "X-" + i;
+		}
+
+		public static B2 fromString(String s) {
+			return valueOf("X" + s.substring(2));
+		}
+	}
+
+	//====================================================================================================
+	// testMethodOrdering
+	//====================================================================================================
+	@Test
+	public void testOrdering() throws Exception {
+		C t = new C().init();
+		t = roundTrip(t);
+		assertObjectEquals("{c1:{f:'1'},c2:{f:'2'},c3:{f:'3'},c4:{f:'4'}}", t);
+	}
+
+	public static class C {
+		public C1 c1;
+		public C2 c2;
+		public C3 c3;
+		public C4 c4;
+
+		public C init() {
+			c1 = new C1();
+			c1.f = "1";
+			c2 = new C2();
+			c2.f = "2";
+			c3 = new C3();
+			c3.f = "3";
+			c4 = new C4();
+			c4.f = "4";
+			return this;
+		}
+	}
+
+	public static class C1 {
+		public String f;
+		public static C2 valueOf(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C2 parse(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C2 parseString(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C1 fromString(String s) {
+			C1 x = new C1();
+			x.f = s.substring(3);
+			return x;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return "C1-" + f;
+		}
+	}
+
+	public static class C2 {
+		public String f;
+		public static C2 parse(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C2 parseString(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C2 valueOf(String s) {
+			C2 x = new C2();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "C2-" + f;
+		}
+	}
+
+	public static class C3 {
+		public String f;
+		public static C2 parseString(String s) {
+			throw new RuntimeException("Shouldn't be called!");
+		}
+		public static C3 parse(String s) {
+			C3 x = new C3();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "C3-" + f;
+		}
+	}
+
+	public static class C4 {
+		public String f;
+		public static C4 parseString(String s) {
+			C4 x = new C4();
+			x.f = s.substring(3);
+			return x;
+		}
+		@Override /* Object */
+		public String toString() {
+			return "C4" + f;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
new file mode 100755
index 0000000..19f83dd
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
@@ -0,0 +1,116 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+
+
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+public class RoundTripObjectsWithSpecialMethodsTest extends RoundTripTest {
+
+	public RoundTripObjectsWithSpecialMethodsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// @NameProperty method.
+	//====================================================================================================
+	@Test
+	public void testNameProperty() throws Exception {
+		A t = new A().init();
+		t = roundTrip(t);
+		assertObjectEquals("{a2:{f2:2},m:{k1:{f2:2}}}", t);
+		if (isValidationOnly())
+			return;
+		assertEquals("a2", t.a2.name);
+		assertEquals("k1", t.m.get("k1").name);
+	}
+
+	public static class A {
+		public A2 a2;
+		public Map<String,A2> m;
+
+		A init() {
+			a2 = new A2().init();
+			m = new LinkedHashMap<String,A2>();
+			m.put("k1", new A2().init());
+			return this;
+		}
+
+	}
+	public static class A2 {
+		String name;
+		public int f2;
+
+		@NameProperty
+		protected void setName(String name) {
+			this.name = name;
+		}
+
+		A2 init() {
+			f2 = 2;
+			return this;
+		}
+	}
+
+	//====================================================================================================
+	// @ParentProperty method.
+	//====================================================================================================
+	@Test
+	public void testParentProperty() throws Exception {
+		B t = new B().init();
+		t = roundTrip(t);
+		if (isValidationOnly())
+			return;
+		assertEquals(t.f1, t.b2.parent.f1);
+	}
+
+	public static class B {
+		public int f1;
+		public B2 b2;
+
+		B init() {
+			f1 = 1;
+			b2 = new B2().init();
+			return this;
+		}
+
+	}
+	public static class B2 {
+		B parent;
+		public int f2;
+
+		@ParentProperty
+		protected void setParent(B parent) {
+			this.parent = parent;
+		}
+
+		B2 init() {
+			f2 = 2;
+			return this;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/df0f8689/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
----------------------------------------------------------------------
diff --git a/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
new file mode 100755
index 0000000..20520f0
--- /dev/null
+++ b/org.apache.juneau/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
@@ -0,0 +1,197 @@
+/***************************************************************************************************************************
+ * 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.a.rttests;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.jena.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.testbeans.*;
+import org.junit.*;
+
+/**
+ * Tests designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+public class RoundTripPrimitiveObjectBeansTest extends RoundTripTest {
+
+	public RoundTripPrimitiveObjectBeansTest(String label, Serializer s, Parser p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// testPrimitiveObjectsBean
+	//====================================================================================================
+	@Test
+	public void testPrimitiveObjectsBean() throws Exception {
+		PrimitiveObjectsBean t = new PrimitiveObjectsBean().init();
+		t = roundTrip(t, PrimitiveObjectsBean.class);
+		t = roundTrip(t, PrimitiveObjectsBean.class);
+
+		// primitives
+		assertEquals(Boolean.valueOf(true), t.poBoolean);
+		assertEquals(Byte.valueOf((byte)1), t.poByte);
+		assertEquals(Character.valueOf('a'), t.poChar);
+		assertEquals(Short.valueOf("2"), t.poShort);
+		assertEquals(Integer.valueOf(3), t.poInt);
+		assertEquals(Long.valueOf(4), t.poLong);
+		assertEquals(Float.valueOf(5), t.poFloat);
+		assertEquals(Double.valueOf(6), t.poDouble);
+		assertEquals(Integer.valueOf(7), t.poNumber);
+		assertEquals(8, t.poBigInteger.intValue());
+		assertTrue(t.poBigDecimal.floatValue() == 9f);
+
+		// uninitialized primitives
+		assertNull(t.pouBoolean);
+		assertNull(t.pouByte);
+		assertNull(t.pouChar);
+		assertNull(t.pouShort);
+		assertNull(t.pouInt);
+		assertNull(t.pouLong);
+		assertNull(t.pouFloat);
+		assertNull(t.pouDouble);
+		assertNull(t.pouNumber);
+		assertNull(t.pouBigInteger);
+		assertNull(t.pouBigDecimal);
+
+		// primitive arrays
+		assertEquals(Boolean.valueOf(false), t.poaBoolean[1][0]);
+		assertEquals(Byte.valueOf((byte)2), t.poaByte[1][0]);
+		assertEquals(Character.valueOf('b'), t.poaChar[1][0]);
+		assertEquals(Short.valueOf("2"), t.poaShort[1][0]);
+		assertEquals(Integer.valueOf(2), t.poaInt[1][0]);
+		assertEquals(Long.valueOf(2), t.poaLong[1][0]);
+		assertEquals(Float.valueOf(2), t.poaFloat[1][0]);
+		assertEquals(Double.valueOf(2), t.poaDouble[1][0]);
+		assertEquals(Integer.valueOf(2), t.poaNumber[1][0]);
+		assertEquals(2, t.poaBigInteger[1][0].intValue());
+		assertEquals(2, t.poaBigDecimal[1][0].intValue());
+		assertNull(t.poaBoolean[2]);
+		assertNull(t.poaByte[2]);
+		assertNull(t.poaChar[2]);
+		assertNull(t.poaShort[2]);
+		assertNull(t.poaInt[2]);
+		assertNull(t.poaLong[2]);
+		assertNull(t.poaFloat[2]);
+		assertNull(t.poaDouble[2]);
+		assertNull(t.poaNumber[2]);
+		assertNull(t.poaBigInteger[2]);
+		assertNull(t.poaBigDecimal[2]);
+
+		// uninitialized primitive arrays
+		assertNull(t.poauBoolean);
+		assertNull(t.poauByte);
+		assertNull(t.poauChar);
+		assertNull(t.poauShort);
+		assertNull(t.poauInt);
+		assertNull(t.poauLong);
+		assertNull(t.poauFloat);
+		assertNull(t.poauDouble);
+		assertNull(t.poauNumber);
+		assertNull(t.poauBigInteger);
+		assertNull(t.poauBigDecimal);
+
+		// anonymous list of object primitive arrays
+		assertEquals(Boolean.valueOf(true), t.poalBoolean.get(0)[0]);
+		assertEquals(Byte.valueOf((byte)1), t.poalByte.get(0)[0]);
+		assertEquals(Character.valueOf('a'), t.poalChar.get(0)[0]);
+		assertEquals(Short.valueOf((short)1), t.poalShort.get(0)[0]);
+		assertEquals(Integer.valueOf(1), t.poalInt.get(0)[0]);
+		assertEquals(Long.valueOf(1l), t.poalLong.get(0)[0]);
+		assertEquals(Float.valueOf(1f), t.poalFloat.get(0)[0]);
+		assertEquals(Double.valueOf(1d), t.poalDouble.get(0)[0]);
+		assertEquals(1, t.poalBigInteger.get(0)[0].intValue());
+		assertEquals(1, t.poalBigDecimal.get(0)[0].intValue());
+		assertNull(t.poalBoolean.get(1));
+		assertNull(t.poalByte.get(1));
+		assertNull(t.poalChar.get(1));
+		assertNull(t.poalShort.get(1));
+		assertNull(t.poalInt.get(1));
+		assertNull(t.poalLong.get(1));
+		assertNull(t.poalFloat.get(1));
+		assertNull(t.poalDouble.get(1));
+		assertNull(t.poalNumber.get(1));
+		assertNull(t.poalBigInteger.get(1));
+		assertNull(t.poalBigDecimal.get(1));
+
+		// regular list of object primitive arrays
+		assertEquals(Boolean.valueOf(true), t.polBoolean.get(0)[0]);
+		assertEquals(Byte.valueOf((byte)1), t.polByte.get(0)[0]);
+		assertEquals(Character.valueOf('a'), t.polChar.get(0)[0]);
+		assertEquals(Short.valueOf((short)1), t.polShort.get(0)[0]);
+		assertEquals(Integer.valueOf(1), t.polInt.get(0)[0]);
+		assertEquals(Long.valueOf(1l), t.polLong.get(0)[0]);
+		assertEquals(Float.valueOf(1f), t.polFloat.get(0)[0]);
+		assertEquals(Double.valueOf(1d), t.polDouble.get(0)[0]);
+		assertEquals(1, t.polBigInteger.get(0)[0].intValue());
+		assertEquals(1, t.polBigDecimal.get(0)[0].intValue());
+		assertNull(t.polBoolean.get(1));
+		assertNull(t.polByte.get(1));
+		assertNull(t.polChar.get(1));
+		assertNull(t.polShort.get(1));
+		assertNull(t.polInt.get(1));
+		assertNull(t.polLong.get(1));
+		assertNull(t.polFloat.get(1));
+		assertNull(t.polDouble.get(1));
+		assertNull(t.polNumber.get(1));
+		assertNull(t.polBigInteger.get(1));
+		assertNull(t.polBigDecimal.get(1));
+	}
+
+	//====================================================================================================
+	// testPrimitiveAtomicObjectsBean
+	//====================================================================================================
+	@Test
+	public void testPrimitiveAtomicObjectsBean() throws Exception {
+
+		// Jena does not support parsing into AtomicIntegers and AtomicLongs.
+		if (getSerializer() instanceof RdfSerializer)
+			return;
+
+		PrimitiveAtomicObjectsBean t = new PrimitiveAtomicObjectsBean().init();
+		t = roundTrip(t, PrimitiveAtomicObjectsBean.class);
+		t = roundTrip(t, PrimitiveAtomicObjectsBean.class);
+
+		// primitives
+		assertEquals(1, t.poAtomicInteger.intValue());
+		assertEquals(2, t.poAtomicLong.intValue());
+
+		// uninitialized primitives
+		assertNull(t.pouAtomicInteger);
+		assertNull(t.pouAtomicLong);
+
+		// primitive arrays
+		assertEquals(2, t.poaAtomicInteger[1][0].intValue());
+		assertEquals(2, t.poaAtomicLong[1][0].intValue());
+		assertNull(t.poaAtomicInteger[2]);
+		assertNull(t.poaAtomicLong[2]);
+
+		// uninitialized primitive arrays
+		assertNull(t.poauAtomicInteger);
+		assertNull(t.poauAtomicLong);
+
+		// anonymous list of object primitive arrays
+		assertEquals(1, t.poalAtomicInteger.get(0)[0].intValue());
+		assertEquals(1, t.poalAtomicLong.get(0)[0].intValue());
+		assertNull(t.poalAtomicInteger.get(1));
+		assertNull(t.poalAtomicLong.get(1));
+
+		// regular list of object primitive arrays
+		assertEquals(1, t.polAtomicInteger.get(0)[0].intValue());
+		assertEquals(1, t.polAtomicLong.get(0)[0].intValue());
+		assertNull(t.polAtomicInteger.get(1));
+		assertNull(t.polAtomicLong.get(1));
+	}
+
+}