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 2018/07/07 15:38:28 UTC

[juneau] branch master updated: Clean up BeanSession convertToMemberType

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new 9fc5ba8  Clean up BeanSession convertToMemberType
9fc5ba8 is described below

commit 9fc5ba80c8cc16a23f2248ef1ee5401280b1a765
Author: JamesBognar <ja...@apache.org>
AuthorDate: Sat Jul 7 11:38:13 2018 -0400

    Clean up BeanSession convertToMemberType
---
 .../java/org/apache/juneau/BeanConfigTest.java     |   2 +-
 .../juneau/httppart/HttpPartSchemaTest_Body.java   |   2 +
 .../httppart/HttpPartSchemaTest_FormData.java      |   2 +
 .../juneau/httppart/HttpPartSchemaTest_Header.java |   2 +
 .../juneau/httppart/HttpPartSchemaTest_Path.java   |   2 +
 .../juneau/httppart/HttpPartSchemaTest_Query.java  |   2 +
 .../httppart/HttpPartSchemaTest_Response.java      |   2 +
 .../HttpPartSchemaTest_ResponseHeader.java         |   2 +
 .../juneau/httppart/OpenApiPartParserTest.java     |   2 +
 .../juneau/httppart/OpenApiPartSerializerTest.java | 394 ++++++++++++---------
 .../apache/juneau/httppart/UonPartParserTest.java  |   2 +
 .../main/java/org/apache/juneau/BeanSession.java   | 299 +++++++++-------
 .../org/apache/juneau/httppart/HttpPartSchema.java |   6 +-
 .../juneau/httppart/OpenApiPartSerializer.java     | 145 ++++----
 .../org/apache/juneau/internal/TransformCache.java |  12 +
 .../org/apache/juneau/transform/PojoSwapper.java   |  24 ++
 16 files changed, 527 insertions(+), 373 deletions(-)

diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
index e72f258..d34ade3 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -833,6 +833,6 @@ public class BeanConfigTest {
 		// Booleans are handled different since 'new Boolean("")' is valid and resolves to false
 		// while 'new Integer("")' produces an exception.
 		assertEquals(false, (boolean)session.convertToType("", boolean.class));
-		assertEquals(false, session.convertToType("", Boolean.class));
+		assertEquals(null, session.convertToType("", Boolean.class));
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
index b708c9c..4b57053 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Body.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_Body {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
index 9f7a030..b9a0c2b 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_FormData.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_FormData {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
index 08e92f9..50427f1 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Header.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_Header {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
index 4d7194d..8612836 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Path.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_Path {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
index d6c92c1..acc0482 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Query.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_Query {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
index fad918a..cd90caa 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_Response.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_Response {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
index 585f9ad..6bc92aa 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/HttpPartSchemaTest_ResponseHeader.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class HttpPartSchemaTest_ResponseHeader {
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
index ed63762..0f32fbb 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartParserTest.java
@@ -23,7 +23,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class OpenApiPartParserTest {
 
 	static OpenApiPartParser p = OpenApiPartParser.DEFAULT;
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java
index 70aae15..bf3b72e 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java
@@ -21,7 +21,9 @@ import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.utils.*;
 import org.junit.*;
+import org.junit.runners.*;
 
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class OpenApiPartSerializerTest {
 
 	static OpenApiPartSerializer s = OpenApiPartSerializer.DEFAULT;
@@ -33,10 +35,10 @@ public class OpenApiPartSerializerTest {
 	@Test
 	public void a01_outputValidations_nullOutput() throws Exception {
 		HttpPartSchema ps = schema().build();
-		assertNull(s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, null));
 
 		ps = schema().required(false).build();
-		assertNull(s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, null));
 
 		ps = schema().required().build();
 		try {
@@ -87,7 +89,7 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema().pattern("x.*").allowEmptyValue().build();
 		assertEquals("x", s.serialize(ps, "x"));
 		assertEquals("xx", s.serialize(ps, "xx"));
-		assertEquals(null, s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, null));
 
 		try {
 			s.serialize(ps, "y");
@@ -115,7 +117,7 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema()._enum("foo").allowEmptyValue().build();
 
 		assertEquals("foo", s.serialize(ps, "foo"));
-		assertEquals(null, s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, null));
 
 		try {
 			s.serialize(ps, "bar");
@@ -144,7 +146,7 @@ public class OpenApiPartSerializerTest {
 	public void a05_outputValidations_minMaxLength() throws Exception {
 		HttpPartSchema ps = schema().minLength(1l).maxLength(2l).allowEmptyValue().build();
 
-		assertEquals(null, s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, null));
 		assertEquals("1", s.serialize(ps, "1"));
 		assertEquals("12", s.serialize(ps, "12"));
 
@@ -180,7 +182,7 @@ public class OpenApiPartSerializerTest {
 	public static class C2 {
 		private String f;
 		public C2(String s) {
-			f = "C2-" + s;
+			f = s;
 		}
 		@Override
 		public String toString() {
@@ -219,6 +221,8 @@ public class OpenApiPartSerializerTest {
 		String expected = base64Encode(foob);
 		assertEquals(expected, s.serialize(ps, foob));
 		assertEquals(expected, s.serialize(ps, new C1(foob)));
+		assertEquals("null", s.serialize(ps, new C1(null)));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
@@ -228,6 +232,8 @@ public class OpenApiPartSerializerTest {
 		String expected = toHex(foob);
 		assertEquals(expected, s.serialize(ps, foob));
 		assertEquals(expected, s.serialize(ps, new C1(foob)));
+		assertEquals("null", s.serialize(ps, new C1(null)));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
@@ -237,6 +243,8 @@ public class OpenApiPartSerializerTest {
 		String expected = toSpacedHex(foob);
 		assertEquals(expected, s.serialize(ps, foob));
 		assertEquals(expected, s.serialize(ps, new C1(foob)));
+		assertEquals("null", s.serialize(ps, new C1(null)));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
@@ -244,6 +252,7 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("string", "date").build();
 		Calendar in = StringUtils.parseIsoCalendar("2012-12-21");
 		assertTrue(s.serialize(ps, in).contains("2012"));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
@@ -251,6 +260,7 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("string", "date-time").build();
 		Calendar in = StringUtils.parseIsoCalendar("2012-12-21T12:34:56.789");
 		assertTrue(s.serialize(ps, in).contains("2012"));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
@@ -258,7 +268,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("string", "uon").build();
 		assertEquals("foo", s.serialize(ps, "foo"));
 		assertEquals("'foo'", s.serialize(ps, "'foo'"));
-		assertEquals("C2-foo", s.serialize(ps, new C2("foo")));
+		assertEquals("foo", s.serialize(ps, new C2("foo")));
+		assertEquals("null", s.serialize(ps, new C2(null)));
+		assertEquals("'null'", s.serialize(ps, new C2("null")));
+		assertEquals("null", s.serialize(ps, null));
 		// UonPartSerializerTest should handle all other cases.
 	}
 
@@ -268,55 +281,60 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("string").build();
 		assertEquals("foo", s.serialize(ps, "foo"));
 		assertEquals("'foo'", s.serialize(ps, "'foo'"));
-		assertEquals("C2-foo", s.serialize(ps, new C2("foo")));
+		assertEquals("foo", s.serialize(ps, new C2("foo")));
+		assertEquals("null", s.serialize(ps, new C2(null)));
+		assertEquals("null", s.serialize(ps, new C2("null")));
+		assertEquals("null", s.serialize(ps, null));
 	}
 
 	@Test
 	public void c10_stringType_noneFormat_2d() throws Exception {
 		HttpPartSchema ps = schema("array").items(schema("string")).build();
-		assertEquals("foo,bar", s.serialize(ps, new String[]{"foo","bar"}));
-		assertEquals("foo,bar", s.serialize(ps, AList.create("foo","bar")));
-		assertEquals("foo,bar", s.serialize(ps, new Object[]{"foo","bar"}));
-		assertEquals("foo,bar", s.serialize(ps, AList.create((Object)"foo",(Object)"bar")));
-		assertEquals("C2-foo,C2-bar", s.serialize(ps, new C2[] {new C2("foo"), new C2("bar")}));
-		assertEquals("C2-foo,C2-bar", s.serialize(ps, AList.create(new C2("foo"), new C2("bar"))));
-		assertEquals("foo,bar", s.serialize(ps, new C3("foo","bar")));
+		assertEquals("foo,bar,null", s.serialize(ps, new String[]{"foo","bar",null}));
+		assertEquals("foo,bar,null", s.serialize(ps, AList.create("foo","bar",null)));
+		assertEquals("foo,bar,null", s.serialize(ps, new Object[]{"foo","bar",null}));
+		assertEquals("foo,bar,null", s.serialize(ps, AList.create((Object)"foo",(Object)"bar",null)));
+		assertEquals("foo,bar,null,null", s.serialize(ps, new C2[]{new C2("foo"),new C2("bar"),new C2(null),null}));
+		assertEquals("foo,bar,null,null", s.serialize(ps, AList.create(new C2("foo"),new C2("bar"),new C2(null),null)));
+		assertEquals("foo,bar,null", s.serialize(ps, new C3("foo","bar",null)));
 	}
 
 	@Test
 	public void c11_stringType_noneFormat_3d() throws Exception {
 		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("string"))).build();
-		assertEquals("foo,bar|baz", s.serialize(ps, new String[][]{{"foo","bar"},{"baz"}}));
-		assertEquals("foo,bar|baz", s.serialize(ps, AList.create(new String[]{"foo","bar"}, new String[]{"baz"})));
-		assertEquals("foo,bar|baz", s.serialize(ps, AList.create(AList.create("foo","bar"),AList.create("baz"))));
-		assertEquals("foo,bar|baz", s.serialize(ps, new Object[][]{{"foo","bar"},{"baz"}}));
-		assertEquals("foo,bar|baz", s.serialize(ps, AList.create(new Object[]{"foo","bar"}, new String[]{"baz"})));
-		assertEquals("foo,bar|baz", s.serialize(ps, AList.create(AList.create((Object)"foo",(Object)"bar"),AList.create((Object)"baz"))));
-		assertEquals("C2-foo,C2-bar|C2-baz", s.serialize(ps, new C2[][]{{new C2("foo"),new C2("bar")},{new C2("baz")}}));
-		assertEquals("C2-foo,C2-bar|C2-baz", s.serialize(ps, AList.create(new C2[]{new C2("foo"),new C2("bar")}, new C2[]{new C2("baz")})));
-		assertEquals("C2-foo,C2-bar|C2-baz", s.serialize(ps, AList.create(AList.create(new C2("foo"),new C2("bar")),AList.create(new C2("baz")))));
-		assertEquals("foo,bar|baz", s.serialize(ps, new C3[]{new C3("foo","bar"),new C3("baz")}));
-		assertEquals("foo,bar|baz", s.serialize(ps, AList.create(new C3("foo","bar"), new C3("baz"))));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, new String[][]{{"foo","bar"},{"baz",null},null}));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(new String[]{"foo","bar"}, new String[]{"baz",null},null)));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(AList.create("foo","bar"),AList.create("baz",null),null)));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, new Object[][]{{"foo","bar"},{"baz",null},null}));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(new Object[]{"foo","bar"}, new String[]{"baz",null},null)));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(AList.create((Object)"foo",(Object)"bar"),AList.create((Object)"baz",null),null)));
+		assertEquals("foo,bar|baz,null,null|null", s.serialize(ps, new C2[][]{{new C2("foo"),new C2("bar")},{new C2("baz"),new C2(null),null},null}));
+		assertEquals("foo,bar|baz,null,null|null", s.serialize(ps, AList.create(new C2[]{new C2("foo"),new C2("bar")}, new C2[]{new C2("baz"),new C2(null),null},null)));
+		assertEquals("foo,bar|baz,null,null|null", s.serialize(ps, AList.create(AList.create(new C2("foo"),new C2("bar")),AList.create(new C2("baz"),new C2(null),null),null)));
+		assertEquals("foo,bar|baz,null|null|null", s.serialize(ps, new C3[]{new C3("foo","bar"),new C3("baz",null),new C3((String)null),null}));
+		assertEquals("foo,bar|baz,null|null|null", s.serialize(ps, AList.create(new C3("foo","bar"),new C3("baz",null),new C3((String)null),null)));
 	}
 
 	@Test
-	public void c12a_stringType_uonKeywords_plain() throws Exception {
+	public void c12_stringType_uonKeywords_plain() throws Exception {
 		HttpPartSchema ps = schema("string").build();
 		// When serialized normally, the following should not be quoted.
 		assertEquals("true", s.serialize(ps, "true"));
 		assertEquals("false", s.serialize(ps, "false"));
 		assertEquals("null", s.serialize(ps, "null"));
+		assertEquals("null", s.serialize(ps, null));
 		assertEquals("123", s.serialize(ps, "123"));
 		assertEquals("1.23", s.serialize(ps, "1.23"));
 	}
 
 	@Test
-	public void c12b_stringType_uonKeywords_uon() throws Exception {
+	public void c13_stringType_uonKeywords_uon() throws Exception {
 		HttpPartSchema ps = schema("string","uon").build();
 		// When serialized as UON, the following should be quoted so that they're not confused with booleans or numbers.
 		assertEquals("'true'", s.serialize(ps, "true"));
 		assertEquals("'false'", s.serialize(ps, "false"));
 		assertEquals("'null'", s.serialize(ps, "null"));
+		assertEquals("null", s.serialize(ps, null));
 		assertEquals("'123'", s.serialize(ps, "123"));
 		assertEquals("'1.23'", s.serialize(ps, "1.23"));
 	}
@@ -328,7 +346,7 @@ public class OpenApiPartSerializerTest {
 	public static class D {
 		private String f;
 		public D(String in) {
-			this.f = "D-" + in;
+			this.f = in;
 		}
 		@Override
 		public String toString() {
@@ -341,10 +359,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("csv").build();
 		assertEquals("foo,bar,null", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo,bar,null", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo,bar,null,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo,bar,null,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo,bar,null", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 
 		assertEquals("foo\\,bar,null", s.serialize(ps, new String[]{"foo,bar",null}));
@@ -355,10 +373,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("pipes").build();
 		assertEquals("foo|bar|null", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo|bar|null", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo|D-bar|null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo|bar|null|null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo|bar|null", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo|bar|null", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo|D-bar|null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo|bar|null|null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo|bar|null", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 	}
 
@@ -367,10 +385,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("ssv").build();
 		assertEquals("foo bar null", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo bar null", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo D-bar null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo bar null null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo bar null", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo bar null", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo D-bar null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo bar null null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo bar null", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 	}
 
@@ -379,10 +397,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("tsv").build();
 		assertEquals("foo\tbar\tnull", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo\tbar\tnull", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo\tD-bar\tnull", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo\tbar\tnull\tnull", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo\tbar\tnull", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo\tbar\tnull", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo\tD-bar\tnull", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo\tbar\tnull\tnull", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo\tbar\tnull", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 	}
 
@@ -391,10 +409,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("uon").build();
 		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new String[]{"foo","bar","null",null}));
 		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new Object[]{"foo","bar","null",null}));
-		assertEquals("@(D-foo,D-bar,D-null,null)", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D("null"),null}));
+		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D("null"),null}));
 		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, AList.create("foo","bar","null",null)));
 		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, AList.<Object>create("foo","bar","null",null)));
-		assertEquals("@(D-foo,D-bar,D-null,null)", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D("null"),null)));
+		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D("null"),null)));
 		assertEquals("@(foo,bar,'null',null)", s.serialize(ps, new ObjectList().append("foo","bar","null",null)));
 	}
 
@@ -403,10 +421,10 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").build();
 		assertEquals("foo,bar,null", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo,bar,null", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo,bar,null,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo,bar,null,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo,bar,null", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 	}
 
@@ -416,22 +434,22 @@ public class OpenApiPartSerializerTest {
 		HttpPartSchema ps = schema("array").collectionFormat("multi").build();
 		assertEquals("foo,bar,null", s.serialize(ps, new String[]{"foo","bar",null}));
 		assertEquals("foo,bar,null", s.serialize(ps, new Object[]{"foo","bar",null}));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),null}));
+		assertEquals("foo,bar,null,null", s.serialize(ps, new D[]{new D("foo"),new D("bar"),new D(null),null}));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.create("foo","bar",null)));
 		assertEquals("foo,bar,null", s.serialize(ps, AList.<Object>create("foo","bar",null)));
-		assertEquals("D-foo,D-bar,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),null)));
+		assertEquals("foo,bar,null,null", s.serialize(ps, AList.create(new D("foo"),new D("bar"),new D(null),null)));
 		assertEquals("foo,bar,null", s.serialize(ps, new ObjectList().append("foo","bar",null)));
 	}
 
 	@Test
 	public void d08_arrayType_collectionFormatCsvAndPipes() throws Exception {
 		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").collectionFormat("csv")).build();
-		assertEquals("foo,bar|baz,null", s.serialize(ps, new String[][]{{"foo","bar"},{"baz",null}}));
-		assertEquals("foo,bar|baz,null", s.serialize(ps, new Object[][]{{"foo","bar"},{"baz",null}}));
-		assertEquals("D-foo,D-bar|D-baz,D-null", s.serialize(ps, new D[][]{{new D("foo"),new D("bar")},{new D("baz"),new D(null)}}));
-		assertEquals("foo,bar|baz,null", s.serialize(ps, AList.create(AList.create("foo","bar"),AList.create("baz",null))));
-		assertEquals("foo,bar|baz,null", s.serialize(ps, AList.create(AList.<Object>create("foo","bar"),AList.<Object>create("baz",null))));
-		assertEquals("D-foo,D-bar|D-baz,D-null", s.serialize(ps, AList.create(AList.create(new D("foo"),new D("bar")),AList.create(new D("baz"),new D(null)))));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, new String[][]{{"foo","bar"},{"baz",null},null}));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, new Object[][]{{"foo","bar"},{"baz",null},null}));
+		assertEquals("foo,bar|baz,null,null|null", s.serialize(ps, new D[][]{{new D("foo"),new D("bar")},{new D("baz"),new D(null),null},null}));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(AList.create("foo","bar"),AList.create("baz",null),null)));
+		assertEquals("foo,bar|baz,null|null", s.serialize(ps, AList.create(AList.<Object>create("foo","bar"),AList.<Object>create("baz",null),null)));
+		assertEquals("foo,bar|baz,null,null|null", s.serialize(ps, AList.create(AList.create(new D("foo"),new D("bar")),AList.create(new D("baz"),new D(null),null),null)));
 	}
 
 	@Test
@@ -443,6 +461,15 @@ public class OpenApiPartSerializerTest {
 		assertEquals("1,2,null", s.serialize(ps, AList.create(1,2,null)));
 	}
 
+	@Test
+	public void d10_arrayType_itemsInteger_2d() throws Exception {
+		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").collectionFormat("csv").allowEmptyValue().items(schema("integer"))).build();
+		assertEquals("1,2||null", s.serialize(ps, new int[][]{{1,2},{},null}));
+		assertEquals("1,2,null||null", s.serialize(ps, new Integer[][]{{1,2,null},{},null}));
+		assertEquals("1,2,null||null", s.serialize(ps, new Object[][]{{1,2,null},{},null}));
+		assertEquals("1,2,null||null", s.serialize(ps, AList.create(AList.create(1,2,null),AList.create(),null)));
+	}
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// type = boolean
 	//-----------------------------------------------------------------------------------------------------------------
@@ -471,12 +498,32 @@ public class OpenApiPartSerializerTest {
 	public void e01_booleanType() throws Exception {
 		HttpPartSchema ps = schema("boolean").build();
 		assertEquals("true", s.serialize(ps, true));
+		assertEquals("true", s.serialize(ps, "true"));
+		assertEquals("true", s.serialize(ps, new E1(true)));
 		assertEquals("false", s.serialize(ps, false));
+		assertEquals("false", s.serialize(ps, "false"));
+		assertEquals("false", s.serialize(ps, new E1(false)));
 		assertEquals("null", s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, "null"));
+		assertEquals("null", s.serialize(ps, new E1(null)));
 	}
 
 	@Test
-	public void e02_booleanType_2d() throws Exception {
+	public void e02_booleanType_uon() throws Exception {
+		HttpPartSchema ps = schema("boolean","uon").build();
+		assertEquals("true", s.serialize(ps, true));
+		assertEquals("true", s.serialize(ps, "true"));
+		assertEquals("true", s.serialize(ps, new E1(true)));
+		assertEquals("false", s.serialize(ps, false));
+		assertEquals("false", s.serialize(ps, "false"));
+		assertEquals("false", s.serialize(ps, new E1(false)));
+		assertEquals("null", s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, "null"));
+		assertEquals("null", s.serialize(ps, new E1(null)));
+	}
+
+	@Test
+	public void e03_booleanType_2d() throws Exception {
 		HttpPartSchema ps = schema("array").items(schema("boolean")).build();
 		assertEquals("true", s.serialize(ps, new boolean[]{true}));
 		assertEquals("true,null", s.serialize(ps, new Boolean[]{true,null}));
@@ -491,7 +538,7 @@ public class OpenApiPartSerializerTest {
 	}
 
 	@Test
-	public void e03_booleanType_3d() throws Exception {
+	public void e04_booleanType_3d() throws Exception {
 		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("boolean"))).build();
 		assertEquals("true,true|false", s.serialize(ps, new boolean[][]{{true,true},{false}}));
 		assertEquals("true,true|false", s.serialize(ps, AList.create(new boolean[]{true,true},new boolean[]{false})));
@@ -527,7 +574,7 @@ public class OpenApiPartSerializerTest {
 
 	public static class F2 {
 		private Integer[] f;
-		public F2(Integer[] in) {
+		public F2(Integer...in) {
 			this.f = in;
 		}
 		public Integer[] toIntegerArray() {
@@ -547,7 +594,7 @@ public class OpenApiPartSerializerTest {
 
 	public static class F4 {
 		private Long[] f;
-		public F4(Long[] in) {
+		public F4(Long...in) {
 			this.f = in;
 		}
 		public Long[] toLongArray() {
@@ -566,127 +613,128 @@ public class OpenApiPartSerializerTest {
 		assertEquals("1", s.serialize(ps, new Long(1)));
 		assertEquals("1", s.serialize(ps, "1"));
 		assertEquals("1", s.serialize(ps, new F1(1)));
+		assertEquals("null", s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, "null"));
+	}
+
+	@Test
+	public void f02_integerType_int32_2d() throws Exception {
+		HttpPartSchema ps = schema("array").items(schema("integer", "int32")).build();
+		assertEquals("1,2", s.serialize(ps, new int[]{1,2}));
+		assertEquals("1,2,null", s.serialize(ps, new Integer[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create(1,2,null)));
+		assertEquals("1,2", s.serialize(ps, new short[]{1,2}));
+		assertEquals("1,2,null", s.serialize(ps, new Short[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create(new Short((short)1),new Short((short)2),null)));
+		assertEquals("1,2", s.serialize(ps, new long[]{1l,2l}));
+		assertEquals("1,2,null", s.serialize(ps, new Long[]{1l,2l,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create(1l,2l,null)));
+		assertEquals("1,2,null", s.serialize(ps, new String[]{"1","2",null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create("1","2",null)));
+		assertEquals("1,2,null", s.serialize(ps, new Object[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.<Object>create(1,2,null)));
+		assertEquals("1,2,null,null", s.serialize(ps, new F1[]{new F1(1),new F1(2),new F1(null),null}));
+		assertEquals("1,2,null,null", s.serialize(ps, AList.create(new F1(1),new F1(2),new F1(null),null)));
+		assertEquals("1,2,null", s.serialize(ps, new F2(1,2,null)));
+	}
+
+	@Test
+	public void f03_integerType_int32_3d() throws Exception {
+		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int32"))).build();
+		assertEquals("1,2|3|null", s.serialize(ps, new int[][]{{1,2},{3},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new int[]{1,2},new int[]{3},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Integer[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Integer[]{1,2},new Integer[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create(1,2),AList.create(3,null),null)));
+		assertEquals("1,2|3|null", s.serialize(ps, new short[][]{{1,2},{3},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new short[]{1,2},new short[]{3},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Short[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Short[]{1,2},new Short[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create(new Short((short)1),new Short((short)2)),AList.create(new Short((short)3),null),null)));
+		assertEquals("1,2|3|null", s.serialize(ps, new long[][]{{1l,2l},{3l},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new long[]{1l,2l},new long[]{3l},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Long[][]{{1l,2l},{3l,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Long[]{1l,2l},new Long[]{3l,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create(new Long(1),new Long(2)),AList.create(new Long(3),null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new String[][]{{"1","2"},{"3",null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new String[]{"1","2"},new String[]{"3",null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create("1","2"),AList.create("3",null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Object[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Object[]{1,2},new Object[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.<Object>create(1,2),AList.<Object>create(3,null),null)));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, new F1[][]{{new F1(1),new F1(2)},{new F1(3),new F1(null),null},null}));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, AList.create(new F1[]{new F1(1),new F1(2)},new F1[]{new F1(3),new F1(null),null},null)));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, AList.create(AList.create(new F1(1),new F1(2)),AList.create(new F1(3),new F1(null),null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new F2[]{new F2(1,2),new F2(3,null),null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new F2(1,2),new F2(3,null),null)));
+	}
+
+	@Test
+	public void f04_integerType_int64() throws Exception {
+		HttpPartSchema ps = schema("integer", "int64").build();
+		assertEquals("1", s.serialize(ps, 1));
+		assertEquals("1", s.serialize(ps, new Integer(1)));
+		assertEquals("1", s.serialize(ps, (short)1));
+		assertEquals("1", s.serialize(ps, new Short((short)1)));
+		assertEquals("1", s.serialize(ps, 1l));
+		assertEquals("1", s.serialize(ps, new Long(1l)));
+		assertEquals("1", s.serialize(ps, "1"));
+		assertEquals("1", s.serialize(ps,  new F3(1l)));
+		assertEquals("null", s.serialize(ps, null));
+		assertEquals("null", s.serialize(ps, "null"));
+	}
+
+	@Test
+	public void f05_integerType_int64_2d() throws Exception {
+		HttpPartSchema ps = schema("array").items(schema("integer", "int64")).build();
+		assertEquals("1,2", s.serialize(ps, new int[]{1,2}));
+		assertEquals("1,2,null", s.serialize(ps, new Integer[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create(1,2,null)));
+		assertEquals("1,2", s.serialize(ps, new short[]{1,2}));
+		assertEquals("1,2,null", s.serialize(ps, new Short[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create((short)1,(short)2,null)));
+		assertEquals("1,2", s.serialize(ps, new long[]{1l,2l}));
+		assertEquals("1,2,null", s.serialize(ps, new Long[]{1l,2l,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create(1l,2l,null)));
+		assertEquals("1,2,null", s.serialize(ps, new String[]{"1","2",null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create("1","2",null)));
+		assertEquals("1,2,null", s.serialize(ps, new Object[]{1,2,null}));
+		assertEquals("1,2,null", s.serialize(ps, AList.create((Object)1,(Object)2,null)));
+		assertEquals("1,2,null,null", s.serialize(ps, new F3[]{new F3(1l),new F3(2l),new F3(null),null}));
+		assertEquals("1,2,null,null", s.serialize(ps, AList.create(new F3(1l),new F3(2l),new F3(null),null)));
+		assertEquals("1,2,null", s.serialize(ps, new F4(1l,2l,null)));
+	}
+
+	@Test
+	public void f06_integerType_int64_3d() throws Exception {
+		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int64"))).build();
+		assertEquals("1,2|3|null", s.serialize(ps, new int[][]{{1,2},{3},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new int[]{1,2},new int[]{3},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Integer[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Integer[]{1,2},new Integer[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create(1,2),AList.create(3,null),null)));
+		assertEquals("1,2|3|null", s.serialize(ps, new short[][]{{1,2},{3},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new short[]{1,2},new short[]{3},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Short[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Short[]{1,2},new Short[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create((short)1,(short)2),AList.create((short)3,null),null)));
+		assertEquals("1,2|3|null", s.serialize(ps, new long[][]{{1l,2l},{3l},null}));
+		assertEquals("1,2|3|null", s.serialize(ps, AList.create(new long[]{1l,2l},new long[]{3l},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Long[][]{{1l,2l},{3l,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Long[]{1l,2l},new Long[]{3l,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create(1l,2l),AList.create(3l,null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new String[][]{{"1","2"},{"3",null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new String[]{"1","2"},new String[]{"3",null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create("1","2"),AList.create("3",null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new Object[][]{{1,2},{3,null},null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new Object[]{1,2},new Object[]{3,null},null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(AList.create((Object)1,(Object)2),AList.create((Object)3,null),null)));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, new F3[][]{{new F3(1l),new F3(2l)},{new F3(3l),new F3(null),null},null}));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, AList.create(new F3[]{new F3(1l),new F3(2l)},new F3[]{new F3(3l),new F3(null),null},null)));
+		assertEquals("1,2|3,null,null|null", s.serialize(ps, AList.create(AList.create(new F3(1l),new F3(2l)),AList.create(new F3(3l),new F3(null),null),null)));
+		assertEquals("1,2|3,null|null", s.serialize(ps, new F4[]{new F4(1l,2l),new F4(3l,null),null}));
+		assertEquals("1,2|3,null|null", s.serialize(ps, AList.create(new F4(1l,2l),new F4(3l,null),null)));
 	}
-//
-//	@Test
-//	public void f02_integerType_int32_2d() throws Exception {
-//		HttpPartSchema ps = schema("array").items(schema("integer", "int32")).build();
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", int[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Integer[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Integer.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", short[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Short[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Short.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", long[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Long[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Long.class));
-//		assertEquals("['1','2']", s.serialize(ps, "1,2", String[].class));
-//		assertEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Object[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Object.class));
-//		assertEquals("['F1-1','F1-2']", s.serialize(ps,  "1,2", F1[].class));
-//		assertEquals("['F1-1','F1-2']", s.serialize(ps,  "1,2", List.class, F1.class));
-//		assertEquals("'F2-[1,2]'", s.serialize(ps,  "1,2", F2.class));
-//	}
-//
-//	@Test
-//	public void f03_integerType_int32_3d() throws Exception {
-//		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int32"))).build();
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", int[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, int[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Integer[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Integer[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Integer.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", short[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, short[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Short[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Short[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Short.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", long[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, long[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Long[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Long[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Long.class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Object[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Object[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class));
-//		assertEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps,  "1,2|3", F1[][].class));
-//		assertEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps,  "1,2|3", List.class, F1[].class));
-//		assertEquals("[['F1-1','F1-2'],['F1-3']]", s.serialize(ps,  "1,2|3", List.class, List.class, F1.class));
-//		assertEquals("['F2-[1,2]','F2-[3]']", s.serialize(ps, "1,2|3", F2[].class));
-//		assertEquals("['F2-[1,2]','F2-[3]']", s.serialize(ps, "1,2|3", List.class, F2.class));
-//	}
-//
-//	@Test
-//	public void f04_integerType_int64() throws Exception {
-//		HttpPartSchema ps = schema("integer", "int64").build();
-//		assertEquals("1", s.serialize(ps, "1", int.class));
-//		assertEquals("1", s.serialize(ps, "1", Integer.class));
-//		assertEquals("1", s.serialize(ps, "1", short.class));
-//		assertEquals("1", s.serialize(ps, "1", Short.class));
-//		assertEquals("1", s.serialize(ps, "1", long.class));
-//		assertEquals("1", s.serialize(ps, "1", Long.class));
-//		assertEquals("'1'", s.serialize(ps, "1", String.class));
-//		Object o = s.serialize(ps, "1", Object.class);
-//		assertEquals("1", o);
-//		assertClass(Long.class, o);
-//		assertEquals("'F3-1'", s.serialize(ps,  "1", F3.class));
-//	}
-//
-//	@Test
-//	public void f05_integerType_int64_2d() throws Exception {
-//		HttpPartSchema ps = schema("array").items(schema("integer", "int64")).build();
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", int[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Integer[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Integer.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", short[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Short[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Short.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", long[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Long[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Long.class));
-//		assertEquals("['1','2']", s.serialize(ps, "1,2", String[].class));
-//		assertEquals("['1','2']", s.serialize(ps, "1,2", List.class, String.class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", Object[].class));
-//		assertEquals("[1,2]", s.serialize(ps, "1,2", List.class, Object.class));
-//		assertEquals("['F3-1','F3-2']", s.serialize(ps,  "1,2", F3[].class));
-//		assertEquals("['F3-1','F3-2']", s.serialize(ps,  "1,2", List.class, F3.class));
-//		assertEquals("'F4-[1,2]'", s.serialize(ps,  "1,2", F4.class));
-//	}
-//
-//	@Test
-//	public void f06_integerType_int64_3d() throws Exception {
-//		HttpPartSchema ps = schema("array").collectionFormat("pipes").items(schema("array").items(schema("integer", "int64"))).build();
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", int[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, int[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Integer[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Integer[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Integer.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", short[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, short[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Short[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Short[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Short.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", long[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, long[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Long[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Long[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Long.class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", String[][].class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, String[].class));
-//		assertEquals("[['1','2'],['3']]", s.serialize(ps, "1,2|3", List.class, List.class, String.class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", Object[][].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, Object[].class));
-//		assertEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", List.class, List.class, Object.class));
-//		assertEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps,  "1,2|3", F3[][].class));
-//		assertEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps,  "1,2|3", List.class, F3[].class));
-//		assertEquals("[['F3-1','F3-2'],['F3-3']]", s.serialize(ps,  "1,2|3", List.class, List.class, F3.class));
-//		assertEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, "1,2|3", F4[].class));
-//		assertEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, "1,2|3", List.class, F4.class));
-//	}
 //
 //
 //	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/UonPartParserTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/UonPartParserTest.java
index 6a60856..011f19b 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/UonPartParserTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/UonPartParserTest.java
@@ -19,8 +19,10 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.json.*;
 import org.junit.*;
+import org.junit.runners.*;
 
 @SuppressWarnings({"rawtypes"})
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
 public class UonPartParserTest {
 
 	static UonPartParser p = UonPartParser.DEFAULT;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
index 2c012b5..ed3f8f3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanSession.java
@@ -330,55 +330,52 @@ public class BeanSession extends Session {
 	 * 	If class is a member class, this is the instance of the containing class.
 	 * 	Should be <jk>null</jk> if not a member class.
 	 * @param value The value to convert.
-	 * @param type The class type to convert the value to.
+	 * @param to The class type to convert the value to.
 	 * @throws InvalidDataConversionException If the specified value cannot be converted to the specified type.
 	 * @return The converted value.
 	 */
-	public final <T> T convertToMemberType(Object outer, Object value, ClassMeta<T> type) throws InvalidDataConversionException {
-		if (type == null)
-			type = (ClassMeta<T>)ctx.object();
+	public final <T> T convertToMemberType(Object outer, Object value, ClassMeta<T> to) throws InvalidDataConversionException {
+		if (to == null)
+			to = (ClassMeta<T>)ctx.object();
 
 		try {
 			// Handle the case of a null value.
 			if (value == null) {
 
 				// If it's a primitive, then use the converters to get the default value for the primitive type.
-				if (type.isPrimitive())
-					return type.getPrimitiveDefault();
+				if (to.isPrimitive())
+					return to.getPrimitiveDefault();
 
 				// Otherwise, just return null.
 				return null;
 			}
 
-			Class<T> tc = type.getInnerClass();
+			Class<T> tc = to.getInnerClass();
 
 			// If no conversion needed, then just return the value.
 			// Don't include maps or collections, because child elements may need conversion.
 			if (tc.isInstance(value))
-				if (! ((type.isMap() && type.getValueType().isNotObject()) || (type.isCollection() && type.getElementType().isNotObject())))
+				if (! ((to.isMap() && to.getValueType().isNotObject()) || (to.isCollection() && to.getElementType().isNotObject())))
 					return (T)value;
 
-			PojoSwap swap = type.getPojoSwap(this);
+			PojoSwap swap = to.getPojoSwap(this);
 			if (swap != null) {
 				Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();
 				if (isParentClass(nc, tc) && isParentClass(fc, value.getClass()))
-					return (T)swap.unswap(this, value, type);
+					return (T)swap.unswap(this, value, to);
 			}
 
-			ClassMeta<?> vt = ctx.getClassMetaForObject(value);
-			swap = vt.getPojoSwap(this);
+			ClassMeta<?> from = ctx.getClassMetaForObject(value);
+			swap = from.getPojoSwap(this);
 			if (swap != null) {
 				Class<?> nc = swap.getNormalClass(), fc = swap.getSwapClass();
-				if (isParentClass(nc, vt.getInnerClass()) && isParentClass(fc, tc))
+				if (isParentClass(nc, from.getInnerClass()) && isParentClass(fc, tc))
 					return (T)swap.swap(this, value);
 			}
 
-			if (type.isPrimitive()) {
-				if (value.toString().isEmpty())
-					return type.getPrimitiveDefault();
-
-				if (type.isNumber()) {
-					if (value instanceof Number) {
+			if (to.isPrimitive()) {
+				if (to.isNumber()) {
+					if (from.isNumber()) {
 						Number n = (Number)value;
 						if (tc == Integer.TYPE)
 							return (T)Integer.valueOf(n.intValue());
@@ -392,17 +389,28 @@ public class BeanSession extends Session {
 							return (T)Double.valueOf(n.doubleValue());
 						if (tc == Byte.TYPE)
 							return (T)Byte.valueOf(n.byteValue());
+					} else if (from.isBoolean()) {
+						Boolean b = (Boolean)value;
+						if (tc == Integer.TYPE)
+							return (T)(Integer.valueOf(b ? 1 : 0));
+						if (tc == Short.TYPE)
+							return (T)(Short.valueOf(b ? (short)1 : 0));
+						if (tc == Long.TYPE)
+							return (T)(Long.valueOf(b ? 1l : 0));
+						if (tc == Float.TYPE)
+							return (T)(Float.valueOf(b ? 1f : 0));
+						if (tc == Double.TYPE)
+							return (T)(Double.valueOf(b ? 1d : 0));
+						if (tc == Byte.TYPE)
+							return (T)(Byte.valueOf(b ? (byte)1 : 0));
+					} else if (isNullOrEmpty(value)) {
+						return (T)getPrimitiveDefault(to.innerClass);
 					} else {
-						String n = null;
-						if (value instanceof Boolean)
-							n = ((Boolean)value).booleanValue() ? "1" : "0";
-						else
-							n = value.toString();
-
-						int multiplier = (tc == Integer.TYPE || tc == Short.TYPE || tc == Long.TYPE) ? getMultiplier(n) : 1;
+						String s = value.toString();
+						int multiplier = (tc == Integer.TYPE || tc == Short.TYPE || tc == Long.TYPE) ? getMultiplier(s) : 1;
 						if (multiplier != 1) {
-							n = n.substring(0, n.length()-1).trim();
-							Long l = Long.valueOf(n) * multiplier;
+							s = s.substring(0, s.length()-1).trim();
+							Long l = Long.valueOf(s) * multiplier;
 							if (tc == Integer.TYPE)
 								return (T)Integer.valueOf(l.intValue());
 							if (tc == Short.TYPE)
@@ -411,32 +419,37 @@ public class BeanSession extends Session {
 								return (T)Long.valueOf(l.longValue());
 						} else {
 							if (tc == Integer.TYPE)
-								return (T)Integer.valueOf(n);
+								return (T)Integer.valueOf(s);
 							if (tc == Short.TYPE)
-								return (T)Short.valueOf(n);
+								return (T)Short.valueOf(s);
 							if (tc == Long.TYPE)
-								return (T)Long.valueOf(n);
+								return (T)Long.valueOf(s);
 							if (tc == Float.TYPE)
-								return (T)new Float(n);
+								return (T)new Float(s);
 							if (tc == Double.TYPE)
-								return (T)new Double(n);
+								return (T)new Double(s);
 							if (tc == Byte.TYPE)
-								return (T)Byte.valueOf(n);
+								return (T)Byte.valueOf(s);
 						}
 					}
-				} else if (type.isChar()) {
+				} else if (to.isChar()) {
+					if (isNullOrEmpty(value))
+						return (T)getPrimitiveDefault(to.innerClass);
 					return (T)parseCharacter(value);
-				} else if (type.isBoolean()) {
-					if (value instanceof Number) {
+				} else if (to.isBoolean()) {
+					if (from.isNumber()) {
 						int i = ((Number)value).intValue();
 						return (T)(i == 0 ? Boolean.FALSE : Boolean.TRUE);
+					} else if (isNullOrEmpty(value)) {
+						return (T)getPrimitiveDefault(to.innerClass);
+					} else {
+						return (T)Boolean.valueOf(value.toString());
 					}
-					return (T)Boolean.valueOf(value.toString());
 				}
 			}
 
-			if (type.isNumber() && (isEmpty(value) || ! hasTransform(vt, type))) {
-				if (value instanceof Number) {
+			if (to.isNumber()) {
+				if (from.isNumber()) {
 					Number n = (Number)value;
 					if (tc == Integer.class)
 						return (T)Integer.valueOf(n.intValue());
@@ -450,25 +463,37 @@ public class BeanSession extends Session {
 						return (T)Double.valueOf(n.doubleValue());
 					if (tc == Byte.class)
 						return (T)Byte.valueOf(n.byteValue());
-					if (tc == Byte.class)
-						return (T)Byte.valueOf(n.byteValue());
 					if (tc == AtomicInteger.class)
 						return (T)new AtomicInteger(n.intValue());
 					if (tc == AtomicLong.class)
 						return (T)new AtomicLong(n.intValue());
-				} else {
-					if (value.toString().isEmpty())
-						return null;
-					String n = null;
-					if (value instanceof Boolean)
-						n = ((Boolean)value).booleanValue() ? "1" : "0";
-					else
-						n = value.toString();
+				} else if (from.isBoolean()) {
+					Boolean b = (Boolean)value;
+					if (tc == Integer.class)
+						return (T)Integer.valueOf(b ? 1 : 0);
+					if (tc == Short.class)
+						return (T)Short.valueOf(b ? (short)1 : 0);
+					if (tc == Long.class)
+						return (T)Long.valueOf(b ? 1 : 0);
+					if (tc == Float.class)
+						return (T)Float.valueOf(b ? 1 : 0);
+					if (tc == Double.class)
+						return (T)Double.valueOf(b ? 1 : 0);
+					if (tc == Byte.class)
+						return (T)Byte.valueOf(b ? (byte)1 : 0);
+					if (tc == AtomicInteger.class)
+						return (T)new AtomicInteger(b ? 1 : 0);
+					if (tc == AtomicLong.class)
+						return (T)new AtomicLong(b ? 1 : 0);
+				} else if (isNullOrEmpty(value)) {
+					return null;
+				} else if (! hasTransform(from, to)) {
+					String s = value.toString();
 
-					int multiplier = (tc == Integer.class || tc == Short.class || tc == Long.class) ? getMultiplier(n) : 1;
+					int multiplier = (tc == Integer.class || tc == Short.class || tc == Long.class) ? getMultiplier(s) : 1;
 					if (multiplier != 1) {
-						n = n.substring(0, n.length()-1).trim();
-						Long l = Long.valueOf(n) * multiplier;
+						s = s.substring(0, s.length()-1).trim();
+						Long l = Long.valueOf(s) * multiplier;
 						if (tc == Integer.TYPE)
 							return (T)Integer.valueOf(l.intValue());
 						if (tc == Short.TYPE)
@@ -477,54 +502,57 @@ public class BeanSession extends Session {
 							return (T)Long.valueOf(l.longValue());
 					} else {
 						if (tc == Integer.class)
-							return (T)Integer.valueOf(n);
+							return (T)Integer.valueOf(s);
 						if (tc == Short.class)
-							return (T)Short.valueOf(n);
+							return (T)Short.valueOf(s);
 						if (tc == Long.class)
-							return (T)Long.valueOf(n);
+							return (T)Long.valueOf(s);
 						if (tc == Float.class)
-							return (T)new Float(n);
+							return (T)new Float(s);
 						if (tc == Double.class)
-							return (T)new Double(n);
+							return (T)new Double(s);
 						if (tc == Byte.class)
-							return (T)Byte.valueOf(n);
+							return (T)Byte.valueOf(s);
 						if (tc == AtomicInteger.class)
-							return (T)new AtomicInteger(Integer.valueOf(n));
+							return (T)new AtomicInteger(Integer.valueOf(s));
 						if (tc == AtomicLong.class)
-							return (T)new AtomicLong(Long.valueOf(n));
+							return (T)new AtomicLong(Long.valueOf(s));
 						if (tc == Number.class)
-							return (T)StringUtils.parseNumber(n, Number.class);
+							return (T)StringUtils.parseNumber(s, Number.class);
 					}
 				}
 			}
 
-			if (type.isChar() && value.toString().length() == 1) {
+			if (to.isChar()) {
+				if (isNullOrEmpty(value))
+					return null;
 				String s = value.toString();
-				return (T)Character.valueOf(s.charAt(0));
+				if (s.length() == 1)
+					return (T)Character.valueOf(s.charAt(0));
 			}
 
 			// Handle setting of array properties
-			if (type.isArray()) {
-				if (vt.isCollection())
-					return (T)toArray(type, (Collection)value);
-				else if (vt.isArray())
-					return (T)toArray(type, Arrays.asList((Object[])value));
+			if (to.isArray()) {
+				if (from.isCollection())
+					return (T)toArray(to, (Collection)value);
+				else if (from.isArray())
+					return (T)toArray(to, Arrays.asList((Object[])value));
 				else if (startsWith(value.toString(), '['))
-					return (T)toArray(type, new ObjectList(value.toString()).setBeanSession(this));
-				else if (type.hasTransformFrom(vt))
-					return type.transformFrom(value);
-				else if (vt.hasTransformTo(type))
-					return vt.transformTo(value, type);
+					return (T)toArray(to, new ObjectList(value.toString()).setBeanSession(this));
+				else if (to.hasTransformFrom(from))
+					return to.transformFrom(value);
+				else if (from.hasTransformTo(to))
+					return from.transformTo(value, to);
 				else
-					return (T)toArray(type, new ObjectList((Object[])StringUtils.split(value.toString())).setBeanSession(this));
+					return (T)toArray(to, new ObjectList((Object[])StringUtils.split(value.toString())).setBeanSession(this));
 			}
 
 			// Target type is some sort of Map that needs to be converted.
-			if (type.isMap()) {
+			if (to.isMap()) {
 				try {
-					if (value instanceof Map) {
-						Map m = type.canCreateNewInstance(outer) ? (Map)type.newInstance(outer) : new ObjectMap(this);
-						ClassMeta keyType = type.getKeyType(), valueType = type.getValueType();
+					if (from.isMap()) {
+						Map m = to.canCreateNewInstance(outer) ? (Map)to.newInstance(outer) : new ObjectMap(this);
+						ClassMeta keyType = to.getKeyType(), valueType = to.getValueType();
 						for (Map.Entry e : (Set<Map.Entry>)((Map)value).entrySet()) {
 							Object k = e.getKey();
 							if (keyType.isNotObject()) {
@@ -539,31 +567,33 @@ public class BeanSession extends Session {
 							m.put(k, v);
 						}
 						return (T)m;
-					} else if (!type.canCreateNewInstanceFromString(outer)) {
+					} else if (!to.canCreateNewInstanceFromString(outer)) {
 						ObjectMap m = new ObjectMap(value.toString());
 						m.setBeanSession(this);
-						return convertToMemberType(outer, m, type);
+						return convertToMemberType(outer, m, to);
 					}
 				} catch (Exception e) {
-					throw new InvalidDataConversionException(value.getClass(), type, e);
+					throw new InvalidDataConversionException(value.getClass(), to, e);
 				}
 			}
 
 			// Target type is some sort of Collection
-			if (type.isCollection()) {
+			if (to.isCollection()) {
 				try {
-					Collection l = type.canCreateNewInstance(outer) ? (Collection)type.newInstance(outer) : type.isSet() ? new LinkedHashSet<>() : new ObjectList(this);
-					ClassMeta elementType = type.getElementType();
+					Collection l = to.canCreateNewInstance(outer) ? (Collection)to.newInstance(outer) : to.isSet() ? new LinkedHashSet<>() : new ObjectList(this);
+					ClassMeta elementType = to.getElementType();
 
-					if (value.getClass().isArray())
+					if (from.isArray())
 						for (Object o : (Object[])value)
 							l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
-					else if (value instanceof Collection)
+					else if (from.isCollection())
 						for (Object o : (Collection)value)
 							l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
-					else if (value instanceof Map)
+					else if (from.isMap())
 						l.add(elementType.isObject() ? value : convertToMemberType(l, value, elementType));
-					else if (value instanceof String) {
+					else if (isNullOrEmpty(value))
+						return null;
+					else if (from.isString()) {
 						String s = value.toString();
 						if (isObjectList(s, false)) {
 							ObjectList l2 = new ObjectList(s);
@@ -571,38 +601,40 @@ public class BeanSession extends Session {
 							for (Object o : l2)
 								l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
 						} else {
-							throw new InvalidDataConversionException(value.getClass(), type, null);
+							throw new InvalidDataConversionException(value.getClass(), to, null);
 						}
 					}
-					else if (! value.toString().isEmpty())
-						throw new InvalidDataConversionException(value.getClass(), type, null);
+					else
+						throw new InvalidDataConversionException(value.getClass(), to, null);
 					return (T)l;
 				} catch (InvalidDataConversionException e) {
 					throw e;
 				} catch (Exception e) {
-					throw new InvalidDataConversionException(value.getClass(), type, e);
+					throw new InvalidDataConversionException(value.getClass(), to, e);
 				}
 			}
 
-			if (type.isEnum()) {
-				if (type.canCreateNewInstanceFromString(outer))
-					return type.newInstanceFromString(outer, value.toString());
+			if (to.isEnum()) {
+				if (to.canCreateNewInstanceFromString(outer))
+					return to.newInstanceFromString(outer, value.toString());
+				if (isNullOrEmpty(value))
+					return null;
 				return (T)Enum.valueOf((Class<? extends Enum>)tc, value.toString());
 			}
 
-			if (type.isString()) {
-				if (vt.isByteArray()) {
+			if (to.isString()) {
+				if (from.isByteArray()) {
 					return (T) new String((byte[])value);
-				} else if (vt.isMapOrBean() || vt.isCollectionOrArray()) {
+				} else if (from.isMapOrBean() || from.isCollectionOrArray()) {
 					if (JsonSerializer.DEFAULT_LAX != null)
 						return (T)JsonSerializer.DEFAULT_LAX.serialize(value);
-				} else if (vt.isClass()) {
+				} else if (from.isClass()) {
 					return (T)((Class<?>)value).getName();
 				}
 				return (T)value.toString();
 			}
 
-			if (type.isCharSequence()) {
+			if (to.isCharSequence()) {
 				Class<?> c = value.getClass();
 				if (c.isArray()) {
 					if (c.getComponentType().isPrimitive()) {
@@ -615,31 +647,34 @@ public class BeanSession extends Session {
 					value = new ObjectList((Object[])value).setBeanSession(this);
 				}
 
-				return type.newInstanceFromString(outer, value.toString());
+				return to.newInstanceFromString(outer, value.toString());
 			}
 
-			if (type.isBoolean() && ! hasTransform(vt, type)) {
-				if (value instanceof Number)
+			if (to.isBoolean()) {
+				if (from.isNumber())
 					return (T)(Boolean.valueOf(((Number)value).intValue() != 0));
-				return (T)Boolean.valueOf(value.toString());
+				if (isNullOrEmpty(value))
+					return null;
+				if (! hasTransform(from, to))
+					return (T)Boolean.valueOf(value.toString());
 			}
 
 			// It's a bean being initialized with a Map
-			if (type.isBean() && value instanceof Map) {
+			if (to.isBean() && value instanceof Map) {
 				if (value instanceof ObjectMap) {
 					ObjectMap m2 = (ObjectMap)value;
-					String typeName = m2.getString(getBeanTypePropertyName(type));
+					String typeName = m2.getString(getBeanTypePropertyName(to));
 					if (typeName != null) {
-						ClassMeta cm = type.getBeanRegistry().getClassMeta(typeName);
-						if (cm != null && isParentClass(type.innerClass, cm.innerClass))
+						ClassMeta cm = to.getBeanRegistry().getClassMeta(typeName);
+						if (cm != null && isParentClass(to.innerClass, cm.innerClass))
 							return (T)m2.cast(cm);
 					}
 				}
 				return newBeanMap(tc).load((Map<?,?>) value).getBean();
 			}
 
-			if (type.isInputStream()) {
-				if (vt.isByteArray()) {
+			if (to.isInputStream()) {
+				if (from.isByteArray()) {
 					byte[] b = (byte[])value;
 					return (T) new ByteArrayInputStream(b, 0, b.length);
 				}
@@ -647,16 +682,16 @@ public class BeanSession extends Session {
 				return (T)new ByteArrayInputStream(b, 0, b.length);
 			}
 
-			if (type.isReader()) {
-				if (vt.isByteArray()) {
+			if (to.isReader()) {
+				if (from.isByteArray()) {
 					byte[] b = (byte[])value;
 					return (T) new StringReader(new String(b));
 				}
 				return (T)new StringReader(value.toString());
 			}
 
-			if (type.isCalendar() && ! hasTransform(vt, type)) {
-				if (vt.isCalendar()) {
+			if (to.isCalendar()) {
+				if (from.isCalendar()) {
 					Calendar c = (Calendar)value;
 					if (value instanceof GregorianCalendar) {
 						GregorianCalendar c2 = new GregorianCalendar(c.getTimeZone());
@@ -664,7 +699,7 @@ public class BeanSession extends Session {
 						return (T)c2;
 					}
 				}
-				if (vt.isDate()) {
+				if (from.isDate()) {
 					Date d = (Date)value;
 					if (value instanceof GregorianCalendar) {
 						GregorianCalendar c2 = new GregorianCalendar(TimeZone.getDefault());
@@ -674,37 +709,41 @@ public class BeanSession extends Session {
 				}
 			}
 
-			if (type.isDate() && type.getInnerClass() == Date.class) {
-				if (vt.isCalendar())
+			if (to.isDate() && to.getInnerClass() == Date.class) {
+				if (from.isCalendar())
 					return (T)((Calendar)value).getTime();
 			}
 
-			if (type.hasTransformFrom(vt))
-				return type.transformFrom(value);
+			if (to.hasTransformFrom(from))
+				return to.transformFrom(value);
 
-			if (vt.hasTransformTo(type))
-				return vt.transformTo(value, type);
+			if (from.hasTransformTo(to))
+				return from.transformTo(value, to);
 
-			if (type.isBean())
-				return newBeanMap(type.getInnerClass()).load(value.toString()).getBean();
+			if (to.isBean())
+				return newBeanMap(to.getInnerClass()).load(value.toString()).getBean();
 
-			if (type.canCreateNewInstanceFromNumber(outer) && value instanceof Number)
-				return type.newInstanceFromNumber(this, outer, (Number)value);
+			if (to.canCreateNewInstanceFromNumber(outer) && value instanceof Number)
+				return to.newInstanceFromNumber(this, outer, (Number)value);
 
-			if (type.canCreateNewInstanceFromString(outer))
-				return type.newInstanceFromString(outer, value.toString());
+			if (to.canCreateNewInstanceFromString(outer))
+				return to.newInstanceFromString(outer, value.toString());
 
 		} catch (Exception e) {
-			throw new InvalidDataConversionException(value, type, e);
+			throw new InvalidDataConversionException(value, to, e);
 		}
 
-		throw new InvalidDataConversionException(value, type, null);
+		throw new InvalidDataConversionException(value, to, null);
 	}
 
 	private static boolean hasTransform(ClassMeta<?> from, ClassMeta<?> to) {
 		return to.hasTransformFrom(from) || from.hasTransformTo(to);
 	}
 
+	private static final boolean isNullOrEmpty(Object o) {
+		return o == null || o.toString().equals("") || o.toString().equals("null");
+	}
+
 	private static int getMultiplier(String s) {
 		if (s.endsWith("G"))
 			return 1024*1024*1024;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index e7d5b14..c4dc13a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -357,7 +357,7 @@ public class HttpPartSchema {
 				notAllowed.appendIf(minItems != null, "minItems");
 				notAllowed.appendIf(minLength != null, "minLength");
 				notAllowed.appendIf(minProperties != null, "minProperties");
-				invalidFormat = ! format.isOneOf(Format.NO_FORMAT);
+				invalidFormat = ! format.isOneOf(Format.NO_FORMAT, Format.UON);
 				break;
 			}
 			case FILE: {
@@ -376,7 +376,7 @@ public class HttpPartSchema {
 				notAllowed.appendIf(minItems != null, "minItems");
 				notAllowed.appendIf(minLength != null, "minLength");
 				notAllowed.appendIf(minProperties != null, "minProperties");
-				invalidFormat = ! format.isOneOf(Format.NO_FORMAT, Format.INT32, Format.INT64);
+				invalidFormat = ! format.isOneOf(Format.NO_FORMAT, Format.UON, Format.INT32, Format.INT64);
 				break;
 			}
 			case NUMBER: {
@@ -392,7 +392,7 @@ public class HttpPartSchema {
 				notAllowed.appendIf(minItems != null, "minItems");
 				notAllowed.appendIf(minLength != null, "minLength");
 				notAllowed.appendIf(minProperties != null, "minProperties");
-				invalidFormat = ! format.isOneOf(Format.NO_FORMAT, Format.FLOAT, Format.DOUBLE);
+				invalidFormat = ! format.isOneOf(Format.NO_FORMAT, Format.UON, Format.FLOAT, Format.DOUBLE);
 				break;
 			}
 			case OBJECT: {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java
index 5c7a688..8913af3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartSerializer.java
@@ -144,6 +144,7 @@ public class OpenApiPartSerializer extends UonPartSerializer {
 			type = object();
 		HttpPartSchema.Type t = schema.getType(type);
 		HttpPartSchema.Format f = schema.getFormat();
+		HttpPartSchema.CollectionFormat cf = schema.getCollectionFormat();
 
 		String out = null;
 
@@ -154,82 +155,94 @@ public class OpenApiPartSerializer extends UonPartSerializer {
 			type = schema.getParsedType();
 		}
 
-		if (t == STRING) {
-
-			if (f == BYTE)
-				out = base64Encode(toType(value, CM_ByteArray));
-			else if (f == BINARY)
-				out = toHex(toType(value, CM_ByteArray));
-			else if (f == BINARY_SPACED)
-				out = toSpacedHex(toType(value, CM_ByteArray));
-			else if (f == DATE)
-				out = toIsoDate(toType(value, CM_Calendar));
-			else if (f == DATE_TIME)
-				out = toIsoDateTime(toType(value, CM_Calendar));
-			else if (f == HttpPartSchema.Format.UON)
-				out = super.serialize(partType, schema, value);
-			else
-				out = toType(value, string());
-
-		} else if (t == ARRAY) {
-
-			List<String> l = new ArrayList<>();
-			HttpPartSchema items = schema.getItems();
-			ClassMeta<?> vt = getClassMetaForObject(value);
-
-			if (type.isArray()) {
-				for (int i = 0; i < Array.getLength(value); i++)
-					l.add(serialize(partType, items, Array.get(value, i)));
-			} else if (type.isCollection()) {
-				for (Object o : (Collection<?>)value)
-					l.add(serialize(partType, items, o));
-			} else if (vt.hasTransformTo(String[].class)) {
-				l.add(serialize(partType, items, value));
-			}
+		if (value != null) {
+
+			if (t == STRING) {
+
+				if (f == BYTE)
+					out = base64Encode(toType(value, CM_ByteArray));
+				else if (f == BINARY)
+					out = toHex(toType(value, CM_ByteArray));
+				else if (f == BINARY_SPACED)
+					out = toSpacedHex(toType(value, CM_ByteArray));
+				else if (f == DATE)
+					out = toIsoDate(toType(value, CM_Calendar));
+				else if (f == DATE_TIME)
+					out = toIsoDateTime(toType(value, CM_Calendar));
+				else if (f == HttpPartSchema.Format.UON)
+					out = super.serialize(partType, schema, value);
+				else
+					out = toType(value, string());
+
+			} else if (t == ARRAY) {
+
+				if (cf == HttpPartSchema.CollectionFormat.UON)
+					out = super.serialize(partType, null, value);
+				else {
+					List<String> l = new ArrayList<>();
+
+					HttpPartSchema items = schema.getItems();
+					ClassMeta<?> vt = getClassMetaForObject(value);
+
+					if (type.isArray()) {
+						for (int i = 0; i < Array.getLength(value); i++)
+							l.add(serialize(partType, items, Array.get(value, i)));
+					} else if (type.isCollection()) {
+						for (Object o : (Collection<?>)value)
+							l.add(serialize(partType, items, o));
+					} else if (vt.hasTransformTo(String[].class)) {
+						l.add(serialize(partType, items, value));
+					}
+
+					if (cf == PIPES)
+						out = joine(l, '|');
+					else if (cf == SSV)
+						out = join(l, ' ');
+					else if (cf == TSV)
+						out = join(l, '\t');
+					else
+						out = joine(l, ',');
+				}
 
-			HttpPartSchema.CollectionFormat cf = schema.getCollectionFormat();
-
-			if (cf == PIPES)
-				out = joine(l, '|');
-			else if (cf == SSV)
-				out = join(l, ' ');
-			else if (cf == TSV)
-				out = join(l, '\t');
-			else if (cf == HttpPartSchema.CollectionFormat.UON)
-				out = super.serialize(partType, null, l);
-			else
-				out = joine(l, ',');
-
-		} else if (t == BOOLEAN || t == INTEGER || t == NUMBER) {
-			out = value == null ? "null" : value.toString();
-
-		} else if (t == OBJECT) {
-
-			if (schema.hasProperties() && type.isMapOrBean()) {
-				ObjectMap m = new ObjectMap();
-				if (type.isBean()) {
-					for (Map.Entry<String,Object> e : BC.createBeanSession().toBeanMap(value).entrySet())
-						m.put(e.getKey(), serialize(partType, schema.getProperty(e.getKey()), e.getValue()));
+			} else if (t == BOOLEAN || t == INTEGER || t == NUMBER) {
+
+				if (cf == HttpPartSchema.CollectionFormat.UON)
+					out = super.serialize(partType, null, value);
+				else
+					out = value.toString();
+
+			} else if (t == OBJECT) {
+
+				if (cf == HttpPartSchema.CollectionFormat.UON) {
+					out = super.serialize(partType, null, value);
+				} else if (schema.hasProperties() && type.isMapOrBean()) {
+					ObjectMap m = new ObjectMap();
+					if (type.isBean()) {
+						for (Map.Entry<String,Object> e : BC.createBeanSession().toBeanMap(value).entrySet())
+							m.put(e.getKey(), serialize(partType, schema.getProperty(e.getKey()), e.getValue()));
+					} else {
+						for (Map.Entry e : (Set<Map.Entry>)((Map)value).entrySet())
+							m.put(asString(e.getKey()), serialize(partType, schema.getProperty(asString(e.getKey())), e.getValue()));
+					}
+					out = super.serialize(m);
 				} else {
-					for (Map.Entry e : (Set<Map.Entry>)((Map)value).entrySet())
-						m.put(asString(e.getKey()), serialize(partType, schema.getProperty(asString(e.getKey())), e.getValue()));
+					out = super.serialize(partType, schema, value);
 				}
-				out = super.serialize(m);
-			} else {
-				out = super.serialize(partType, schema, value);
-			}
 
-		} else if (t == FILE) {
-			throw new SerializeException("File part not supported.");
+			} else if (t == FILE) {
+				throw new SerializeException("File part not supported.");
 
-		} else if (t == NO_TYPE) {
-			// This should never be returned by HttpPartSchema.getType(ClassMeta).
-			throw new SerializeException("Invalid type.");
+			} else if (t == NO_TYPE) {
+				// This should never be returned by HttpPartSchema.getType(ClassMeta).
+				throw new SerializeException("Invalid type.");
+			}
 		}
 
 		schema.validateInput(out);
 		if (out == null)
 			out = schema.getDefault();
+		if (out == null)
+			out = "null";
 		return out;
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
index 72902e1..8381305 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/TransformCache.java
@@ -64,6 +64,18 @@ public class TransformCache {
 				}
 			}
 		);
+
+		// String-to-Boolean transform should allow for "null" keyword.
+		add(String.class, Boolean.class,
+			new Transform<String,Boolean>() {
+				@Override
+				public Boolean transform(Object outer, String in) {
+					if (in == null || "null".equals(in) || in.isEmpty())
+						return null;
+					return Boolean.valueOf(in);
+				}
+			}
+		);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwapper.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwapper.java
new file mode 100644
index 0000000..69e1582
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/PojoSwapper.java
@@ -0,0 +1,24 @@
+// ***************************************************************************************************************************
+// * 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.transform;
+
+import org.apache.juneau.*;
+
+/**
+ * TODO
+ *
+ */
+public interface PojoSwapper {
+
+	public <T> T swap(Object o, ClassMeta<T> toType);
+}