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 2017/09/02 14:11:06 UTC

[44/51] [partial] incubator-juneau git commit: Add project hierarchies, part 1

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
new file mode 100755
index 0000000..3101903
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
@@ -0,0 +1,169 @@
+// ***************************************************************************************************************************
+// * 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;
+
+import static org.apache.juneau.Visibility.*;
+import static org.junit.Assert.*;
+
+import org.apache.juneau.a.*;
+import org.apache.juneau.json.*;
+import org.junit.*;
+
+@SuppressWarnings("javadoc")
+public class VisibilityTest {
+
+	//====================================================================================================
+	// testVisibility
+	//====================================================================================================
+	@Test
+	public void testClassDefault() throws Exception {
+		JsonSerializerBuilder s1 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false);
+		JsonSerializerBuilder s2 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(PROTECTED);
+		JsonSerializerBuilder s3 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(Visibility.DEFAULT);
+		JsonSerializerBuilder s4 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(PRIVATE);
+
+		A1 a1 = A1.create();
+		String r;
+
+		s1.beanFieldVisibility(NONE);
+		s2.beanFieldVisibility(NONE);
+		s3.beanFieldVisibility(NONE);
+		s4.beanFieldVisibility(NONE);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f5:5}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f5:5}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f5:5}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f5:5}", r);
+
+		s1.beanFieldVisibility(PUBLIC);
+		s2.beanFieldVisibility(PUBLIC);
+		s3.beanFieldVisibility(PUBLIC);
+		s4.beanFieldVisibility(PUBLIC);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:{f1:1,f5:5},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:{f1:1,f5:5},g5:{f1:1,f5:5}}", r);
+
+		s1.beanFieldVisibility(PROTECTED);
+		s2.beanFieldVisibility(PROTECTED);
+		s3.beanFieldVisibility(PROTECTED);
+		s4.beanFieldVisibility(PROTECTED);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:{f1:1,f2:2,f5:5},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:{f1:1,f2:2,f5:5},g5:{f1:1,f2:2,f5:5}}", r);
+
+		s1.beanFieldVisibility(Visibility.DEFAULT);
+		s2.beanFieldVisibility(Visibility.DEFAULT);
+		s3.beanFieldVisibility(Visibility.DEFAULT);
+		s4.beanFieldVisibility(Visibility.DEFAULT);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:{f1:1,f2:2,f3:3,f5:5},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:{f1:1,f2:2,f3:3,f5:5},g5:{f1:1,f2:2,f3:3,f5:5}}", r);
+
+		s1.beanFieldVisibility(PRIVATE);
+		s2.beanFieldVisibility(PRIVATE);
+		s3.beanFieldVisibility(PRIVATE);
+		s4.beanFieldVisibility(PRIVATE);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:{f1:1,f2:2,f3:3,f4:4,f5:5},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:{f1:1,f2:2,f3:3,f4:4,f5:5},g5:{f1:1,f2:2,f3:3,f4:4,f5:5}}", r);
+
+		s1.methodVisibility(NONE);
+		s2.methodVisibility(NONE);
+		s3.methodVisibility(NONE);
+		s4.methodVisibility(NONE);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:{f1:1,f2:2,f3:3,f4:4},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:{f1:1,f2:2,f3:3,f4:4},g5:{f1:1,f2:2,f3:3,f4:4}}", r);
+
+		s1.methodVisibility(PROTECTED);
+		s2.methodVisibility(PROTECTED);
+		s3.methodVisibility(PROTECTED);
+		s4.methodVisibility(PROTECTED);
+
+		r = s1.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:'A3',g4:'A4',g5:'A5'}", r);
+
+		r = s2.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:'A4',g5:'A5'}", r);
+
+		r = s3.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g5:'A5'}", r);
+
+		r = s4.build().serialize(a1);
+		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g5:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6}}", r);
+
+	}
+
+	static class A {
+		public int f1;
+		public A(){}
+
+		static A create() {
+			A x = new A();
+			x.f1 = 1;
+			return x;
+		}
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
new file mode 100755
index 0000000..1ff1add
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
@@ -0,0 +1,70 @@
+// ***************************************************************************************************************************
+// * 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;
+
+import static javax.xml.stream.XMLStreamConstants.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import javax.xml.stream.*;
+
+import org.apache.juneau.parser.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Used to validate that the syntax of XML documents are valid.
+ */
+@SuppressWarnings({"unchecked","javadoc"})
+public class XmlValidatorParser extends XmlParser {
+
+	public XmlValidatorParser() {
+		super(PropertyStore.create());
+	}
+
+	@Override /* Parser */
+	public ReaderParserSession createSession(ParserSessionArgs args) {
+		return new ReaderParserSession(null, args) {
+
+			@Override
+			protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws Exception {
+				return (T)validate(pipe.getReader());
+			}
+			
+			@Override /* ReaderParser */
+			protected <K,V> Map<K,V> doParseIntoMap(ParserPipe pipe, Map<K,V> m, Type keyType, Type valueType) throws Exception {
+				return (Map<K,V>)validate(pipe.getReader());
+			}
+
+			@Override /* ReaderParser */
+			protected <E> Collection<E> doParseIntoCollection(ParserPipe pipe, Collection<E> c, Type elementType) throws Exception {
+				return (Collection<E>)validate(pipe.getReader());
+			}
+		};
+	}
+
+	public <T> T validate(Reader r) throws Exception {
+		XMLStreamReader sr = getStaxReader(r);
+		while(sr.next() != END_DOCUMENT){}
+		return null;
+	}
+
+	protected XMLStreamReader getStaxReader(Reader in) throws Exception {
+		XMLInputFactory factory = XMLInputFactory.newInstance();
+		factory.setProperty("javax.xml.stream.isNamespaceAware", false);
+		XMLStreamReader parser = factory.createXMLStreamReader(in);
+		parser.nextTag();
+		return parser;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
new file mode 100644
index 0000000..6d7f00b
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
@@ -0,0 +1,27 @@
+// ***************************************************************************************************************************
+// * 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;
+
+import org.apache.juneau.xml.*;
+
+public class XmlValidatorParserBuilder extends XmlParserBuilder {
+
+	public XmlValidatorParserBuilder() {
+		super(PropertyStore.create());
+	}
+
+	@Override
+	public XmlValidatorParser build() {
+		return new XmlValidatorParser();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/A1.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/A1.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/A1.java
new file mode 100755
index 0000000..5db099c
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/A1.java
@@ -0,0 +1,191 @@
+// ***************************************************************************************************************************
+// * 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;
+
+import org.apache.juneau.annotation.*;
+
+// Default class
+@SuppressWarnings({"unused","synthetic-access","javadoc"})
+@Bean(sort=true)
+public class A1 {
+	public int f1;
+	protected int f2;
+	int f3;
+	private int f4;
+
+	@BeanIgnore
+	private int f5, f6, f7, f8;
+
+	public int getF5() { return f5; }
+	public void setF5(int f5) { this.f5 = f5; }
+	protected int getF6() { return f6; }
+	protected void setF6(int f6) { this.f6 = f6; }
+	int getF7() { return f7; }
+	void setF7(int f7) { this.f7 = f7; }
+	private int getF8() { return f8; }
+	private void setF8(int f8) { this.f8 = f8; }
+
+	public A2 g2;
+	public A3 g3;
+	public A4 g4;
+	public A5 g5;
+
+	public static A1 create() {
+		A1 x = new A1();
+		x.f1 = 1;
+		x.f2 = 2;
+		x.f3 = 3;
+		x.f4 = 4;
+		x.f5 = 5;
+		x.f6 = 6;
+		x.f7 = 7;
+		x.f8 = 8;
+		x.g2 = new A2();
+		x.g2.f1 = 1;
+		x.g2.f2 = 2;
+		x.g2.f3 = 3;
+		x.g2.f4 = 4;
+		x.g2.f5 = 5;
+		x.g2.f6 = 6;
+		x.g2.f7 = 7;
+		x.g2.f8 = 8;
+		x.g3 = new A3();
+		x.g3.f1 = 1;
+		x.g3.f2 = 2;
+		x.g3.f3 = 3;
+		x.g3.f4 = 4;
+		x.g3.f5 = 5;
+		x.g3.f6 = 6;
+		x.g3.f7 = 7;
+		x.g3.f8 = 8;
+		x.g4 = new A4();
+		x.g4.f1 = 1;
+		x.g4.f2 = 2;
+		x.g4.f3 = 3;
+		x.g4.f4 = 4;
+		x.g4.f5 = 5;
+		x.g4.f6 = 6;
+		x.g4.f7 = 7;
+		x.g4.f8 = 8;
+		x.g5 = new A5();
+		x.g5.f1 = 1;
+		x.g5.f2 = 2;
+		x.g5.f3 = 3;
+		x.g5.f4 = 4;
+		x.g5.f5 = 5;
+		x.g5.f6 = 6;
+		x.g5.f7 = 7;
+		x.g5.f8 = 8;
+		return x;
+	}
+
+	@Bean(sort=true)
+	public static class A2 {
+		public int f1;
+		protected int f2;
+		int f3;
+		private int f4;
+
+		@BeanIgnore
+		private int f5, f6, f7, f8;
+
+		public int getF5() { return f5; }
+		public void setF5(int f5) { this.f5 = f5; }
+		protected int getF6() { return f6; }
+		protected void setF6(int f6) { this.f6 = f6; }
+		int getF7() { return f7; }
+		void setF7(int f7) { this.f7 = f7; }
+		private int getF8() { return f8; }
+		private void setF8(int f8) { this.f8 = f8; }
+
+		@Override /* Object */
+		public String toString() {
+			return "A2";
+		}
+	}
+
+	@Bean(sort=true)
+	protected static class A3 {
+		public int f1;
+		protected int f2;
+		int f3;
+		private int f4;
+
+		@BeanIgnore
+		private int f5, f6, f7, f8;
+
+		public int getF5() { return f5; }
+		public void setF5(int f5) { this.f5 = f5; }
+		protected int getF6() { return f6; }
+		protected void setF6(int f6) { this.f6 = f6; }
+		int getF7() { return f7; }
+		void setF7(int f7) { this.f7 = f7; }
+		private int getF8() { return f8; }
+		private void setF8(int f8) { this.f8 = f8; }
+
+		@Override /* Object */
+		public String toString() {
+			return "A3";
+		}
+	}
+
+	@Bean(sort=true)
+	static class A4 {
+		public int f1;
+		protected int f2;
+		int f3;
+		private int f4;
+
+		@BeanIgnore
+		private int f5, f6, f7, f8;
+
+		public int getF5() { return f5; }
+		public void setF5(int f5) { this.f5 = f5; }
+		protected int getF6() { return f6; }
+		protected void setF6(int f6) { this.f6 = f6; }
+		int getF7() { return f7; }
+		void setF7(int f7) { this.f7 = f7; }
+		private int getF8() { return f8; }
+		private void setF8(int f8) { this.f8 = f8; }
+
+		@Override /* Object */
+		public String toString() {
+			return "A4";
+		}
+	}
+
+	@Bean(sort=true)
+	private static class A5 {
+		public int f1;
+		protected int f2;
+		int f3;
+		private int f4;
+
+		@BeanIgnore
+		private int f5, f6, f7, f8;
+
+		public int getF5() { return f5; }
+		public void setF5(int f5) { this.f5 = f5; }
+		protected int getF6() { return f6; }
+		protected void setF6(int f6) { this.f6 = f6; }
+		int getF7() { return f7; }
+		void setF7(int f7) { this.f7 = f7; }
+		private int getF8() { return f8; }
+		private void setF8(int f8) { this.f8 = f8; }
+
+		@Override /* Object */
+		public String toString() {
+			return "A5";
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
new file mode 100755
index 0000000..d607d04
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
@@ -0,0 +1,357 @@
+// ***************************************************************************************************************************
+// * 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.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.html.*;
+import org.apache.juneau.jena.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.msgpack.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
+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.
+ */
+@SuppressWarnings("javadoc")
+public class RoundTripAddClassAttrsTest extends RoundTripTest {
+
+	@Parameterized.Parameters
+	public static Collection<Object[]> getPairs() {
+		return Arrays.asList(new Object[][] {
+			{ /* 0 */
+				"JsonSerializer.DEFAULT/JsonParser.DEFAULT",
+				new JsonSerializerBuilder().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 1 */
+				"JsonSerializer.DEFAULT_LAX/JsonParser.DEFAULT",
+				new JsonSerializerBuilder().simple().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 2 */
+				"JsonSerializer.DEFAULT_SQ/JsonParser.DEFAULT",
+				new JsonSerializerBuilder().simple().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 3 */
+				"XmlSerializer.DEFAULT/XmlParser.DEFAULT",
+				new XmlSerializerBuilder().addBeanTypeProperties(true),
+				new XmlParserBuilder().useInterfaceProxies(false),
+				CHECK_XML_WHITESPACE | VALIDATE_XML
+			},
+			{ /* 4 */
+				"HtmlSerializer.DEFAULT/HtmlParser.DEFAULT",
+				new HtmlSerializerBuilder().addBeanTypeProperties(true),
+				new HtmlParserBuilder().useInterfaceProxies(false),
+				CHECK_XML_WHITESPACE
+			},
+			{ /* 5 */
+				"UonSerializer.DEFAULT_ENCODING/UonParser.DEFAULT_DECODING",
+				new UonSerializerBuilder().encoding().addBeanTypeProperties(true),
+				new UonParserBuilder().decoding().useInterfaceProxies(false),
+				0
+			},
+			{ /* 6 */
+				"UonSerializer.DEFAULT/UonParser.DEFAULT",
+				new UonSerializerBuilder().addBeanTypeProperties(true),
+				new UonParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 7 */
+				"UrlEncodingSerializer.DEFAULT/UrlEncodingParser.DEFAULT",
+				new UrlEncodingSerializerBuilder().addBeanTypeProperties(true),
+				new UrlEncodingParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 8 */
+				"RdfSerializer.Xml/RdfParser.Xml",
+				new RdfSerializerBuilder().addBeanTypeProperties(true),
+				new RdfParserBuilder().useInterfaceProxies(false),
+				0
+			},
+			{ /* 9 */
+				"MsgPackSerializer.DEFAULT/MsgPackParser.DEFAULT",
+				new MsgPackSerializerBuilder().addBeanTypeProperties(true),
+				new MsgPackParserBuilder().useInterfaceProxies(false),
+				0
+			}
+		});
+	}
+
+	public RoundTripAddClassAttrsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@Override
+	public Class<?>[] getDictionary() {
+		return new Class<?>[]{A.class, B.class, C.class, D.class, E.class, F.class};
+	}
+
+	//====================================================================================================
+	// testBean
+	//====================================================================================================
+	@Test
+	public void testBean() throws Exception {
+		A t = new A("foo");
+		AA ta;
+		IA ti;
+
+		t = roundTrip(t, A.class);
+		assertEquals("foo", t.getF1());
+
+		ta = roundTrip(t, AA.class);
+		assertEquals("foo", ta.getF1());
+
+		ti = roundTrip(t, IA.class);
+		assertEquals("foo", ti.getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.getF1());
+	}
+
+	public static interface IA {
+		public String getF1();
+		public void setF1(String f1);
+	}
+
+	public static abstract class AA implements IA {
+	}
+
+	@Bean(typeName="A")
+	public static class A extends AA {
+		private String f1;
+
+		@Override /* AA */
+		public String getF1() {
+			return f1;
+		}
+		@Override /* AA */
+		public void setF1(String f1) {
+			this.f1 = f1;
+		}
+
+		public A() {}
+		public A(String f1) {
+			this.f1 = f1;
+		}
+	}
+
+	//====================================================================================================
+	// testBeanArray
+	//====================================================================================================
+	@Test
+	public void testBeanArray() throws Exception {
+		A[] t = {new A("foo")};
+		AA[] ta;
+		IA[] ti;
+
+		t = roundTrip(t, A[].class);
+		assertEquals("foo", t[0].getF1());
+
+		ta = roundTrip(t, AA[].class);
+		assertEquals("foo", ta[0].getF1());
+
+		ti = roundTrip(t, IA[].class);
+		assertEquals("foo", ti[0].getF1());
+	}
+
+	//====================================================================================================
+	// testBeanWithBeanProps
+	//====================================================================================================
+	@Test
+	public void testBeanWithBeanProps() throws Exception {
+		B t = new B("foo");
+		t = roundTrip(t, B.class);
+		assertEquals("foo", t.f2a.getF1());
+		assertEquals("foo", t.f2b.getF1());
+		assertEquals("foo", t.f2c.getF1());
+		assertEquals("foo", ((A)t.f2d).getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.f2a.getF1());
+		assertEquals("foo", t.f2b.getF1());
+		assertEquals("foo", t.f2c.getF1());
+		assertEquals("foo", ((A)t.f2d).getF1());
+	}
+
+	@Bean(typeName="B")
+	public static class B {
+		public A f2a;
+		public AA f2b;
+		public IA f2c;
+		public Object f2d;
+		public B() {}
+		public B(String f1) {
+			f2d = f2c = f2b = f2a = new A(f1);
+		}
+	}
+
+	//====================================================================================================
+	// testMapsWithTypeParams - Maps with type parameters should not have class attributes on entries.
+	//====================================================================================================
+	@Test
+	public void testMapsWithTypeParams() throws Exception {
+		C t = new C("foo");
+		t = roundTrip(t, C.class);
+		assertEquals("foo", t.f3a.get("foo").getF1());
+		assertEquals("foo", t.f3b.get("foo").getF1());
+		assertEquals("foo", t.f3c.get("foo").getF1());
+		assertEquals("foo", t.f3d.get("foo").getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.f3a.get("foo").getF1());
+		assertEquals("foo", t.f3b.get("foo").getF1());
+		assertEquals("foo", t.f3c.get("foo").getF1());
+		assertEquals("foo", t.f3d.get("foo").getF1());
+	}
+
+	@Bean(typeName="C")
+	public static class C {
+		public Map<String,A> f3a = new HashMap<String,A>();
+		public Map<String,A> f3b = new HashMap<String,A>();
+		public Map<String,A> f3c = new HashMap<String,A>();
+		public Map<String,A> f3d = new HashMap<String,A>();
+
+		public C(){}
+		public C(String f1) {
+			A b = new A(f1);
+			f3a.put("foo", b);
+			f3b.put("foo", b);
+			f3c.put("foo", b);
+			f3d.put("foo", b);
+		}
+	}
+
+	//====================================================================================================
+	// testMapsWithoutTypeParams - Maps without type parameters should have class attributes on entries.
+	//====================================================================================================
+	@Test
+	public void testMapsWithoutTypeParams() throws Exception {
+		D t = new D("foo");
+		t = roundTrip(t, D.class);
+		assertEquals("foo", t.f4a[0].getF1());
+		assertEquals("foo", t.f4b[0].getF1());
+		assertEquals("foo", t.f4c[0].getF1());
+		assertEquals("foo", ((A)t.f4d[0]).getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.f4a[0].getF1());
+		assertEquals("foo", t.f4b[0].getF1());
+		assertEquals("foo", t.f4c[0].getF1());
+		assertEquals("foo", ((A)t.f4d[0]).getF1());
+	}
+
+	@Bean(typeName="D")
+	public static class D {
+		public A[] f4a;
+		public AA[] f4b;
+		public IA[] f4c;
+		public Object[] f4d;
+
+		public D(){}
+		public D(String f1) {
+			A b = new A(f1);
+			f4a = new A[]{b};
+			f4b = new AA[]{b};
+			f4c = new IA[]{b};
+			f4d = new Object[]{b};
+		}
+	}
+
+	//====================================================================================================
+	// testBeanWithListProps
+	//====================================================================================================
+	@Test
+	public void testBeanWithListProps() throws Exception {
+		E t = new E("foo");
+		t = roundTrip(t, E.class);
+		assertEquals("foo", t.f5a.get(0).getF1());
+		assertEquals("foo", t.f5b.get(0).getF1());
+		assertEquals("foo", t.f5c.get(0).getF1());
+		assertEquals("foo", ((A)t.f5d.get(0)).getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.f5a.get(0).getF1());
+		assertEquals("foo", t.f5b.get(0).getF1());
+		assertEquals("foo", t.f5c.get(0).getF1());
+		assertEquals("foo", ((A)t.f5d.get(0)).getF1());
+	}
+
+	@Bean(typeName="E")
+	public static class E {
+		public List<A> f5a = new LinkedList<A>();
+		public List<AA> f5b = new LinkedList<AA>();
+		public List<IA> f5c = new LinkedList<IA>();
+		public List<Object> f5d = new LinkedList<Object>();
+
+		public E(){}
+		public E(String f1) {
+			A b = new A(f1);
+			f5a.add(b);
+			f5b.add(b);
+			f5c.add(b);
+			f5d.add(b);
+		}
+	}
+
+	//====================================================================================================
+	// testBeanWithListOfArraysProps
+	//====================================================================================================
+	@Test
+	public void testBeanWithListOfArraysProps() throws Exception {
+		F t = new F("foo");
+		t = roundTrip(t, F.class);
+		assertEquals("foo", t.f6a.get(0)[0].getF1());
+		assertEquals("foo", t.f6b.get(0)[0].getF1());
+		assertEquals("foo", t.f6c.get(0)[0].getF1());
+		assertEquals("foo", ((A)t.f6d.get(0)[0]).getF1());
+
+		t = roundTrip(t, Object.class);
+		assertEquals("foo", t.f6a.get(0)[0].getF1());
+		assertEquals("foo", t.f6b.get(0)[0].getF1());
+		assertEquals("foo", t.f6c.get(0)[0].getF1());
+		assertEquals("foo", ((A)t.f6d.get(0)[0]).getF1());
+	}
+
+	@Bean(typeName="F")
+	public static class F {
+		public List<A[]> f6a = new LinkedList<A[]>();
+		public List<AA[]> f6b = new LinkedList<AA[]>();
+		public List<IA[]> f6c = new LinkedList<IA[]>();
+		public List<Object[]> f6d = new LinkedList<Object[]>();
+
+		public F(){}
+		public F(String f1) {
+			A[] b = {new A(f1)};
+			f6a.add(b);
+			f6b.add(b);
+			f6c.add(b);
+			f6d.add(b);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
new file mode 100755
index 0000000..dfe8dd6
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
@@ -0,0 +1,218 @@
+// ***************************************************************************************************************************
+// * 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 designed to serialize and parse objects to make sure we end up
+ * with the same objects for all serializers and parsers.
+ */
+@SuppressWarnings("javadoc")
+public class RoundTripBeanInheritanceTest extends RoundTripTest {
+
+	public RoundTripBeanInheritanceTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	//====================================================================================================
+	// testBeanInheritance
+	//====================================================================================================
+	@Test
+	public void testBeanInheritance() throws Exception {
+
+		// Skip tests that just return the same object.
+		if (returnOriginalObject)
+			return;
+
+		A2 t1 = new A2(), t2;
+		t1.init();
+		t2 = roundTrip(t1, A2.class);
+		assertEqualObjects(t1, t2);
+
+		A3 t3 = new A3();
+		t3.init();
+		try {
+			ClassMeta<?> cm = BeanContext.DEFAULT.getClassMeta(A3.class);
+			assertEquals("No properties detected on bean class", cm.getNotABeanReason());
+			roundTrip(t3, A3.class);
+			fail("Exception expected");
+		} catch (ParseException e) {
+		} catch (SerializeException e) {
+		} catch (InvalidDataConversionException e) {}
+	}
+
+
+	public static abstract class A1 {
+		protected String x = null;
+		protected String y = null;
+		protected String z = null;
+
+		public A1() {
+			this.x = null;
+			this.y = null;
+			this.z = null;
+		}
+
+		public A1(String x, String y, String z) {
+			this.x = x;
+			this.y = y;
+			this.z = z;
+		}
+
+		public void setX(String x) {
+			this.x = x;
+		}
+
+		public void setY(String y) {
+			this.y = y;
+		}
+
+		public void setZ(String z) {
+			this.z = z;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return ("A1(x: " + this.x + ", y: " + this.y + ", z: " + this.z + ")");
+		}
+
+		public A1 init() {
+			x = null;
+			y = "";
+			z = "z";
+			return this;
+		}
+	}
+
+	public static class A2 extends A1 {
+		public A2() {
+			super();
+		}
+
+		public A2(String x, String y, String z) {
+			super(x, y, z);
+		}
+
+		public String getX() {
+			return this.x;
+		}
+
+		public String getY() {
+			return this.y;
+		}
+
+		public String getZ() {
+			return this.z;
+		}
+	}
+
+	// This is not supposed to be a valid bean since it has no getters defined.
+	public static class A3 extends A1 {
+		public A3() {
+			super();
+		}
+
+		public A3(String x, String y, String z) {
+			super(x, y, z);
+		}
+
+		public String isX() {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public String isY() {
+			throw new RuntimeException("Should not be called!");
+		}
+
+		public String isZ() {
+			throw new RuntimeException("Should not be called!");
+		}
+	}
+
+	//====================================================================================================
+	// testBeanInheritance2
+	//====================================================================================================
+	@Test
+	public void testBeanInheritance2() throws Exception {
+		B1 t1 = new B1().init(), t2;
+		t2 = roundTrip(t1, B1.class);
+		assertEqualObjects(t1, t2);
+	}
+
+	public static class B1 extends B2 {
+		private A2 f4;
+
+		public A2 getF4() {
+			return this.f4;
+		}
+
+		public void setF4(A2 f4) {
+			this.f4 = f4;
+		}
+
+		@Override /* Object */
+		public String toString() {
+			return super.toString() + " / " + this.f4;
+		}
+
+		public B1 init() {
+			setF1("A1");
+			setF2(101);
+			setF3(false);
+			setF4((A2)new A2().init());
+			return this;
+		}
+	}
+
+	public static class B2 {
+		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 ("B2(f1: " + this.getF1() + ", f2: " + this.getF2() + ")");
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
new file mode 100755
index 0000000..35ba64a
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -0,0 +1,975 @@
+// ***************************************************************************************************************************
+// * 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.apache.juneau.utils.*;
+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","serial","javadoc"})
+public class RoundTripBeanMapsTest extends RoundTripTest {
+
+	public RoundTripBeanMapsTest(String label, SerializerBuilder s, ParserBuilder 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 AList<IBean>().append(new CBean());
+
+		l.get(0).setF1("bar");
+		l = roundTrip(l, List.class, IBean.class);
+		assertEquals("bar", l.get(0).getF1());
+		l = roundTrip(l, LinkedList.class, IBean.class);
+		assertEquals("bar", l.get(0).getF1());
+
+		l.get(0).setF1("baz");
+		l = roundTrip(l, List.class, ABean.class);
+		assertEquals("baz", l.get(0).getF1());
+		l = roundTrip(l, LinkedList.class, ABean.class);
+		assertEquals("baz", l.get(0).getF1());
+
+		l.get(0).setF1("bing");
+		l = roundTrip(l, List.class, CBean.class);
+		assertEquals("bing", l.get(0).getF1());
+		l = roundTrip(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 AMap<String,IBean>().append("foo", new CBean());
+
+		l.get("foo").setF1("bar");
+		l = roundTrip(l, Map.class, String.class, IBean.class);
+		assertEquals("bar", l.get("foo").getF1());
+		l = roundTrip(l, LinkedHashMap.class, String.class, IBean.class);
+		assertEquals("bar", l.get("foo").getF1());
+
+		l.get("foo").setF1("baz");
+		l = roundTrip(l, Map.class, String.class, ABean.class);
+		assertEquals("baz", l.get("foo").getF1());
+		l = roundTrip(l, LinkedHashMap.class, String.class, ABean.class);
+		assertEquals("baz", l.get("foo").getF1());
+
+		l.get("foo").setF1("bing");
+		l = roundTrip(l, Map.class, String.class, CBean.class);
+		assertEquals("bing", l.get("foo").getF1());
+		l = roundTrip(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 = new JsonSerializerBuilder().simple().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+		Parser p = getParser().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+
+		B1 b1 = B1.create();
+		Object r = s.serialize(b1);
+		B b = p.parse(r, B.class);
+		assertTrue(b instanceof B1);
+		assertObjectEquals("{_type:'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("{_type:'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("{_type:'B3',f0:'f0',f3:'2001-01-01T12:34:56.789Z'}", b, js);
+}
+
+	@Bean(
+		beanDictionary={B1.class,B2.class,B3.class}
+	)
+	public abstract static class B {
+		public String f0 = "f0";
+	}
+
+	@Bean(typeName="B1")
+	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;
+		}
+	}
+
+	@Bean(typeName="B2")
+	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;
+		}
+	}
+
+	@Bean(typeName="B3")
+	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 BeanFilter
+	//====================================================================================================
+	@Test
+	public void testSubTypesUsingBeanFilter() throws Exception {
+		JsonSerializer js = new JsonSerializerBuilder().simple().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().builder().beanFilters(CFilter.class).pojoSwaps(XMLGregorianCalendarSwap.class).build();
+		Parser p = getParser().builder().beanFilters(CFilter.class).pojoSwaps(XMLGregorianCalendarSwap.class).build();
+
+		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 CFilter extends BeanFilterBuilder {
+		public CFilter() {
+			super(C.class);
+			beanDictionary(CFilterDictionaryMap.class);
+		}
+	}
+
+	public static class CFilterDictionaryMap extends BeanDictionaryMap {
+		public CFilterDictionaryMap() {
+			addClass("C1", C1.class);
+			addClass("C2", C2.class);
+			addClass("C3", C3.class);
+		}
+	}
+
+	//====================================================================================================
+	// 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);
+		assertObjectEquals("{_type:'BA1',f0a:'f0a',f0b:'f0b',f1:'f1'}", b);
+	}
+
+	@Bean(beanDictionary={BA1.class,BA2.class})
+	public abstract static class BA {
+		public String f0a, f0b;
+	}
+
+	@Bean(typeName="BA1")
+	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";
+			return b;
+		}
+	}
+
+	@Bean(typeName="BA2")
+	public static class BA2 extends BA {
+		public String f2;
+	}
+
+
+	//====================================================================================================
+	// Test @Bean(subTypes=xxx) with real bean property using BeanFilter
+	//====================================================================================================
+	@Test
+	public void testSubTypePropertyWithRealPropertyUsingBeanFilter() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().builder().beanFilters(CAFilter.class).build();
+		Parser p = getParser().builder().beanFilters(CAFilter.class).build();
+
+		CA1 c1 = CA1.create();
+		Object r = s.serialize(c1);
+		CA c = p.parse(r, CA.class);
+		assertTrue(c instanceof CA1);
+		assertObjectEquals("{f0a:'f0a',f0b:'f0b',f1:'f1'}", c);
+	}
+
+	public abstract static class CA {
+		public String f0a, 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";
+			return c;
+		}
+	}
+
+	public static class CA2 extends CA {
+		public String f2;
+	}
+
+	public static class CAFilter extends BeanFilterBuilder {
+		public CAFilter() {
+			super(CA.class);
+			beanDictionary(CAFilterDictionaryMap.class);
+		}
+	}
+
+	public static class CAFilterDictionaryMap extends BeanDictionaryMap {
+		public CAFilterDictionaryMap() {
+			addClass("CA1", CA1.class);
+			addClass("CA2", CA2.class);
+		}
+	}
+
+	//====================================================================================================
+	// 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 BeanFilter
+	//====================================================================================================
+	@Test
+	public void testPropertiesUsingBeanFilter() throws Exception {
+		JsonSerializer js = new JsonSerializerBuilder().simple().beanFilters(D2Filter.class).build();
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().builder().beanFilters(D2Filter.class).build();
+		Parser p = getParser().builder().beanFilters(D2Filter.class).build();
+
+		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 D2Filter extends BeanFilterBuilder {
+		public D2Filter() {
+			super(D2.class);
+			properties("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 BeanFilter
+	//====================================================================================================
+	@Test
+	public void testExcludePropertiesUsingBeanFilter() throws Exception {
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		Serializer s = getSerializer().builder().beanFilters(E2Filter.class).build();
+		Parser p = getParser().builder().beanFilters(E2Filter.class).build();
+
+		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 E2Filter extends BeanFilterBuilder {
+		public E2Filter() {
+			super(E2.class);
+			excludeProperties("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 BeanFilter
+	//====================================================================================================
+	@Test
+	public void testInterfaceClassUsingBeanFilter() throws Exception {
+		SerializerBuilder s = getSerializer().builder();
+		ParserBuilder p = getParser() == null ? null : getParser().builder();
+		FB2 t;
+		Object r;
+
+		// Skip validation-only tests
+		if (isValidationOnly())
+			return;
+
+		// --- BeanFilter defined on parent class ---
+		s.beanFilters(FB1Filter.class);
+		p.beanFilters(FB1Filter.class);
+
+		t = new FB2().init();
+		r = s.build().serialize(t);
+		t = p.build().parse(r, FB2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+
+		// --- BeanFilter defined on child class class ---
+		s.beanFilters(FB2Filter.class);
+		p.beanFilters(FB2Filter.class);
+
+		t = new FB2().init();
+		r = s.build().serialize(t);
+		t = p.build().parse(r, FB2.class);
+		assertObjectEquals("{f1:'f1'}", t);
+
+		// --- BeanFilter defined as plain class ---
+		s.beanFilters(FB1.class);
+		p.beanFilters(FB1.class);
+
+		t = new FB2().init();
+		r = s.build().serialize(t);
+		t = p.build().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 FB1Filter extends InterfaceBeanFilterBuilder {
+		public FB1Filter() {
+			super(FB1.class);
+		}
+	}
+	public static class FB2Filter extends InterfaceBeanFilterBuilder {
+		public FB2Filter() {
+			super(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());
+		roundTrip(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());
+		roundTrip(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;
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
new file mode 100644
index 0000000..e303899
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
@@ -0,0 +1,52 @@
+// ***************************************************************************************************************************
+// * 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.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.utils.*;
+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("javadoc")
+public class RoundTripClassesTest extends RoundTripTest {
+
+	public RoundTripClassesTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
+		super(label, s, p, flags);
+	}
+
+	@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 AList<Class<?>>().append(String.class).append(Integer.class);
+		o = roundTrip(o);
+		assertObjectEquals("['java.lang.String','java.lang.Integer']", o);
+
+		o = new AMap<Class<?>,Class<?>>().append(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/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
new file mode 100755
index 0000000..d7b749c
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
@@ -0,0 +1,49 @@
+// ***************************************************************************************************************************
+// * 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({"javadoc"})
+public class RoundTripDTOsTest extends RoundTripTest {
+
+	public RoundTripDTOsTest(String label, SerializerBuilder s, ParserBuilder 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/75b0d8ee/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
----------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
new file mode 100755
index 0000000..77a2ec0
--- /dev/null
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
@@ -0,0 +1,247 @@
+// ***************************************************************************************************************************
+// * 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.apache.juneau.utils.*;
+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({"javadoc"})
+public class RoundTripEnumTest extends RoundTripTest {
+
+	public RoundTripEnumTest(String label, SerializerBuilder s, ParserBuilder 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 JsonSerializerBuilder().simple().beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps()).build();
+		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 AList<AEnum>().append(AEnum.FOO);
+			f6 = new AList<AEnum>().append(AEnum.FOO);
+			f7 = new ASet<AEnum>().append(AEnum.FOO);
+			f8 = new ASet<AEnum>().append(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 AList<BEnum>().append(BEnum.FOO);
+			f6 = new AList<BEnum>().append(BEnum.FOO);
+			f7 = new ASet<BEnum>().append(BEnum.FOO);
+			f8 = new ASet<BEnum>().append(BEnum.FOO);
+
+			return this;
+		}
+	}
+}