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 8abfc70  Implement OpenApiPartSerializer
8abfc70 is described below

commit 8abfc7027cbffd7ab2474dfe6d3bbdc8a90e4555
Author: JamesBognar <[email protected]>
AuthorDate: Thu Jul 5 16:56:49 2018 -0400

    Implement OpenApiPartSerializer
---
 .../juneau/httppart/OpenApiPartSerializerTest.java | 1079 ++++++++++++++++++++
 .../main/java/org/apache/juneau/BeanSession.java   |    5 +-
 .../src/main/java/org/apache/juneau/ClassMeta.java |   36 +-
 .../org/apache/juneau/httppart/HttpPartSchema.java |    2 +-
 .../apache/juneau/httppart/OpenApiPartParser.java  |   18 +-
 .../juneau/httppart/OpenApiPartSerializer.java     |  280 +++--
 .../org/apache/juneau/internal/StringUtils.java    |   20 +
 .../apache/juneau/rest/BasicRestCallHandler.java   |    7 +
 .../java/org/apache/juneau/rest/RestContext.java   |   46 +-
 .../org/apache/juneau/rest/RestContextBuilder.java |   20 +
 .../juneau/rest/annotation/RestResource.java       |   25 +
 11 files changed, 1363 insertions(+), 175 deletions(-)

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
new file mode 100644
index 0000000..7289117
--- /dev/null
+++ 
b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/httppart/OpenApiPartSerializerTest.java
@@ -0,0 +1,1079 @@
+// 
***************************************************************************************************************************
+// * 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.httppart;
+
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.junit.*;
+
+public class OpenApiPartSerializerTest {
+
+       static OpenApiPartSerializer s = OpenApiPartSerializer.DEFAULT;
+
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Input validations
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       @Test
+       public void a01_outputValidations_nullOutput() throws Exception {
+               HttpPartSchema ps = schema().build();
+               assertNull(s.serialize(ps, null));
+
+               ps = schema().required(false).build();
+               assertNull(s.serialize(ps, null));
+
+               ps = schema().required().build();
+               try {
+                       s.serialize(ps, null);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Required value not provided.", 
e.getMessage());
+               }
+
+               ps = schema().required(true).build();
+               try {
+                       s.serialize(ps, null);
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Required value not provided.", 
e.getMessage());
+               }
+       }
+
+       @Test
+       public void a02_outputValidations_emptyOutput() throws Exception {
+
+               HttpPartSchema ps = schema().allowEmptyValue().build();
+               assertEquals("", s.serialize(ps, ""));
+
+               ps = schema().allowEmptyValue().build();
+               assertEquals("", s.serialize(ps, ""));
+
+               ps = schema().allowEmptyValue(false).build();
+               try {
+                       s.serialize(ps, "");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Empty value not allowed.", 
e.getMessage());
+               }
+
+               try {
+                       s.serialize(ps, "");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Empty value not allowed.", 
e.getMessage());
+               }
+
+               assertEquals(" ", s.serialize(ps, " "));
+       }
+
+       @Test
+       public void a03_outputValidations_pattern() throws Exception {
+               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));
+
+               try {
+                       s.serialize(ps, "y");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match expected pattern.  
Must match pattern: x.*", e.getMessage());
+               }
+
+               try {
+                       s.serialize(ps, "");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match expected pattern.  
Must match pattern: x.*", e.getMessage());
+               }
+
+               // Blank/null patterns are ignored.
+               ps = schema().pattern("").allowEmptyValue().build();
+               assertEquals("x", s.serialize(ps, "x"));
+               ps = schema().pattern(null).allowEmptyValue().build();
+               assertEquals("x", s.serialize(ps, "x"));
+       }
+
+       @Test
+       public void a04_outputValidations_enum() throws Exception {
+               HttpPartSchema ps = 
schema()._enum("foo").allowEmptyValue().build();
+
+               assertEquals("foo", s.serialize(ps, "foo"));
+               assertEquals(null, s.serialize(ps, null));
+
+               try {
+                       s.serialize(ps, "bar");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match one of the expected 
values.  Must be one of the following: ['foo']", e.getMessage());
+               }
+
+               try {
+                       s.serialize(ps, "");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Value does not match one of the expected 
values.  Must be one of the following: ['foo']", e.getMessage());
+               }
+
+               ps = schema()._enum((Set<String>)null).build();
+               assertEquals("foo", s.serialize(ps, "foo"));
+               ps = 
schema()._enum((Set<String>)null).allowEmptyValue().build();
+               assertEquals("foo", s.serialize(ps, "foo"));
+
+               ps = schema()._enum("foo","foo").build();
+               assertEquals("foo", s.serialize(ps, "foo"));
+       }
+
+       @Test
+       public void a05_outputValidations_minMaxLength() throws Exception {
+               HttpPartSchema ps = 
schema().minLength(1l).maxLength(2l).allowEmptyValue().build();
+
+               assertEquals(null, s.serialize(ps, null));
+               assertEquals("1", s.serialize(ps, "1"));
+               assertEquals("12", s.serialize(ps, "12"));
+
+               try {
+                       s.serialize(ps, "");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Minimum length of value not met.", 
e.getMessage());
+               }
+
+               try {
+                       s.serialize(ps, "123");
+                       fail();
+               } catch (Exception e) {
+                       assertEquals("Maximum length of value exceeded.", 
e.getMessage());
+               }
+       }
+
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = string
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class C1 {
+//             private String f;
+//             public C1(byte[] b) {
+//                     f = "C1-" + new String(b);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class C2 {
+//             private String f;
+//             public C2(String s) {
+//                     f = "C2-" + s;
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class C3 {
+//             private String f;
+//             public C3(String[] in) {
+//                     f = "C3-" + JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//
+//     @Test
+//     public void c01_stringType_simple() throws Exception {
+//             HttpPartSchema ps = schema("string").build();
+//             assertEquals("foo", s.serialize(ps, "foo", String.class));
+//     }
+//
+//     @Test
+//     public void c02_stringType_default() throws Exception {
+//             HttpPartSchema ps = schema("string")._default("x").build();
+//             assertEquals("foo", s.serialize(ps, "foo", String.class));
+//             assertEquals("x", s.serialize(ps, null, String.class));
+//     }
+//
+//     @Test
+//     public void c03_stringType_byteFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "byte").build();
+//             String in = base64Encode("foo".getBytes());
+//             assertEquals("foo", s.serialize(ps, in, String.class));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
InputStream.class)));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
Reader.class)));
+//             assertEquals("C1-foo", s.serialize(ps, in, 
C1.class).toString());
+//     }
+//
+//     @Test
+//     public void c04_stringType_binaryFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "binary").build();
+//             String in = toHex("foo".getBytes());
+//             assertEquals("foo", s.serialize(ps, in, String.class));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
InputStream.class)));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
Reader.class)));
+//             assertEquals("C1-foo", s.serialize(ps, in, 
C1.class).toString());
+//     }
+//
+//     @Test
+//     public void c05_stringType_binarySpacedFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "binary-spaced").build();
+//             String in = toSpacedHex("foo".getBytes());
+//             assertEquals("foo", s.serialize(ps, in, String.class));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
InputStream.class)));
+//             assertEquals("foo", IOUtils.read(s.serialize(ps, in, 
Reader.class)));
+//             assertEquals("C1-foo", s.serialize(ps, in, 
C1.class).toString());
+//     }
+//
+//     @Test
+//     public void c06_stringType_dateFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "date").build();
+//             String in = "2012-12-21";
+//             assertTrue(s.serialize(ps, in, String.class).contains("2012"));
+//             assertTrue(s.serialize(ps, in, 
Date.class).toString().contains("2012"));
+//             assertEquals(2012, s.serialize(ps, in, 
Calendar.class).get(Calendar.YEAR));
+//             assertEquals(2012, s.serialize(ps, in, 
GregorianCalendar.class).get(Calendar.YEAR));
+//     }
+//
+//     @Test
+//     public void c07_stringType_dateTimeFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "date-time").build();
+//             String in = "2012-12-21T12:34:56.789";
+//             assertTrue(s.serialize(ps, in, String.class).contains("2012"));
+//             assertTrue(s.serialize(ps, in, 
Date.class).toString().contains("2012"));
+//             assertEquals(2012, s.serialize(ps, in, 
Calendar.class).get(Calendar.YEAR));
+//             assertEquals(2012, s.serialize(ps, in, 
GregorianCalendar.class).get(Calendar.YEAR));
+//     }
+//
+//     @Test
+//     public void c08_stringType_uonFormat() throws Exception {
+//             HttpPartSchema ps = schema("string", "uon").build();
+//             assertEquals("foo", s.serialize(ps, "foo", String.class));
+//             assertEquals("foo", s.serialize(ps, "'foo'", String.class));
+//             assertEquals("C2-foo", s.serialize(ps, "'foo'", 
C2.class).toString());
+//             // UonPartParserTest should handle all other cases.
+//     }
+//
+//     @Test
+//     public void c09_stringType_noneFormat() throws Exception {
+//             // If no format is specified, then we should transform directly 
from a string.
+//             HttpPartSchema ps = schema("string").build();
+//             assertEquals("foo", s.serialize(ps, "foo", String.class));
+//             assertEquals("'foo'", s.serialize(ps, "'foo'", String.class));
+//             assertEquals("C2-foo", s.serialize(ps, "foo", 
C2.class).toString());
+//     }
+//
+//     @Test
+//     public void c10_stringType_noneFormat_2d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").items(schema("string")).build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
Object[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, Object.class));
+//             Object o = s.serialize(ps, "foo,bar", Object.class);
+//             assertObjectEquals("['foo','bar']", o);
+//             assertClass(ObjectList.class, o);
+//             assertObjectEquals("['C2-foo','C2-bar']", s.serialize(ps, 
"foo,bar", C2[].class));
+//             assertObjectEquals("['C2-foo','C2-bar']", s.serialize(ps, 
"foo,bar", List.class, C2.class));
+//             assertEquals("C3-['foo','bar']", s.serialize(ps, "foo,bar", 
C3.class).toString());
+//     }
+//
+//     @Test
+//     public void c11_stringType_noneFormat_3d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").items(schema("array").items(schema("string"))).build();
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", String[][].class));
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", List.class, String[].class));
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", List.class, List.class, String.class));
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", Object[][].class));
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", List.class, Object[].class));
+//             assertObjectEquals("[['foo','bar'],['baz']]", s.serialize(ps, 
"foo,bar|baz", List.class, List.class, Object.class));
+//             Object o = s.serialize(ps, "foo,bar|baz", Object.class);
+//             assertObjectEquals("[['foo','bar'],['baz']]", o);
+//             assertClass(ObjectList.class, o);
+//             assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", 
s.serialize(ps, "foo,bar|baz", C2[][].class));
+//             assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", 
s.serialize(ps, "foo,bar|baz", List.class, C2[].class));
+//             assertObjectEquals("[['C2-foo','C2-bar'],['C2-baz']]", 
s.serialize(ps, "foo,bar|baz", List.class, List.class, C2.class));
+//             
assertObjectEquals("['C3-[\\'foo\\',\\'bar\\']','C3-[\\'baz\\']']", 
s.serialize(ps, "foo,bar|baz", C3[].class));
+//             
assertObjectEquals("['C3-[\\'foo\\',\\'bar\\']','C3-[\\'baz\\']']", 
s.serialize(ps, "foo,bar|baz", List.class, C3.class));
+//     }
+//
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = array
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class D {
+//             private String f;
+//             public D(String in) {
+//                     this.f = "D-" + in;
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     @Test
+//     public void d01_arrayType_collectionFormatCsv() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("csv").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo,bar", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo,bar", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
Object.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
ObjectList.class));
+//     }
+//
+//     @Test
+//     public void d02_arrayType_collectionFormatPipes() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo|bar", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo|bar", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
Object.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo|bar", 
ObjectList.class));
+//     }
+//
+//     @Test
+//     public void d03_arrayType_collectionFormatSsv() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("ssv").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo 
bar", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, "foo 
bar", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
Object.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo bar", 
ObjectList.class));
+//     }
+//
+//     @Test
+//     public void d04_arrayType_collectionFormatTsv() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("tsv").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo\tbar", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo\tbar", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
Object.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo\tbar", 
ObjectList.class));
+//     }
+//
+//     @Test
+//     public void d05_arrayType_collectionFormatUon() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("uon").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"@(foo,bar)", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"@(foo,bar)", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", Object.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", ObjectList.class));
+//     }
+//
+//     @Test
+//     public void d06a_arrayType_collectionFormatNone() throws Exception {
+//             HttpPartSchema ps = schema("array").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo,bar", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"foo,bar", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, "foo,bar", 
Object.class));
+//     }
+//
+//     @Test
+//     public void d06b_arrayType_collectionFormatNone_autoDetectUon() throws 
Exception {
+//             HttpPartSchema ps = schema("array").build();
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", String[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", Object[].class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"@(foo,bar)", D[].class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", List.class, String.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", List.class, Object.class));
+//             assertObjectEquals("['D-foo','D-bar']", s.serialize(ps, 
"@(foo,bar)", List.class, D.class));
+//             assertObjectEquals("['foo','bar']", s.serialize(ps, 
"@(foo,bar)", Object.class));
+//     }
+//
+//     @Test
+//     public void d07_arrayType_collectionFormatMulti() throws Exception {
+//             // collectionFormat=multi should not do any sort of splitting.
+//             HttpPartSchema ps = 
schema("array").collectionFormat("multi").build();
+//             assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", 
String[].class));
+//             assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", 
Object[].class));
+//             assertObjectEquals("['D-foo,bar']", s.serialize(ps, "foo,bar", 
D[].class));
+//             assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", 
List.class, String.class));
+//             assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", 
List.class, Object.class));
+//             assertObjectEquals("['D-foo,bar']", s.serialize(ps, "foo,bar", 
List.class, D.class));
+//             assertObjectEquals("['foo,bar']", s.serialize(ps, "foo,bar", 
Object.class));
+//     }
+//
+//     @Test
+//     public void d08_arrayType_collectionFormatCsvAndPipes() throws 
Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").items(schema("array").collectionFormat("csv")).build();
+//             assertObjectEquals("[['foo','bar'],['baz','qux']]", 
s.serialize(ps, "foo,bar|baz,qux", String[][].class));
+//             assertObjectEquals("[['foo','bar'],['baz','qux']]", 
s.serialize(ps, "foo,bar|baz,qux", Object[][].class));
+//             assertObjectEquals("[['D-foo','D-bar'],['D-baz','D-qux']]", 
s.serialize(ps, "foo,bar|baz,qux", D[][].class));
+//             assertObjectEquals("[['foo','bar'],['baz','qux']]", 
s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, String.class));
+//             assertObjectEquals("[['foo','bar'],['baz','qux']]", 
s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, Object.class));
+//             assertObjectEquals("[['D-foo','D-bar'],['D-baz','D-qux']]", 
s.serialize(ps, "foo,bar|baz,qux", List.class, List.class, D.class));
+//             assertObjectEquals("[['foo','bar'],['baz','qux']]", 
s.serialize(ps, "foo,bar|baz,qux", Object.class));
+//     }
+//
+//     @Test
+//     public void d09_arrayType_itemsInteger() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("csv").items(schema("integer")).build();
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
int[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Integer[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Object[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Integer.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Object.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Object.class));
+//     }
+//
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = boolean
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class E1 {
+//             private String f;
+//             public E1(Boolean in) {
+//                     this.f = "E1-" + in.toString();
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class E2 {
+//             private String f;
+//             public E2(Boolean[] in) {
+//                     this.f = "E2-" + 
JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     @Test
+//     public void e01_booleanType() throws Exception {
+//             HttpPartSchema ps = schema("boolean").build();
+//             assertEquals(true, s.serialize(ps, "true", boolean.class));
+//             assertEquals(true, s.serialize(ps, "true", Boolean.class));
+//             assertEquals(true, s.serialize(ps, "True", boolean.class));
+//             assertEquals(true, s.serialize(ps, "TRUE", boolean.class));
+//             assertEquals("true", s.serialize(ps, "true", String.class));
+//             assertEquals(true, s.serialize(ps, "true", Object.class));
+//             assertObjectEquals("'E1-true'", s.serialize(ps, "true", 
E1.class));
+//     }
+//
+//     @Test
+//     public void e02_booleanType_2d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").items(schema("boolean")).build();
+//             assertObjectEquals("[true,true]", s.serialize(ps, "true,true", 
boolean[].class));
+//             assertObjectEquals("[true,true]", s.serialize(ps, "true,true", 
Boolean[].class));
+//             assertObjectEquals("[true,true]", s.serialize(ps, "true,true", 
List.class, Boolean.class));
+//             assertObjectEquals("['true','true']", s.serialize(ps, 
"true,true", String[].class));
+//             assertObjectEquals("['true','true']", s.serialize(ps, 
"true,true", List.class, String.class));
+//             assertObjectEquals("[true,true]", s.serialize(ps, "true,true", 
Object[].class));
+//             assertObjectEquals("[true,true]", s.serialize(ps, "true,true", 
List.class, Object.class));
+//             assertObjectEquals("['E1-true','E1-true']", s.serialize(ps, 
"true,true", E1[].class));
+//             assertObjectEquals("['E1-true','E1-true']", s.serialize(ps, 
"true,true", List.class, E1.class));
+//             assertObjectEquals("'E2-[true,true]'", s.serialize(ps, 
"true,true", E2.class));
+//
+//             assertObjectEquals("[true,true]", s.serialize(ps, "True,true", 
boolean[].class));
+//             assertObjectEquals("[true,true]", s.serialize(ps, "TRUE,true", 
boolean[].class));
+//     }
+//
+//     @Test
+//     public void e03_booleanType_3d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").items(schema("array").items(schema("boolean"))).build();
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", boolean[][].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", List.class, boolean[].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", Boolean[][].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", List.class, Boolean[].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", List.class, List.class, Boolean.class));
+//             assertObjectEquals("[['true','true'],['false']]", 
s.serialize(ps, "true,true|false", String[][].class));
+//             assertObjectEquals("[['true','true'],['false']]", 
s.serialize(ps, "true,true|false", List.class, List.class, String.class));
+//             assertObjectEquals("[['true','true'],['false']]", 
s.serialize(ps, "true,true|false", List.class, String[].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", Object[][].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", List.class, List.class, Object.class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"true,true|false", List.class, Object[].class));
+//             assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", 
s.serialize(ps, "true,true|false", E1[][].class));
+//             assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", 
s.serialize(ps, "true,true|false", List.class, List.class, E1.class));
+//             assertObjectEquals("[['E1-true','E1-true'],['E1-false']]", 
s.serialize(ps, "true,true|false", List.class, E1[].class));
+//             assertObjectEquals("['E2-[true,true]','E2-[false]']", 
s.serialize(ps, "true,true|false", E2[].class));
+//             assertObjectEquals("['E2-[true,true]','E2-[false]']", 
s.serialize(ps, "true,true|false", List.class, E2.class));
+//
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"True,true|false", boolean[][].class));
+//             assertObjectEquals("[[true,true],[false]]", s.serialize(ps, 
"TRUE,true|false", boolean[][].class));
+//     }
+//
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = integer
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class F1 {
+//             private String f;
+//             public F1(Integer in) {
+//                     this.f = "F1-" + in.toString();
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class F2 {
+//             private String f;
+//             public F2(Integer[] in) {
+//                     this.f = "F2-" + 
JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class F3 {
+//             private String f;
+//             public F3(Long in) {
+//                     this.f = "F3-" + in.toString();
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class F4 {
+//             private String f;
+//             public F4(Long[] in) {
+//                     this.f = "F4-" + 
JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     @Test
+//     public void f01_integerType_int32() throws Exception {
+//             HttpPartSchema ps = schema("integer", "int32").build();
+//             assertObjectEquals("1", s.serialize(ps, "1", int.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Integer.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", short.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Short.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", long.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Long.class));
+//             assertObjectEquals("'1'", s.serialize(ps, "1", String.class));
+//             Object o = s.serialize(ps, "1", Object.class);
+//             assertObjectEquals("1", o);
+//             assertClass(Integer.class, o);
+//             assertObjectEquals("'F1-1'", s.serialize(ps,  "1", F1.class));
+//     }
+//
+//     @Test
+//     public void f02_integerType_int32_2d() throws Exception {
+//             HttpPartSchema ps = schema("array").items(schema("integer", 
"int32")).build();
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
int[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Integer[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Integer.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
short[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Short[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Short.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
long[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Long[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Long.class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
String[].class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
List.class, String.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Object[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Object.class));
+//             assertObjectEquals("['F1-1','F1-2']", s.serialize(ps,  "1,2", 
F1[].class));
+//             assertObjectEquals("['F1-1','F1-2']", s.serialize(ps,  "1,2", 
List.class, F1.class));
+//             assertObjectEquals("'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();
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
int[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, int[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Integer[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Integer[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Integer.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
short[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, short[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Short[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Short[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Short.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
long[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, long[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Long[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Long[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Long.class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", String[][].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, String[].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, List.class, String.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Object[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Object[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Object.class));
+//             assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", 
s.serialize(ps,  "1,2|3", F1[][].class));
+//             assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", 
s.serialize(ps,  "1,2|3", List.class, F1[].class));
+//             assertObjectEquals("[['F1-1','F1-2'],['F1-3']]", 
s.serialize(ps,  "1,2|3", List.class, List.class, F1.class));
+//             assertObjectEquals("['F2-[1,2]','F2-[3]']", s.serialize(ps, 
"1,2|3", F2[].class));
+//             assertObjectEquals("['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();
+//             assertObjectEquals("1", s.serialize(ps, "1", int.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Integer.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", short.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Short.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", long.class));
+//             assertObjectEquals("1", s.serialize(ps, "1", Long.class));
+//             assertObjectEquals("'1'", s.serialize(ps, "1", String.class));
+//             Object o = s.serialize(ps, "1", Object.class);
+//             assertObjectEquals("1", o);
+//             assertClass(Long.class, o);
+//             assertObjectEquals("'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();
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
int[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Integer[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Integer.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
short[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Short[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Short.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
long[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Long[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Long.class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
String[].class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
List.class, String.class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", 
Object[].class));
+//             assertObjectEquals("[1,2]", s.serialize(ps, "1,2", List.class, 
Object.class));
+//             assertObjectEquals("['F3-1','F3-2']", s.serialize(ps,  "1,2", 
F3[].class));
+//             assertObjectEquals("['F3-1','F3-2']", s.serialize(ps,  "1,2", 
List.class, F3.class));
+//             assertObjectEquals("'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();
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
int[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, int[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Integer[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Integer[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Integer.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
short[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, short[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Short[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Short[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Short.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
long[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, long[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Long[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Long[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Long.class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", String[][].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, String[].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, List.class, String.class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
Object[][].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, Object[].class));
+//             assertObjectEquals("[[1,2],[3]]", s.serialize(ps, "1,2|3", 
List.class, List.class, Object.class));
+//             assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", 
s.serialize(ps,  "1,2|3", F3[][].class));
+//             assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", 
s.serialize(ps,  "1,2|3", List.class, F3[].class));
+//             assertObjectEquals("[['F3-1','F3-2'],['F3-3']]", 
s.serialize(ps,  "1,2|3", List.class, List.class, F3.class));
+//             assertObjectEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, 
"1,2|3", F4[].class));
+//             assertObjectEquals("['F4-[1,2]','F4-[3]']", s.serialize(ps, 
"1,2|3", List.class, F4.class));
+//     }
+//
+//
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = number
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class G1 {
+//             private String f;
+//             public G1(Float in) {
+//                     this.f = "G1-" + in.toString();
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class G2 {
+//             private String f;
+//             public G2(Float[] in) {
+//                     this.f = "G2-" + 
JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class G3 {
+//             private String f;
+//             public G3(Double in) {
+//                     this.f = "G3-" + in.toString();
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     public static class G4 {
+//             private String f;
+//             public G4(Double[] in) {
+//                     this.f = "G4-" + 
JsonSerializer.DEFAULT_LAX.toString(in);
+//             }
+//             @Override
+//             public String toString() {
+//                     return f;
+//             }
+//     }
+//
+//     @Test
+//     public void g01_numberType_float() throws Exception {
+//             HttpPartSchema ps = schema("number", "float").build();
+//             assertObjectEquals("1.0", s.serialize(ps, "1", float.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", Float.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", double.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", Double.class));
+//             assertObjectEquals("'1'", s.serialize(ps, "1", String.class));
+//             Object o =  s.serialize(ps, "1", Object.class);
+//             assertObjectEquals("1.0",o);
+//             assertClass(Float.class, o);
+//             assertObjectEquals("'G1-1.0'", s.serialize(ps,  "1", G1.class));
+//     }
+//
+//     @Test
+//     public void g02_numberType_float_2d() throws Exception {
+//             HttpPartSchema ps = schema("array").items(schema("number", 
"float")).build();
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
float[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Float[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Float.class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
double[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Double[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Double.class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
String[].class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
List.class, String.class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Object[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Object.class));
+//             assertObjectEquals("['G1-1.0','G1-2.0']", s.serialize(ps,  
"1,2", G1[].class));
+//             assertObjectEquals("['G1-1.0','G1-2.0']", s.serialize(ps,  
"1,2", List.class, G1.class));
+//             assertObjectEquals("'G2-[1.0,2.0]'", s.serialize(ps,  "1,2", 
G2.class));
+//     }
+//
+//     @Test
+//     public void g03_numberType_float_3d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").items(schema("array").items(schema("number",
 "float"))).build();
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", float[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, float[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Float[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Float[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Float.class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", double[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, double[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Double[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Double[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Double.class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", String[][].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, String[].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, List.class, String.class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Object[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Object[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Object.class));
+//             assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", 
s.serialize(ps,  "1,2|3", G1[][].class));
+//             assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", 
s.serialize(ps,  "1,2|3", List.class, G1[].class));
+//             assertObjectEquals("[['G1-1.0','G1-2.0'],['G1-3.0']]", 
s.serialize(ps,  "1,2|3", List.class, List.class, G1.class));
+//             assertObjectEquals("['G2-[1.0,2.0]','G2-[3.0]']", 
s.serialize(ps, "1,2|3", G2[].class));
+//             assertObjectEquals("['G2-[1.0,2.0]','G2-[3.0]']", 
s.serialize(ps, "1,2|3", List.class, G2.class));
+//     }
+//
+//     @Test
+//     public void g04_numberType_double() throws Exception {
+//             HttpPartSchema ps = schema("number", "double").build();
+//             assertObjectEquals("1.0", s.serialize(ps, "1", float.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", Float.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", double.class));
+//             assertObjectEquals("1.0", s.serialize(ps, "1", Double.class));
+//             assertObjectEquals("'1'", s.serialize(ps, "1", String.class));
+//             Object o = s.serialize(ps, "1", Object.class);
+//             assertObjectEquals("1.0", o);
+//             assertClass(Double.class, o);
+//             assertObjectEquals("'G3-1.0'", s.serialize(ps,  "1", G3.class));
+//     }
+//
+//     @Test
+//     public void g05_numberType_double_2d() throws Exception {
+//             HttpPartSchema ps = schema("array").items(schema("number", 
"double")).build();
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
float[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Float[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Float.class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
double[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Double[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Double.class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
String[].class));
+//             assertObjectEquals("['1','2']", s.serialize(ps, "1,2", 
List.class, String.class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
Object[].class));
+//             assertObjectEquals("[1.0,2.0]", s.serialize(ps, "1,2", 
List.class, Object.class));
+//             assertObjectEquals("['G3-1.0','G3-2.0']", s.serialize(ps,  
"1,2", G3[].class));
+//             assertObjectEquals("['G3-1.0','G3-2.0']", s.serialize(ps,  
"1,2", List.class, G3.class));
+//             assertObjectEquals("'G4-[1.0,2.0]'", s.serialize(ps,  "1,2", 
G4.class));
+//     }
+//
+//     @Test
+//     public void g06_numberType_double_3d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").collectionFormat("pipes").items(schema("array").items(schema("number",
 "double"))).build();
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", float[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, float[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Float[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Float[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Float.class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", double[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, double[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Double[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Double[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Double.class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", String[][].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, String[].class));
+//             assertObjectEquals("[['1','2'],['3']]", s.serialize(ps, 
"1,2|3", List.class, List.class, String.class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", Object[][].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, Object[].class));
+//             assertObjectEquals("[[1.0,2.0],[3.0]]", s.serialize(ps, 
"1,2|3", List.class, List.class, Object.class));
+//             assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", 
s.serialize(ps,  "1,2|3", G3[][].class));
+//             assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", 
s.serialize(ps,  "1,2|3", List.class, G3[].class));
+//             assertObjectEquals("[['G3-1.0','G3-2.0'],['G3-3.0']]", 
s.serialize(ps,  "1,2|3", List.class, List.class, G3.class));
+//             assertObjectEquals("['G4-[1.0,2.0]','G4-[3.0]']", 
s.serialize(ps, "1,2|3", G4[].class));
+//             assertObjectEquals("['G4-[1.0,2.0]','G4-[3.0]']", 
s.serialize(ps, "1,2|3", List.class, G4.class));
+//     }
+//
+//
+//     
//-----------------------------------------------------------------------------------------------------------------
+//     // type = object
+//     
//-----------------------------------------------------------------------------------------------------------------
+//
+//     public static class H1 {
+//             public int f;
+//     }
+//
+//     @Test
+//     public void h01_objectType() throws Exception {
+//             HttpPartSchema ps = 
HttpPartSchema.create().type("object").build();
+//             assertObjectEquals("{f:1}", s.serialize(ps, "(f=1)", H1.class));
+//             assertObjectEquals("{f:1}", s.serialize(ps, "(f=1)", 
ObjectMap.class));
+//             Object o = s.serialize(ps, "(f=1)", Object.class);
+//             assertObjectEquals("{f:1}", o);
+//             assertClass(ObjectMap.class, o);
+//     }
+//
+//     @Test
+//     public void h02_objectType_2d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").format("uon").items(schema("object")).build();
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", H1[].class));
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", List.class, H1.class));
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", ObjectMap[].class));
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", List.class, ObjectMap.class));
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", Object[].class));
+//             assertObjectEquals("[{f:1},{f:2}]", s.serialize(ps, 
"@((f=1),(f=2))", List.class, Object.class));
+//             Object o = s.serialize(ps, "@((f=1),(f=2))", Object.class);
+//             assertObjectEquals("[{f:1},{f:2}]", o);
+//             assertClass(ObjectList.class, o);
+//     }
+//
+//     @Test
+//     public void h03_objectType_3d() throws Exception {
+//             HttpPartSchema ps = 
schema("array").format("uon").items(schema("array").items(schema("object"))).build();
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", H1[][].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, H1[].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, H1.class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", ObjectMap[][].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, ObjectMap[].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, ObjectMap.class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", Object[][].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, Object[].class));
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", s.serialize(ps, 
"@(@((f=1),(f=2)),@((f=3)))", List.class, List.class, Object.class));
+//             Object o =  s.serialize(ps, "@(@((f=1),(f=2)),@((f=3)))", 
Object.class);
+//             assertObjectEquals("[[{f:1},{f:2}],[{f:3}]]", o);
+//             assertClass(ObjectList.class, o);
+//     }
+//
+//     public static class H2 {
+//             public Object f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, 
f12, f99;
+//     }
+//
+//     @Test
+//     public void h04_objectType_simpleProperties() throws Exception {
+//             HttpPartSchema ps = schema("object")
+//                     .property("f1", schema("string"))
+//                     .property("f2", schema("string", "byte"))
+//                     .property("f4", schema("string", "date-time"))
+//                     .property("f5", schema("string", "binary"))
+//                     .property("f6", schema("string", "binary-spaced"))
+//                     .property("f7", schema("string", "uon"))
+//                     .property("f8", schema("integer"))
+//                     .property("f9", schema("integer", "int64"))
+//                     .property("f10", schema("number"))
+//                     .property("f11", schema("number", "double"))
+//                     .property("f12", schema("boolean"))
+//                     .additionalProperties(schema("integer"))
+//                     .build();
+//
+//             byte[] foob = "foo".getBytes();
+//             String in = 
"(f1=foo,f2="+base64Encode(foob)+",f4=2012-12-21T12:34:56Z,f5="+toHex(foob)+",f6='"+toSpacedHex(foob)+"',f7=foo,f8=1,f9=1,f10=1,f11=1,f12=true,f99=1)";
+//
+//             H2 h2 = s.serialize(ps, in, H2.class);
+//             
assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}",
 h2);
+//             assertClass(String.class, h2.f1);
+//             assertClass(byte[].class, h2.f2);
+//             assertClass(GregorianCalendar.class, h2.f4);
+//             assertClass(byte[].class, h2.f5);
+//             assertClass(byte[].class, h2.f6);
+//             assertClass(String.class, h2.f7);
+//             assertClass(Integer.class, h2.f8);
+//             assertClass(Long.class, h2.f9);
+//             assertClass(Float.class, h2.f10);
+//             assertClass(Double.class, h2.f11);
+//             assertClass(Boolean.class, h2.f12);
+//             assertClass(Integer.class, h2.f99);
+//
+//             ObjectMap om = s.serialize(ps, in, ObjectMap.class);
+//             
assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}",
 om);
+//             assertClass(String.class, om.get("f1"));
+//             assertClass(byte[].class, om.get("f2"));
+//             assertClass(GregorianCalendar.class, om.get("f4"));
+//             assertClass(byte[].class, om.get("f5"));
+//             assertClass(byte[].class, om.get("f6"));
+//             assertClass(String.class, om.get("f7"));
+//             assertClass(Integer.class, om.get("f8"));
+//             assertClass(Long.class, om.get("f9"));
+//             assertClass(Float.class, om.get("f10"));
+//             assertClass(Double.class, om.get("f11"));
+//             assertClass(Boolean.class, om.get("f12"));
+//             assertClass(Integer.class, om.get("f99"));
+//
+//             om = (ObjectMap)s.serialize(ps, in, Object.class);
+//             
assertObjectEquals("{f1:'foo',f2:[102,111,111],f4:'2012-12-21T12:34:56Z',f5:[102,111,111],f6:[102,111,111],f7:'foo',f8:1,f9:1,f10:1.0,f11:1.0,f12:true,f99:1}",
 om);
+//             assertClass(String.class, om.get("f1"));
+//             assertClass(byte[].class, om.get("f2"));
+//             assertClass(GregorianCalendar.class, om.get("f4"));
+//             assertClass(byte[].class, om.get("f5"));
+//             assertClass(byte[].class, om.get("f6"));
+//             assertClass(String.class, om.get("f7"));
+//             assertClass(Integer.class, om.get("f8"));
+//             assertClass(Long.class, om.get("f9"));
+//             assertClass(Float.class, om.get("f10"));
+//             assertClass(Double.class, om.get("f11"));
+//             assertClass(Boolean.class, om.get("f12"));
+//             assertClass(Integer.class, om.get("f99"));
+//     }
+//
+//     @Test
+//     public void h05_objectType_arrayProperties() throws Exception {
+//             HttpPartSchema ps = schema("object")
+//                     .property("f1", schema("array").items(schema("string")))
+//                     .property("f2", schema("array").items(schema("string", 
"byte")))
+//                     .property("f4", schema("array").items(schema("string", 
"date-time")))
+//                     .property("f5", schema("array").items(schema("string", 
"binary")))
+//                     .property("f6", schema("array").items(schema("string", 
"binary-spaced")))
+//                     .property("f7", schema("array").items(schema("string", 
"uon")))
+//                     .property("f8", 
schema("array").items(schema("integer")))
+//                     .property("f9", schema("array").items(schema("integer", 
"int64")))
+//                     .property("f10", 
schema("array").items(schema("number")))
+//                     .property("f11", schema("array").items(schema("number", 
"double")))
+//                     .property("f12", 
schema("array").items(schema("boolean")))
+//                     
.additionalProperties(schema("array").items(schema("integer")))
+//                     .build();
+//
+//             byte[] foob = "foo".getBytes();
+//             String in = 
"(f1=foo,f2="+base64Encode(foob)+",f4=2012-12-21T12:34:56Z,f5="+toHex(foob)+",f6='"+toSpacedHex(foob)+"',f7=foo,f8=1,f9=1,f10=1,f11=1,f12=true,f99=1)";
+//
+//             H2 h2 = s.serialize(ps, in, H2.class);
+//             
assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}",
 h2);
+//
+//             ObjectMap om = s.serialize(ps, in, ObjectMap.class);
+//             
assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}",
 om);
+//
+//             om = (ObjectMap)s.serialize(ps, in, Object.class);
+//             
assertObjectEquals("{f1:['foo'],f2:[[102,111,111]],f4:['2012-12-21T12:34:56Z'],f5:[[102,111,111]],f6:[[102,111,111]],f7:['foo'],f8:[1],f9:[1],f10:[1.0],f11:[1.0],f12:[true],f99:[1]}",
 om);
+//     }
+//
+//     @Test
+//     public void h06_objectType_arrayProperties_pipes() throws Exception {
+//             HttpPartSchema ps = schema("object")
+//                     .property("f1", 
schema("array").collectionFormat("pipes").items(schema("string")))
+//                     .property("f2", 
schema("array").collectionFormat("pipes").items(schema("string", "byte")))
+//                     .property("f4", 
schema("array").collectionFormat("pipes").items(schema("string", "date-time")))
+//                     .property("f5", 
schema("array").collectionFormat("pipes").items(schema("string", "binary")))
+//                     .property("f6", 
schema("array").collectionFormat("pipes").items(schema("string", 
"binary-spaced")))
+//                     .property("f7", 
schema("array").collectionFormat("pipes").items(schema("string", "uon")))
+//                     .property("f8", 
schema("array").collectionFormat("pipes").items(schema("integer")))
+//                     .property("f9", 
schema("array").collectionFormat("pipes").items(schema("integer", "int64")))
+//                     .property("f10", 
schema("array").collectionFormat("pipes").items(schema("number")))
+//                     .property("f11", 
schema("array").collectionFormat("pipes").items(schema("number", "double")))
+//                     .property("f12", 
schema("array").collectionFormat("pipes").items(schema("boolean")))
+//                     
.additionalProperties(schema("array").collectionFormat("pipes").items(schema("integer")))
+//                     .build();
+//
+//             byte[] foob = "foo".getBytes(), barb = "bar".getBytes();
+//             String in = 
"(f1=foo|bar,f2="+base64Encode(foob)+"|"+base64Encode(barb)+",f4=2012-12-21T12:34:56Z|2012-12-21T12:34:56Z,f5="+toHex(foob)+"|"+toHex(barb)+",f6='"+toSpacedHex(foob)+"|"+toSpacedHex(barb)+"',f7=foo|bar,f8=1|2,f9=1|2,f10=1|2,f11=1|2,f12=true|true,f99=1|2)";
+//
+//             H2 h2 = s.serialize(ps, in, H2.class);
+//             
assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}",
 h2);
+//
+//             ObjectMap om = s.serialize(ps, in, ObjectMap.class);
+//             
assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}",
 om);
+//
+//             om = (ObjectMap)s.serialize(ps, in, Object.class);
+//             
assertObjectEquals("{f1:['foo','bar'],f2:[[102,111,111],[98,97,114]],f4:['2012-12-21T12:34:56Z','2012-12-21T12:34:56Z'],f5:[[102,111,111],[98,97,114]],f6:[[102,111,111],[98,97,114]],f7:['foo','bar'],f8:[1,2],f9:[1,2],f10:[1.0,2.0],f11:[1.0,2.0],f12:[true,true],f99:[1,2]}",
 om);
+//     }
+//
+       
//-----------------------------------------------------------------------------------------------------------------
+       // Utility methods
+       
//-----------------------------------------------------------------------------------------------------------------
+
+       private static HttpPartSchemaBuilder schema() {
+               return HttpPartSchema.create();
+       }
+//
+//     private static HttpPartSchemaBuilder schema(String type) {
+//             return HttpPartSchema.create(type);
+//     }
+//
+//     private static HttpPartSchemaBuilder schema(String type, String format) 
{
+//             return HttpPartSchema.create(type, format);
+//     }
+}
\ No newline at end of file
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 8c7fba9..7feb819 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
@@ -681,9 +681,8 @@ public class BeanSession extends Session {
                                        return (T)((Calendar)value).getTime();
                        }
 
-                       Transform t = type.getTransform(value.getClass());
-                       if (t != null)
-                               return (T) t.transform(value);
+                       if (type.hasTransformForObject(value))
+                               return type.transform(value);
 
                        if (type.isBean())
                                return 
newBeanMap(type.getInnerClass()).load(value.toString()).getBean();
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
index 0a4b1c6..d420d6f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ClassMeta.java
@@ -2081,7 +2081,7 @@ public final class ClassMeta<T> implements Type {
         * @return <jk>true</jk> if this class has a transform associated with 
it that allows it to be created from a Reader.
         */
        public boolean hasReaderTransform() {
-               return getTransform(Reader.class) != null;
+               return hasTransform(Reader.class);
        }
 
        /**
@@ -2099,7 +2099,7 @@ public final class ClassMeta<T> implements Type {
         * @return <jk>true</jk> if this class has a transform associated with 
it that allows it to be created from an InputStream.
         */
        public boolean hasInputStreamTransform() {
-               return getTransform(InputStream.class) != null;
+               return hasTransform(InputStream.class);
        }
 
        /**
@@ -2130,6 +2130,38 @@ public final class ClassMeta<T> implements Type {
        }
 
        /**
+        * Returns <jk>true</jk> if this class can be instantiated from the 
specified type.
+        *
+        * @param c The class type to convert from.
+        * @return <jk>true</jk> if this class can be instantiated from the 
specified type.
+        */
+       public boolean hasTransform(Class<?> c) {
+               return getTransform(c) != null;
+       }
+
+       /**
+        * Returns <jk>true</jk> if this class can be instantiated from the 
specified object.
+        *
+        * @param o The object to convert from.
+        * @return <jk>true</jk> if this class can be instantiated from the 
specified object.
+        */
+       public boolean hasTransformForObject(Object o) {
+               return getTransform(o.getClass()) != null;
+       }
+
+       /**
+        * Transforms the specified object into an instance of this class.
+        *
+        * @param o The object to transform.
+        * @return The transformed object.
+        */
+       @SuppressWarnings({"unchecked","rawtypes"})
+       public T transform(Object o) {
+               Transform t = getTransform(o.getClass());
+               return (T)(t == null ? null : t.transform(o));
+       }
+
+       /**
         * Returns the transform for this class for creating instances from 
other object types.
         *
         * @param c The transform-from class.
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 30c7876..e7d5b14 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
@@ -1010,7 +1010,7 @@ public class HttpPartSchema {
         * @throws SchemaValidationException if the specified parsed output 
does not validate against this schema.
         */
        @SuppressWarnings("rawtypes")
-       public Object validateOutput(Object o, BeanContext bc) throws 
SchemaValidationException {
+       public <T> T validateOutput(T o, BeanContext bc) throws 
SchemaValidationException {
                if (o == null) {
                        if (! isValidRequired(o))
                                throw new SchemaValidationException("Required 
value not provided.");
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
index 14c07c6..d482732 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/OpenApiPartParser.java
@@ -273,25 +273,25 @@ public class OpenApiPartParser extends UonPartParser {
                        if (t == STRING) {
                                if (type.isObject()) {
                                        if (f == BYTE)
-                                               return 
(T)StringUtils.base64Decode(in);
+                                               return (T)base64Decode(in);
                                        if (f == DATE || f == DATE_TIME)
-                                               return 
(T)StringUtils.parseIsoCalendar(in);
+                                               return (T)parseIsoCalendar(in);
                                        if (f == BINARY)
-                                               return 
(T)StringUtils.fromHex(in);
+                                               return (T)fromHex(in);
                                        if (f == BINARY_SPACED)
-                                               return 
(T)StringUtils.fromSpacedHex(in);
+                                               return (T)fromSpacedHex(in);
                                        if (f == HttpPartSchema.Format.UON)
                                                return super.parse(partType, 
schema, in, type);
                                        return (T)in;
                                }
                                if (f == BYTE)
-                                       return 
toType(StringUtils.base64Decode(in), type);
+                                       return toType(base64Decode(in), type);
                                if (f == DATE || f == DATE_TIME)
-                                       return 
toType(StringUtils.parseIsoCalendar(in), type);
+                                       return toType(parseIsoCalendar(in), 
type);
                                if (f == BINARY)
-                                       return toType(StringUtils.fromHex(in), 
type);
+                                       return toType(fromHex(in), type);
                                if (f == BINARY_SPACED)
-                                       return 
toType(StringUtils.fromSpacedHex(in), type);
+                                       return toType(fromSpacedHex(in), type);
                                if (f == HttpPartSchema.Format.UON)
                                        return super.parse(partType, schema, 
in, type);
                                return toType(in, type);
@@ -333,7 +333,7 @@ public class OpenApiPartParser extends UonPartParser {
                                } else {
                                        o = ss;
                                }
-                               if 
(type.getTransform(schema.getParsedType().getInnerClass()) != null)
+                               if 
(type.hasTransform(schema.getParsedType().getInnerClass()))
                                        return toType(toType(o, 
schema.getParsedType()), type);
                                return toType(o, type);
 
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 1eda116..6aac247 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
@@ -12,6 +12,14 @@
 // 
***************************************************************************************************************************
 package org.apache.juneau.httppart;
 
+import static org.apache.juneau.httppart.HttpPartSchema.CollectionFormat.*;
+import static org.apache.juneau.httppart.HttpPartSchema.Format.*;
+import static org.apache.juneau.httppart.HttpPartSchema.Type.*;
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
@@ -60,6 +68,12 @@ public class OpenApiPartSerializer extends UonPartSerializer 
{
        /** Reusable instance of {@link OpenApiPartSerializer}, all default 
settings. */
        public static final OpenApiPartSerializer DEFAULT = new 
OpenApiPartSerializer(PropertyStore.DEFAULT);
 
+       // Cache these for faster lookup
+       private static final BeanContext BC = BeanContext.DEFAULT;
+       private static final ClassMeta<byte[]> CM_ByteArray = 
BC.getClassMeta(byte[].class);
+       private static final ClassMeta<Calendar> CM_Calendar = 
BC.getClassMeta(Calendar.class);
+
+       private static final HttpPartSchema DEFAULT_SCHEMA = 
HttpPartSchema.DEFAULT;
 
        
//-------------------------------------------------------------------------------------------------------------------
        // Instance
@@ -104,168 +118,116 @@ public class OpenApiPartSerializer extends 
UonPartSerializer {
        // Entry point methods
        
//--------------------------------------------------------------------------------
 
+       /**
+        * Convenience method for serializing a part.
+        *
+        * @param schema
+        *      Schema information about the part.
+        *      <br>May be <jk>null</jk>.
+        *      <br>Not all part serializers use the schema information.
+        * @param value The value being serialized.
+        * @return The serialized value.
+        * @throws SerializeException If a problem occurred while trying to 
serialize the input.
+        * @throws SchemaValidationException If the input or resulting HTTP 
part object fails schema validation.
+        */
+       public String serialize(HttpPartSchema schema, Object value) throws 
SerializeException, SchemaValidationException {
+               return serialize(null, schema, value);
+       }
+
        @Override /* PartSerializer */
+       @SuppressWarnings("rawtypes")
        public String serialize(HttpPartType partType, HttpPartSchema schema, 
Object value) throws SerializeException, SchemaValidationException {
-               schema = ObjectUtils.firstNonNull(schema, this.schema, 
HttpPartSchema.DEFAULT);
-//             ClassMeta<?> type = getClassMetaForObject(value);
-//             String out;
-//
-//             switch (schema.getType()) {
-//                     case STRING: {
-//                             if (type.isObject()) {
-//                                     switch (schema.getFormat()) {
-//                                             case BYTE:
-//                                                     return 
(T)StringUtils.base64Decode(in);
-//                                             case DATE:
-//                                             case DATE_TIME:
-//                                                     return 
(T)StringUtils.parseIsoCalendar(in);
-//                                             case BINARY:
-//                                                     return 
(T)StringUtils.fromHex(in);
-//                                             case BINARY_SPACED:
-//                                                     return 
(T)StringUtils.fromSpacedHex(in);
-//                                             case UON:
-//                                                     return 
super.parse(partType, schema, in, type);
-//                                             default:
-//                                                     return (T)in;
-//                                     }
-//                             }
-//                             switch (schema.getFormat()) {
-//                                     case BYTE:
-//                                             return 
toType(StringUtils.base64Decode(in), type);
-//                                     case DATE:
-//                                     case DATE_TIME:
-//                                             return 
toType(StringUtils.parseIsoCalendar(in), type);
-//                                     case BINARY:
-//                                             return 
toType(StringUtils.fromHex(in), type);
-//                                     case BINARY_SPACED:
-//                                             return 
toType(StringUtils.fromSpacedHex(in), type);
-//                                     case UON:
-//                                             return super.parse(partType, 
schema, in, type);
-//                                     default:
-//                                             return toType(in, type);
-//                             }
-//                     }
-//                     case ARRAY: {
-//                             if (type.isObject())
-//                                     type = (ClassMeta<T>)CM_ObjectList;
-//
-//                             ClassMeta<?> eType = type.isObject() ? string() 
: type.getElementType();
-//                             if (eType == null)
-//                                     eType = 
schema.getParsedType().getElementType();
-//
-//                             String[] ss = new String[0];
-//                             switch (schema.getCollectionFormat()) {
-//                                     case MULTI:
-//                                             ss = new String[]{in};
-//                                             break;
-//                                     case CSV:
-//                                             ss = split(in, ',');
-//                                             break;
-//                                     case PIPES:
-//                                             ss = split(in, '|');
-//                                             break;
-//                                     case SSV:
-//                                             ss = splitQuoted(in);
-//                                             break;
-//                                     case TSV:
-//                                             ss = split(in, '\t');
-//                                             break;
-//                                     case UON:
-//                                             return super.parse(partType, 
null, in, type);
-//                                     case NONE:
-//                                             if (firstNonWhitespaceChar(in) 
== '@' && lastNonWhitespaceChar(in) == ')')
-//                                                     return 
super.parse(partType, null, in, type);
-//                                             ss = split(in, ',');
-//                             }
-//                             Object[] o = null;
-//                             if (schema.getItems() != null) {
-//                                     o = new Object[ss.length];
-//                                     for (int i = 0; i < ss.length; i++)
-//                                             o[i] = parse(partType, 
schema.getItems(), ss[i], eType);
-//                             } else {
-//                                     o = ss;
-//                             }
-//                             if 
(type.getTransform(schema.getParsedType().getInnerClass()) != null)
-//                                     return toType(toType(o, 
schema.getParsedType()), type);
-//                             return toType(o, type);
-//                     }
-//                     case BOOLEAN: {
-//                             if (type.isObject())
-//                                     type = (ClassMeta<T>)CM_Boolean;
-//                             if (type.isBoolean())
-//                                     return super.parse(partType, schema, 
in, type);
-//                             return toType(super.parse(partType, schema, in, 
CM_Boolean), type);
-//                     }
-//                     case INTEGER: {
-//                             if (type.isObject()) {
-//                                     switch (schema.getFormat()) {
-//                                             case INT64:
-//                                                     type = 
(ClassMeta<T>)CM_Long;
-//                                                     break;
-//                                             default:
-//                                                     type = 
(ClassMeta<T>)CM_Integer;
-//
-//                                     }
-//                             }
-//                             if (type.isNumber())
-//                                     return super.parse(partType, schema, 
in, type);
-//                             return toType(super.parse(partType, schema, in, 
CM_Integer), type);
-//                     }
-//                     case NUMBER: {
-//                             if (type.isObject()) {
-//                                     switch (schema.getFormat()) {
-//                                             case DOUBLE:
-//                                                     type = 
(ClassMeta<T>)CM_Double;
-//                                                     break;
-//                                             default:
-//                                                     type = 
(ClassMeta<T>)CM_Float;
-//                                     }
-//                             }
-//                             if (type.isNumber())
-//                                     return super.parse(partType, schema, 
in, type);
-//                             return toType(super.parse(partType, schema, in, 
CM_Integer), type);
-//                     }
-//                     case OBJECT: {
-//                             if (type.isObject())
-//                                     type = (ClassMeta<T>)CM_ObjectMap;
-//                             if (schema.hasProperties() && 
type.isMapOrBean()) {
-//                                     try {
-//                                             if (type.isBean()) {
-//                                                     BeanMap<T> m = 
BC.createBeanSession().newBeanMap(type.getInnerClass());
-//                                                     for 
(Map.Entry<String,Object> e : parse(partType, DEFAULT_SCHEMA, in, 
CM_ObjectMap).entrySet()) {
-//                                                             String key = 
e.getKey();
-//                                                             
BeanPropertyMeta bpm = m.getPropertyMeta(key);
-//                                                             m.put(key, 
parse(partType, schema.getProperty(key), asString(e.getValue()), bpm == null ? 
object() : bpm.getClassMeta()));
-//                                                     }
-//                                                     return m.getBean();
-//                                             }
-//                                             Map<String,Object> m = 
(Map<String,Object>)type.newInstance();
-//                                             for (Map.Entry<String,Object> e 
: parse(partType, DEFAULT_SCHEMA, in, CM_ObjectMap).entrySet()) {
-//                                                     String key = e.getKey();
-//                                                     m.put(key, 
parse(partType, schema.getProperty(key), asString(e.getValue()), object()));
-//                                             }
-//                                             return (T)m;
-//                                     } catch (Exception e1) {
-//                                             throw new ParseException(e1, 
"Could not instantiate type ''{0}''.", type);
-//                                     }
-//                             }
-//                             return super.parse(partType, schema, in, type);
-//                     }
-//                     case FILE: {
-//                             throw new ParseException("File part not 
supported.");
-//                     }
-//                     case NONE: {
-//                             // This should never be returned by 
HttpPartSchema.getType(ClassMeta).
-//                             throw new ParseException("Invalid type.");
-//                     }
-//             }
-//     }
-
-
-
-
-               String out = super.serialize(partType, schema, value);
+
+               schema = ObjectUtils.firstNonNull(schema, this.schema, 
DEFAULT_SCHEMA);
+               ClassMeta<?> type = getClassMetaForObject(value);
+               if (type == null)
+                       type = object();
+               HttpPartSchema.Type t = schema.getType(type);
+               HttpPartSchema.Format f = schema.getFormat();
+
+               String out = null;
+
+               schema.validateOutput(value, this);
+
+               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();
+                       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 {
+                               l.add(serialize(partType, items, value));
+                       }
+
+                       HttpPartSchema.CollectionFormat cf = 
schema.getCollectionFormat();
+
+                       if (cf == MULTI || cf == CSV)
+                               out = join(l, ',');
+                       else if (cf == PIPES)
+                               out = join(l, '|');
+                       else if (cf == SSV)
+                               out = join(l, ' ');
+                       else if (cf == TSV)
+                               out = join(l, '\t');
+                       else
+                               out = super.serialize(partType, null, l);
+
+               } else if (t == BOOLEAN || t == INTEGER || t == NUMBER) {
+                       out = super.serialize(partType, null, value);
+
+               } 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 {
+                                       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 {
+                               out = super.serialize(partType, schema, value);
+                       }
+
+               } 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.");
+               }
+
                schema.validateInput(out);
                return out;
        }
+
+       private <T> T toType(Object in, ClassMeta<T> type) throws 
SerializeException {
+               try {
+                       return createBeanSession().convertToType(in, type);
+               } catch (InvalidDataConversionException e) {
+                       throw new SerializeException(e.getMessage());
+               }
+       }
 }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index 0c157c3..452fccf 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1227,6 +1227,26 @@ public final class StringUtils {
        }
 
        /**
+        * Converts the specified object to an ISO8601 date string.
+        *
+        * @param c The object to convert.
+        * @return The converted object.
+        */
+       public static String toIsoDate(Calendar c) {
+               return DatatypeConverter.printDate(c);
+       }
+
+       /**
+        * Converts the specified object to an ISO8601 date-time string.
+        *
+        * @param c The object to convert.
+        * @return The converted object.
+        */
+       public static String toIsoDateTime(Calendar c) {
+               return DatatypeConverter.printDateTime(c);
+       }
+
+       /**
         * Simple utility for replacing variables of the form <js>"{key}"</js> 
with values in the specified map.
         *
         * <p>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
index 341a600..a9f9c7c 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestCallHandler.java
@@ -287,6 +287,13 @@ public class BasicRestCallHandler implements 
RestCallHandler {
         */
        @Override /* RestCallHandler */
        public synchronized void handleError(HttpServletRequest req, 
HttpServletResponse res, RestException e) throws IOException {
+               if (context.isDebug()) {
+                       String qs = req.getQueryString();
+                       int c = e.getOccurrence();
+                       String msg = '[' + Integer.toHexString(e.hashCode()) + 
'.' + e.getStatus() + '.' + c + "] HTTP " + req.getMethod() + " " + 
e.getStatus() + " " + req.getRequestURI() + (qs == null ? "" : "?" + qs);
+                       System.err.println(msg);
+                       e.printStackTrace(System.err);
+               }
                e.setOccurrence(context == null ? 0 : 
context.getStackTraceOccurrence(e));
                logger.onError(req, res, e);
                renderError(req, res, e);
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
index 1ceebd1..dd36625 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContext.java
@@ -811,6 +811,34 @@ public final class RestContext extends BeanContext {
        public static final String REST_converters = PREFIX + "converters.lo";
 
        /**
+        * Configuration property:  Debug mode.
+        *
+        * <h5 class='section'>Property:</h5>
+        * <ul>
+        *      <li><b>Name:</b>  <js>"RestContext.debug.b"</js>
+        *      <li><b>Data type:</b>  <code>Boolean</code>
+        *      <li><b>Default:</b>  <jk>false</jk>
+        *      <li><b>Session-overridable:</b>  <jk>false</jk>
+        *      <li><b>Annotations:</b>
+        *              <ul>
+        *                      <li class='ja'>{@link RestResource#debug()}
+        *              </ul>
+        *      <li><b>Methods:</b>
+        *              <ul>
+        *                      <li class='jm'>{@link 
RestContextBuilder#debug(boolean)}
+        *              </ul>
+        * </ul>
+        *
+        * <h5 class='section'>Description:</h5>
+        * <p>
+        * Enables the following:
+        * <ul>
+        *      <li>A message and stack trace is printed to STDERR when {@link 
BasicRestCallHandler#handleError(HttpServletRequest, HttpServletResponse, 
RestException)} is called.
+        * </ul>
+        */
+       public static final String REST_debug = PREFIX + "debug.b";
+
+       /**
         * Configuration property:  Default character encoding.
         *
         * <h5 class='section'>Property:</h5>
@@ -2749,7 +2777,8 @@ public final class RestContext extends BeanContext {
                allowBodyParam,
                renderResponseStackTraces,
                useStackTraceHashes,
-               useClasspathResourceCaching;
+               useClasspathResourceCaching,
+               debug;
        private final String
                defaultCharset,
                clientVersionHeader,
@@ -2874,6 +2903,7 @@ public final class RestContext extends BeanContext {
                        allowedMethodParams = Collections.unmodifiableSet(new 
LinkedHashSet<>(Arrays.asList(StringUtils.split(getStringProperty(REST_allowedMethodParams,
 "HEAD,OPTIONS")))));
                        renderResponseStackTraces = 
getBooleanProperty(REST_renderResponseStackTraces, false);
                        useStackTraceHashes = 
getBooleanProperty(REST_useStackTraceHashes, true);
+                       debug = getBooleanProperty(REST_debug, false);
                        defaultCharset = getStringProperty(REST_defaultCharset, 
"utf-8");
                        maxInput = getLongProperty(REST_maxInput, 100_000_000l);
                        clientVersionHeader = 
getStringProperty(REST_clientVersionHeader, "X-Client-Version");
@@ -3900,6 +3930,20 @@ public final class RestContext extends BeanContext {
        }
 
        /**
+        * Returns <jk>true</jk> if debug mode is enabled on this resource.
+        *
+        * <h5 class='section'>See Also:</h5>
+        * <ul>
+        *      <li class='jf'>{@link RestContext#REST_debug}
+        * </ul>
+        *
+        * @return <jk>true</jk> if setting is enabled.
+        */
+       public boolean isDebug() {
+               return debug;
+       }
+
+       /**
         * Returns the default charset to use on requests and responses when 
not specified on the request.
         *
         * <h5 class='section'>See Also:</h5>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
index e7c5cbc..a7c9d6b 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestContextBuilder.java
@@ -223,6 +223,8 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
                                        
defaultCharset(vr.resolve(r.defaultCharset()));
                                if (! r.maxInput().isEmpty())
                                        maxInput(vr.resolve(r.maxInput()));
+                               if (! r.debug().isEmpty())
+                                       
debug(Boolean.valueOf(vr.resolve(r.debug())));
                                mimeTypes(resolveVars(vr, r.mimeTypes()));
 
                                HtmlDoc hd = r.htmldoc();
@@ -773,6 +775,24 @@ public class RestContextBuilder extends BeanContextBuilder 
implements ServletCon
        }
 
        /**
+        * Configuration property:  Debug mode.
+        *
+        * <h5 class='section'>See Also:</h5>
+        * <ul>
+        *      <li class='jf'>{@link RestContext#REST_debug}
+        *      <li class='jf'>{@link BeanContext#BEAN_debug}
+        * </ul>
+        *
+        * @param value The new value for this setting.
+        * @return This object (for method chaining).
+        */
+       @Override
+       public RestContextBuilder debug(boolean value) {
+               super.debug(value);
+               return set(REST_debug, value);
+       }
+
+       /**
         * Configuration property:  Default character encoding.
         *
         * <p>
diff --git 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index 9337288..adec8b1 100644
--- 
a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ 
b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -17,6 +17,8 @@ import static java.lang.annotation.RetentionPolicy.*;
 
 import java.lang.annotation.*;
 
+import javax.servlet.http.*;
+
 import org.apache.juneau.*;
 import org.apache.juneau.config.*;
 import org.apache.juneau.encoders.*;
@@ -943,4 +945,27 @@ public @interface RestResource {
         * </ul>
         */
        String useStackTraceHashes() default "";
+
+       /**
+        * Enable debug mode.
+        *
+        * <p>
+        * Enables the following:
+        * <ul>
+        *      <li>A message and stack trace is printed to STDERR when {@link 
BasicRestCallHandler#handleError(HttpServletRequest, HttpServletResponse, 
RestException)} is called.
+        * </ul>
+        *
+        * <h5 class='section'>Notes:</h5>
+        * <ul class='spaced-list'>
+        *      <li>
+        *              Supports <a class="doclink" 
href="../../../../../overview-summary.html#DefaultRestSvlVariables">initialization-time
 variables</a>
+        *              (e.g. <js>"$L{my.localized.variable}"</js>).
+        * </ul>
+        *
+        * <h5 class='section'>See Also:</h5>
+        * <ul>
+        *      <li class='jf'>{@link RestContext#REST_debug}
+        * </ul>
+        */
+       String debug() default "";
 }

Reply via email to