You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2018/04/03 19:42:22 UTC

[juneau] branch master updated: Swagger UI enhancements.

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 078799b  Swagger UI enhancements.
078799b is described below

commit 078799b1c03b45e6eebb85d0282284315e8981a6
Author: JamesBognar <ja...@apache.org>
AuthorDate: Tue Apr 3 15:42:20 2018 -0400

    Swagger UI enhancements.
---
 .../apache/juneau/dto/swagger/HeaderInfoTest.java  |   2 +-
 .../org/apache/juneau/dto/swagger/ItemsTest.java   |   2 +-
 .../apache/juneau/dto/swagger/SchemaInfoTest.java  |  84 +++-------
 .../org/apache/juneau/dto/swagger/SwaggerTest.java |  25 +--
 .../juneau/json/JsonSchemaSerializerTest.java      | 147 ++++++++---------
 .../org/apache/juneau/dto/swagger/Contact.java     |  27 +++
 .../juneau/dto/swagger/ExternalDocumentation.java  |  26 +++
 .../org/apache/juneau/dto/swagger/HeaderInfo.java  | 114 ++++++++++++-
 .../java/org/apache/juneau/dto/swagger/Info.java   |  30 ++++
 .../java/org/apache/juneau/dto/swagger/Items.java  | 116 ++++++++++++-
 .../org/apache/juneau/dto/swagger/License.java     |  26 +++
 .../org/apache/juneau/dto/swagger/Operation.java   |  74 +++++++++
 .../apache/juneau/dto/swagger/ParameterInfo.java   |  70 ++++++++
 .../apache/juneau/dto/swagger/ResponseInfo.java    |  55 +++++++
 .../org/apache/juneau/dto/swagger/SchemaInfo.java  | 170 +++++++++++++------
 .../apache/juneau/dto/swagger/SecurityScheme.java  |  36 ++++
 .../org/apache/juneau/dto/swagger/Swagger.java     | 120 +++++++++++++-
 .../apache/juneau/dto/swagger/SwaggerElement.java  |   7 +
 .../java/org/apache/juneau/dto/swagger/Tag.java    |  27 +++
 .../java/org/apache/juneau/dto/swagger/Xml.java    |  29 ++++
 .../apache/juneau/dto/swagger/ui/SwaggerUI.java    |  71 ++------
 .../src/main/java/org/apache/juneau/BeanMap.java   |   6 +-
 .../java/org/apache/juneau/BeanPropertyMeta.java   |   4 +-
 .../main/java/org/apache/juneau/BeanSession.java   |  12 +-
 .../src/main/java/org/apache/juneau/ClassMeta.java |  19 +++
 .../src/main/java/org/apache/juneau/ObjectMap.java |   2 +-
 .../src/main/java/org/apache/juneau/Session.java   |  12 +-
 .../org/apache/juneau/httppart/HttpPartType.java   |   2 +-
 .../juneau/jsonschema/JsonSchemaSerializer.java    |  57 +++++--
 .../jsonschema/JsonSchemaSerializerBuilder.java    |  12 +-
 .../jsonschema/JsonSchemaSerializerSession.java    |  19 ++-
 .../org/apache/juneau/jsonschema/TypeCategory.java |  22 ++-
 .../src/main/java/org/apache/juneau/svl/Var.java   |   6 +-
 .../org/apache/juneau/svl/VarResolverContext.java  |   2 +-
 .../apache/juneau/svl/VarResolverException.java}   |  65 ++++----
 .../org/apache/juneau/svl/VarResolverSession.java  |  25 +--
 .../examples/rest/petstore/PetStoreResource.json   |  91 ----------
 .../rest/client/SerializedNameValuePair.java       |   2 +-
 .../apache/juneau/rest/BasicRestInfoProvider.java  | 183 ++++++++++-----------
 .../org/apache/juneau/rest/BasicRestServlet.java   |   8 +
 .../org/apache/juneau/rest/RequestFormData.java    |   2 +-
 .../java/org/apache/juneau/rest/RestContext.java   |  13 ++
 .../org/apache/juneau/rest/RestJavaMethod.java     |  36 ++++
 43 files changed, 1316 insertions(+), 542 deletions(-)

diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/HeaderInfoTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/HeaderInfoTest.java
index 1f994bf..d8b86ab 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/HeaderInfoTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/HeaderInfoTest.java
@@ -589,7 +589,7 @@ public class HeaderInfoTest {
 		assertType(String.class, t.get("pattern", Object.class));
 		assertType(String.class, t.get("type", Object.class));
 		assertType(Boolean.class, t.get("uniqueItems", Object.class));
-		assertType(StringBuilder.class, t.get("$ref", Object.class));
+		assertType(String.class, t.get("$ref", Object.class));
 		
 		JsonSerializer.DEFAULT_LAX.println(t);
 	
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/ItemsTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/ItemsTest.java
index ff9176a..63074a9 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/ItemsTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/ItemsTest.java
@@ -566,7 +566,7 @@ public class ItemsTest {
 		assertType(String.class, t.get("pattern", Object.class));
 		assertType(String.class, t.get("type", Object.class));
 		assertType(Boolean.class, t.get("uniqueItems", Object.class));
-		assertType(StringBuilder.class, t.get("$ref", Object.class));
+		assertType(String.class, t.get("$ref", Object.class));
 		
 		JsonSerializer.DEFAULT_LAX.println(t);
 	
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SchemaInfoTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SchemaInfoTest.java
index 9e0120c..23b1f78 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SchemaInfoTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SchemaInfoTest.java
@@ -616,11 +616,11 @@ public class SchemaInfoTest {
 	public void testSetProperties() {
 		SchemaInfo t = new SchemaInfo();
 		
-		t.setProperties(new AMap<String,Map<String,Object>>().append("foo",new AMap<String,Object>().append("bar",new AList<Number>().append(123))));
-		assertObjectEquals("{foo:{bar:[123]}}", t.getProperties());
+		t.setProperties(new AMap<String,SchemaInfo>().append("foo",new SchemaInfo().type("foo")));
+		assertObjectEquals("{foo:{type:'foo'}}", t.getProperties());
 		assertType(Map.class, t.getProperties());
 		
-		t.setProperties(new AMap<String,Map<String,Object>>());
+		t.setProperties(new AMap<String,SchemaInfo>());
 		assertObjectEquals("{}", t.getProperties());
 		assertType(Map.class, t.getProperties());
 
@@ -635,16 +635,16 @@ public class SchemaInfoTest {
 	public void testAddProperties() {
 		SchemaInfo t = new SchemaInfo();
 		
-		t.addProperties(new AMap<String,Map<String,Object>>().append("foo",new AMap<String,Object>().append("bar",new AList<Number>().append(123))));
-		assertObjectEquals("{foo:{bar:[123]}}", t.getProperties());
+		t.addProperties(new AMap<String,SchemaInfo>().append("foo", new SchemaInfo().type("foo")));
+		assertObjectEquals("{foo:{type:'foo'}}", t.getProperties());
 		assertType(Map.class, t.getProperties());
 		
-		t.addProperties(new AMap<String,Map<String,Object>>());
-		assertObjectEquals("{foo:{bar:[123]}}", t.getProperties());
+		t.addProperties(new AMap<String,SchemaInfo>());
+		assertObjectEquals("{foo:{type:'foo'}}", t.getProperties());
 		assertType(Map.class, t.getProperties());
 
 		t.addProperties(null);
-		assertObjectEquals("{foo:{bar:[123]}}", t.getProperties());
+		assertObjectEquals("{foo:{type:'foo'}}", t.getProperties());
 		assertType(Map.class, t.getProperties());
 	}
 
@@ -655,13 +655,16 @@ public class SchemaInfoTest {
 	public void testProperties() {
 		SchemaInfo t = new SchemaInfo();
 		
-		t.properties(new AMap<String,Map<String,Object>>().append("a", new AMap<String,Object>().append("a1", 1)));
-		t.properties(new AMap<String,String>().append("b", "{b1:2}"));
-		t.properties("{c:{c1:'c2'}}");
+		t.properties(new AMap<String,Map<String,Object>>().append("a", new AMap<String,Object>().append("type", "foo")));
+		t.properties(new AMap<String,String>().append("b", "{type:'bar'}"));
+		t.properties("{c:{type:'baz'}}");
 		t.properties("{}");
 		t.properties((Object[])null);
 		
-		assertObjectEquals("{a:{a1:1},b:{b1:2},c:{c1:'c2'}}", t.getProperties());
+		assertObjectEquals("{a:{type:'foo'},b:{type:'bar'},c:{type:'baz'}}", t.getProperties());
+		assertType(SchemaInfo.class, t.getProperties().get("a"));
+		assertType(SchemaInfo.class, t.getProperties().get("b"));
+		assertType(SchemaInfo.class, t.getProperties().get("c"));
 	}
 
 	/**
@@ -671,66 +674,29 @@ public class SchemaInfoTest {
 	public void testSetAdditionalProperties() {
 		SchemaInfo t = new SchemaInfo();
 		
-		t.setAdditionalProperties(new AMap<String,Object>().append("foo",new AList<String>().append("bar")));
-		assertObjectEquals("{foo:['bar']}", t.getAdditionalProperties());
-		assertType(Map.class, t.getAdditionalProperties());
+		t.setAdditionalProperties(new SchemaInfo().type("foo"));
+		assertObjectEquals("{type:'foo'}", t.getAdditionalProperties());
+		assertType(SchemaInfo.class, t.getAdditionalProperties());
 		
-		t.setAdditionalProperties(new AMap<String,Object>());
+		t.setAdditionalProperties(new SchemaInfo());
 		assertObjectEquals("{}", t.getAdditionalProperties());
-		assertType(Map.class, t.getAdditionalProperties());
+		assertType(SchemaInfo.class, t.getAdditionalProperties());
 
 		t.setAdditionalProperties(null);
 		assertNull(t.getAdditionalProperties());
 	}
 
 	/**
-	 * Test method for {@link SchemaInfo#addAdditionalProperties(java.util.Map)}.
-	 */
-	@Test
-	public void testAddAdditionalProperties() {
-		SchemaInfo t = new SchemaInfo();
-		
-		t.addAdditionalProperties(new AMap<String,Object>().append("foo",new AList<String>().append("bar")));
-		assertObjectEquals("{foo:['bar']}", t.getAdditionalProperties());
-		assertType(Map.class, t.getAdditionalProperties());
-		
-		t.addAdditionalProperties(new AMap<String,Object>());
-		assertObjectEquals("{foo:['bar']}", t.getAdditionalProperties());
-		assertType(Map.class, t.getAdditionalProperties());
-
-		t.addAdditionalProperties(null);
-		assertObjectEquals("{foo:['bar']}", t.getAdditionalProperties());
-		assertType(Map.class, t.getAdditionalProperties());
-	}
-
-	/**
-	 * Test method for {@link SchemaInfo#additionalProperty(java.lang.String, java.lang.Object)}.
-	 */
-	@Test
-	public void testAdditionalProperty() {
-		SchemaInfo t = new SchemaInfo();
-		
-		t.additionalProperty("a", "a1");
-		t.additionalProperty(null, "b1");
-		t.additionalProperty("c", null);
-		
-		assertObjectEquals("{a:'a1',null:'b1',c:null}", t.getAdditionalProperties());
-	}
-
-	/**
 	 * Test method for {@link SchemaInfo#additionalProperties(java.lang.Object[])}.
 	 */
 	@Test
 	public void testAdditionalProperties() {
 		SchemaInfo t = new SchemaInfo();
 
-		t.additionalProperties(new AMap<String,Object>().append("a",new AList<String>().append("a1")));
-		t.additionalProperties(new AMap<String,Object>().append("b","b1"));
-		t.additionalProperties("{c:['c1']}");
-		t.additionalProperties("{}");
-		t.additionalProperties((Object)null);
+		t.additionalProperties(new AMap<String,Object>().append("type","foo"));
 		
-		assertObjectEquals("{a:['a1'],b:'b1',c:['c1']}", t.getAdditionalProperties());
+		assertObjectEquals("{type:'foo'}", t.getAdditionalProperties());
+		assertType(SchemaInfo.class, t.getAdditionalProperties());
 	}
 
 	/**
@@ -969,7 +935,7 @@ public class SchemaInfoTest {
 	
 		assertType(StringBuilder.class, t.get("default", Object.class));
 		assertType(List.class, t.get("enum", Object.class));
-		assertType(Map.class, t.get("additionalProperties", Object.class));
+		assertType(SchemaInfo.class, t.get("additionalProperties", Object.class));
 		assertType(List.class, t.get("allOf", Object.class));
 		assertType(String.class, t.get("description", Object.class));
 		assertType(String.class, t.get("discriminator", Object.class));
@@ -996,7 +962,7 @@ public class SchemaInfoTest {
 		assertType(String.class, t.get("type", Object.class));
 		assertType(Boolean.class, t.get("uniqueItems", Object.class));
 		assertType(Xml.class, t.get("xml", Object.class));
-		assertType(StringBuilder.class, t.get("$ref", Object.class));
+		assertType(String.class, t.get("$ref", Object.class));
 	
 		t.set("null", null).set(null, "null");
 		assertNull(t.get("null", Object.class));
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SwaggerTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SwaggerTest.java
index 6d5afe4..06fa9ab 100644
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SwaggerTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/dto/swagger/SwaggerTest.java
@@ -18,6 +18,7 @@ import static org.junit.Assert.*;
 
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.utils.*;
@@ -360,11 +361,11 @@ public class SwaggerTest {
 	public void testSetDefinitions() {
 		Swagger t = new Swagger();
 		
-		t.setDefinitions(new AMap<String,SchemaInfo>().append("foo",schemaInfo().title("bar")));
-		assertObjectEquals("{foo:{title:'bar'}}", t.getDefinitions());
+		t.setDefinitions(new AMap<String,ObjectMap>().append("foo",new ObjectMap().append("type","bar")));
+		assertObjectEquals("{foo:{type:'bar'}}", t.getDefinitions());
 		assertType(Map.class, t.getDefinitions());
 		
-		t.setDefinitions(new AMap<String,SchemaInfo>());
+		t.setDefinitions(new AMap<String,ObjectMap>());
 		assertObjectEquals("{}", t.getDefinitions());
 		assertType(Map.class, t.getDefinitions());
 
@@ -379,16 +380,16 @@ public class SwaggerTest {
 	public void testAddDefinitions() {
 		Swagger t = new Swagger();
 		
-		t.addDefinitions(new AMap<String,SchemaInfo>().append("foo",schemaInfo().title("bar")));
-		assertObjectEquals("{foo:{title:'bar'}}", t.getDefinitions());
+		t.addDefinitions(new AMap<String,ObjectMap>().append("foo", new ObjectMap().append("type", "bar")));
+		assertObjectEquals("{foo:{type:'bar'}}", t.getDefinitions());
 		assertType(Map.class, t.getDefinitions());
 		
-		t.addDefinitions(new AMap<String,SchemaInfo>());
-		assertObjectEquals("{foo:{title:'bar'}}", t.getDefinitions());
+		t.addDefinitions(new AMap<String,ObjectMap>());
+		assertObjectEquals("{foo:{type:'bar'}}", t.getDefinitions());
 		assertType(Map.class, t.getDefinitions());
 
 		t.addDefinitions(null);
-		assertObjectEquals("{foo:{title:'bar'}}", t.getDefinitions());
+		assertObjectEquals("{foo:{type:'bar'}}", t.getDefinitions());
 		assertType(Map.class, t.getDefinitions());
 	}
 
@@ -399,11 +400,11 @@ public class SwaggerTest {
 	public void testDefinition() {
 		Swagger t = new Swagger();
 
-		t.definition("a", schemaInfo().title("a1"));
+		t.definition("a", new ObjectMap().append("type","a1"));
 		t.definition("b", null);
-		t.definition(null, schemaInfo().title("c1"));
+		t.definition(null, new ObjectMap().append("type", "c1"));
 		
-		assertObjectEquals("{a:{title:'a1'},b:null,null:{title:'c1'}}", t.getDefinitions());
+		assertObjectEquals("{a:{type:'a1'},b:null,null:{type:'c1'}}", t.getDefinitions());
 	}
 
 	/**
@@ -874,7 +875,7 @@ public class SwaggerTest {
 		assertType(List.class, t.get("consumes", Object.class));
 		assertType(MediaType.class, t.get("consumes", List.class).get(0));
 		assertType(Map.class, t.get("definitions", Object.class));
-		assertType(SchemaInfo.class, t.get("definitions", Map.class).values().iterator().next());
+		assertType(ObjectMap.class, t.get("definitions", Map.class).values().iterator().next());
 		assertType(ExternalDocumentation.class, t.get("externalDocs", Object.class));
 		assertType(String.class, t.get("host", Object.class));
 		assertType(Info.class, t.get("info", Object.class));
diff --git a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaSerializerTest.java b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaSerializerTest.java
index e0d45a3..639e224 100755
--- a/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaSerializerTest.java
+++ b/juneau-core/juneau-core-test/src/test/java/org/apache/juneau/json/JsonSchemaSerializerTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.json;
 
 import static org.apache.juneau.TestUtils.*;
 import static org.junit.Assert.*;
-import static org.apache.juneau.jsonschema.TypeCategory.*;
 
 import java.util.*;
 
@@ -413,13 +412,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_BEAN_noBeanExample() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}}}", s.getSchema(SimpleBean.class));
 	}
 
 	@Test
 	public void addExample_BEAN_exampleMethod() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(SimpleBeanWithExampleMethod.class));
 	}
 
@@ -427,13 +426,13 @@ public class JsonSchemaSerializerTest {
 	public void addExample_BEAN_exampleMethod_wDefault() throws Exception {
 		SimpleBeanWithExampleMethod b = new SimpleBeanWithExampleMethod();
 		b.f1 = "baz";
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).example(SimpleBeanWithExampleMethod.class, b).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").example(SimpleBeanWithExampleMethod.class, b).build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},example:{f1:'baz'}}", s.getSchema(SimpleBeanWithExampleMethod.class));
 	}
 
 	@Test
 	public void addExample_BEAN_exampleMethod_array2d() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(SimpleBeanWithExampleMethod[][].class));
 	}
 
@@ -449,13 +448,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_BEAN_exampleField() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(SimpleBeanWithExampleField.class));
 	}
 
 	@Test
 	public void addExample_BEAN_exampleField_array2d() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(SimpleBeanWithExampleField[][].class));
 	}
 
@@ -473,13 +472,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_BEAN_exampleBeanAnnotation() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(SimpleBeanWithExampleAnnotation.class));
 	}
 
 	@Test
 	public void addExample_BEAN_exampleBeanAnnotation_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(SimpleBeanWithExampleAnnotation[][].class));
 	}
 
@@ -490,7 +489,7 @@ public class JsonSchemaSerializerTest {
 	public void addExample_BEAN_exampleBeanProperty() throws Exception {
 		SimpleBean b = new SimpleBean();
 		b.f1 = "foobar";
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).example(SimpleBean.class, b).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").example(SimpleBean.class, b).build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}", s.getSchema(SimpleBean.class));
 	}
 
@@ -498,7 +497,7 @@ public class JsonSchemaSerializerTest {
 	public void addExample_BEAN_exampleBeanProperty_2darray() throws Exception {
 		SimpleBean b = new SimpleBean();
 		b.f1 = "foobar";
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BEAN).example(SimpleBean.class, b).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("bean").example(SimpleBean.class, b).build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{f1:'foobar'}}}}", s.getSchema(SimpleBean[][].class));
 	}
 	
@@ -508,13 +507,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_MAP_noExample() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanMap.class));
 	}
 
 	@Test
 	public void addExample_MAP_exampleMethod() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(BeanMapWithExampleMethod.class));
 	}
 	
@@ -522,7 +521,7 @@ public class JsonSchemaSerializerTest {
 	public void addExample_MAP_exampleMethod_wDefault() throws Exception {
 		BeanMapWithExampleMethod b = new BeanMapWithExampleMethod();
 		b.put(456, SimpleBeanWithExampleMethod.example());
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).example(BeanMapWithExampleMethod.class, b).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").example(BeanMapWithExampleMethod.class, b).build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'456':{f1:'foobar'}}}", s.getSchema(BeanMapWithExampleMethod.class));
 	}
 
@@ -539,13 +538,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_MAP_exampleField() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(BeanMapWithExampleField.class));
 	}
 
 	@Test
 	public void addExample_MAP_exampleField_array2d() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}}}", s.getSchema(BeanMapWithExampleField[][].class));
 	}
 
@@ -564,13 +563,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_MAP_exampleBeanAnnotation() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}", s.getSchema(BeanMapWithExampleAnnotation.class));
 	}
 
 	@Test
 	public void addExample_MAP_exampleBeanAnnotation_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'baz'}}}}}", s.getSchema(BeanMapWithExampleAnnotation[][].class));
 	}
 
@@ -580,13 +579,13 @@ public class JsonSchemaSerializerTest {
 	
 	@Test
 	public void addExample_MAP_exampleBeanProperty() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).example(BeanMap.class, BeanMapWithExampleMethod.example()).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").example(BeanMap.class, BeanMapWithExampleMethod.example()).build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(BeanMap.class));
 	}
 
 	@Test
 	public void addExample_MAP_exampleBeanProperty_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(MAP).example(BeanMap.class, BeanMapWithExampleMethod.example()).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("map").example(BeanMap.class, BeanMapWithExampleMethod.example()).build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}}}", s.getSchema(BeanMap[][].class));
 	}
 	
@@ -596,13 +595,13 @@ public class JsonSchemaSerializerTest {
 	
 	@Test
 	public void addExample_COLLECTION_noExample() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}", s.getSchema(BeanList.class));
 	}
 
 	@Test
 	public void addExample_COLLECTION_exampleMethod() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(BeanListWithExampleMethod.class));
 	}
 
@@ -612,7 +611,7 @@ public class JsonSchemaSerializerTest {
 		SimpleBean sb = new SimpleBean();
 		sb.f1 = "baz";
 		b.add(sb);
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).example(BeanListWithExampleMethod.class, b).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").example(BeanListWithExampleMethod.class, b).build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(BeanListWithExampleMethod.class));
 	}
 
@@ -629,13 +628,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_COLLECTION_exampleField() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(BeanListWithExampleField.class));
 	}
 
 	@Test
 	public void addExample_ARRAY_exampleField_array2d() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ARRAY).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("array").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(BeanListWithExampleField[][].class));
 	}
 
@@ -654,13 +653,13 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_COLLECTION_exampleBeanAnnotation() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'baz'}]}", s.getSchema(BeanListWithExampleAnnotation.class));
 	}
 
 	@Test
 	public void addExample_ARRAY_exampleBeanAnnotation_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ARRAY).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("array").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'baz'}]]]}", s.getSchema(BeanListWithExampleAnnotation[][].class));
 	}
 
@@ -670,13 +669,13 @@ public class JsonSchemaSerializerTest {
 	
 	@Test
 	public void addExample_COLLECTION_exampleBeanProperty() throws Exception {
-		JsonSchemaSerializerSession s =JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(COLLECTION).example(BeanList.class, BeanListWithExampleMethod.example()).build().createSession();
+		JsonSchemaSerializerSession s =JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("collection").example(BeanList.class, BeanListWithExampleMethod.example()).build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(BeanList.class));
 	}
 
 	@Test
 	public void addExample_ARRAY_exampleBeanProperty_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ARRAY).example(BeanList.class, BeanListWithExampleMethod.example()).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("array").example(BeanList.class, BeanListWithExampleMethod.example()).build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},example:[[[{f1:'foobar'}]]]}", s.getSchema(BeanList[][].class));
 	}
 
@@ -685,14 +684,14 @@ public class JsonSchemaSerializerTest {
 	//====================================================================================================
 	@Test
 	public void addExample_BOOLEAN() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BOOLEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("boolean").build().createSession();
 		assertObjectEquals("{type:'boolean',example:true}", s.getSchema(boolean.class));
 		assertObjectEquals("{type:'boolean',example:true}", s.getSchema(Boolean.class));
 	}
 	
 	@Test
 	public void addExample_BOOLEAN_wDefault() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BOOLEAN)
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("boolean")
 			.example(boolean.class, false)
 			.example(Boolean.class, false)
 			.build().createSession();
@@ -702,7 +701,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_BOOLEAN_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(BOOLEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("boolean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'boolean',example:true}}}", s.getSchema(boolean[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'boolean',example:true}}}", s.getSchema(Boolean[][].class));
 	}
@@ -712,7 +711,7 @@ public class JsonSchemaSerializerTest {
 	//====================================================================================================
 	@Test
 	public void addExample_NUMBER() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(NUMBER).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("number").build().createSession();
 		assertObjectEquals("{type:'integer',format:'int16',example:1}", s.getSchema(short.class));
 		assertObjectEquals("{type:'integer',format:'int16',example:1}", s.getSchema(Short.class));
 		assertObjectEquals("{type:'integer',format:'int32',example:1}", s.getSchema(int.class));
@@ -727,7 +726,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_NUMBER_wDefault() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(NUMBER)
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("number")
 			.example(short.class, (short)2)
 			.example(Short.class, (short)3)
 			.example(int.class, 4)
@@ -753,7 +752,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_NUMBER_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(NUMBER).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("number").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',example:1}}}", s.getSchema(short[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',example:1}}}", s.getSchema(Short[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',example:1}}}", s.getSchema(int[][].class));
@@ -772,7 +771,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_STRING() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(STRING).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("string").build().createSession();
 		assertObjectEquals("{type:'string',example:'foo'}", s.getSchema(String.class));
 		assertObjectEquals("{type:'string',example:'foo'}", s.getSchema(StringBuilder.class));
 		assertObjectEquals("{type:'string',example:'a'}", s.getSchema(Character.class));
@@ -781,7 +780,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_STRING_wDefault() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(STRING)
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("string")
 			.example(String.class, "bar1")
 			.example(StringBuilder.class, new StringBuilder("bar2"))
 			.example(Character.class, 'b')
@@ -795,7 +794,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_STRING_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(STRING).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("string").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',example:'foo'}}}", s.getSchema(String[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',example:'foo'}}}", s.getSchema(StringBuilder[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',example:'a'}}}", s.getSchema(Character[][].class));
@@ -804,7 +803,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_STRING_2darray_wDefault() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(STRING)
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("string")
 			.example(String.class, "bar1")
 			.example(StringBuilder.class, new StringBuilder("bar2"))
 			.example(Character.class, 'b')
@@ -822,37 +821,37 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addExample_ENUM() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("enum").build().createSession();
 		assertObjectEquals("{type:'string','enum':['one','two','three'],example:'one'}", s.getSchema(TestEnum.class));
 	}
 
 	@Test
 	public void addExample_ENUM_wDefault() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ENUM).example(TestEnum.class, TestEnum.TWO).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("enum").example(TestEnum.class, TestEnum.TWO).build().createSession();
 		assertObjectEquals("{type:'string','enum':['one','two','three'],example:'two'}", s.getSchema(TestEnum.class));
 	}
 
 	@Test
 	public void addExample_ENUM_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("enum").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string','enum':['one','two','three'],example:'one'}}}", s.getSchema(TestEnum[][].class));
 	}
 
 	@Test
 	public void addExample_ENUM_useEnumNames() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamples(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamplesTo("enum").build().createSession();
 		assertObjectEquals("{type:'string','enum':['ONE','TWO','THREE'],example:'ONE'}", s.getSchema(TestEnum.class));
 	}
 
 	@Test
 	public void addExample_ENUM_wDefault_useEnumNames() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamples(ENUM).example(TestEnum.class, TestEnum.TWO).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamplesTo("enum").example(TestEnum.class, TestEnum.TWO).build().createSession();
 		assertObjectEquals("{type:'string','enum':['ONE','TWO','THREE'],example:'TWO'}", s.getSchema(TestEnum.class));
 	}
 
 	@Test
 	public void addExample_ENUM_2darray_useEnumNames() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamples(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().useEnumNames().addExamplesTo("enum").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string','enum':['ONE','TWO','THREE'],example:'ONE'}}}", s.getSchema(TestEnum[][].class));
 	}
 
@@ -861,7 +860,7 @@ public class JsonSchemaSerializerTest {
 	//====================================================================================================
 	@Test
 	public void addExample_ANY() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamples(ANY).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addExamplesTo("any").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string',example:'foo'}}}", s.getSchema(SimpleBean.class));
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},example:{'123':{f1:'foobar'}}}", s.getSchema(BeanMapWithExampleMethod.class));
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[{f1:'foobar'}]}", s.getSchema(BeanListWithExampleMethod.class));
@@ -885,82 +884,82 @@ public class JsonSchemaSerializerTest {
 	}
 	
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - BEAN
+	// JSONSCHEMA_addDescriptionsTo - BEAN
 	//====================================================================================================
 
 	@Test
 	public void addDescription_BEAN() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("bean").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$SimpleBean'}", s.getSchema(SimpleBean.class));
 	}
 
 	@Test
 	public void addDescription_BEAN_array2d() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(BEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("bean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$SimpleBean'}}}", s.getSchema(SimpleBean[][].class));
 	}
 	
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - MAP
+	// JSONSCHEMA_addDescriptionsTo - MAP
 	//====================================================================================================
 
 	@Test
 	public void addDescription_MAP() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("map").build().createSession();
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanMap'}", s.getSchema(BeanMap.class));
 	}
 
 	@Test
 	public void addDescription_MAP_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(MAP).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("map").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanMap'}}}", s.getSchema(BeanMap[][].class));
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - COLLECTION / ARRAY
+	// JSONSCHEMA_addDescriptionsTo - COLLECTION / ARRAY
 	//====================================================================================================
 	
 	@Test
 	public void addDescription_COLLECTION() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList'}", s.getSchema(BeanList.class));
 	}
 
 	@Test
 	public void addDescription_COLLECTION_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(COLLECTION).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("collection").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList'}}}", s.getSchema(BeanList[][].class));
 	}
 	
 	@Test
 	public void addDescription_ARRAY() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(ARRAY).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("array").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'array',items:{type:'object',properties:{f1:{type:'string'}}}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList[][]'}", s.getSchema(BeanList[][].class));
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - BOOLEAN
+	// JSONSCHEMA_addDescriptionsTo - BOOLEAN
 	//====================================================================================================
 	@Test
 	public void addDescription_BOOLEAN() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(BOOLEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("boolean").build().createSession();
 		assertObjectEquals("{type:'boolean',description:'boolean'}", s.getSchema(boolean.class));
 		assertObjectEquals("{type:'boolean',description:'java.lang.Boolean'}", s.getSchema(Boolean.class));
 	}
 
 	@Test
 	public void addDescription_BOOLEAN_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(BOOLEAN).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("boolean").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'boolean',description:'boolean'}}}", s.getSchema(boolean[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'boolean',description:'java.lang.Boolean'}}}", s.getSchema(Boolean[][].class));
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - NUMBER
+	// JSONSCHEMA_addDescriptionsTo - NUMBER
 	//====================================================================================================
 	@Test
 	public void addDescription_NUMBER() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(NUMBER).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("number").build().createSession();
 		assertObjectEquals("{type:'integer',format:'int16',description:'short'}", s.getSchema(short.class));
 		assertObjectEquals("{type:'integer',format:'int16',description:'java.lang.Short'}", s.getSchema(Short.class));
 		assertObjectEquals("{type:'integer',format:'int32',description:'int'}", s.getSchema(int.class));
@@ -975,7 +974,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addDescription_NUMBER_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(NUMBER).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("number").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',description:'short'}}}", s.getSchema(short[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int16',description:'java.lang.Short'}}}", s.getSchema(Short[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'integer',format:'int32',description:'int'}}}", s.getSchema(int[][].class));
@@ -989,12 +988,12 @@ public class JsonSchemaSerializerTest {
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - STRING
+	// JSONSCHEMA_addDescriptionsTo - STRING
 	//====================================================================================================
 
 	@Test
 	public void addDescription_STRING() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(STRING).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("string").build().createSession();
 		assertObjectEquals("{type:'string',description:'java.lang.String'}", s.getSchema(String.class));
 		assertObjectEquals("{type:'string',description:'java.lang.StringBuilder'}", s.getSchema(StringBuilder.class));
 		assertObjectEquals("{type:'string',description:'java.lang.Character'}", s.getSchema(Character.class));
@@ -1003,7 +1002,7 @@ public class JsonSchemaSerializerTest {
 
 	@Test
 	public void addDescription_STRING_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(STRING).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("string").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.String'}}}", s.getSchema(String[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.StringBuilder'}}}", s.getSchema(StringBuilder[][].class));
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string',description:'java.lang.Character'}}}", s.getSchema(Character[][].class));
@@ -1011,27 +1010,27 @@ public class JsonSchemaSerializerTest {
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - ENUM
+	// JSONSCHEMA_addDescriptionsTo - ENUM
 	//====================================================================================================
 
 	@Test
 	public void addDescription_ENUM() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("enum").build().createSession();
 		assertObjectEquals("{type:'string','enum':['one','two','three'],description:'org.apache.juneau.TestEnum'}", s.getSchema(TestEnum.class));
 	}
 
 	@Test
 	public void addDescription_ENUM_2darray() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(ENUM).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("enum").build().createSession();
 		assertObjectEquals("{type:'array',items:{type:'array',items:{type:'string','enum':['one','two','three'],description:'org.apache.juneau.TestEnum'}}}", s.getSchema(TestEnum[][].class));
 	}
 
 	//====================================================================================================
-	// JSONSCHEMA_addDescriptions - ANY
+	// JSONSCHEMA_addDescriptionsTo - ANY
 	//====================================================================================================
 	@Test
 	public void addDescription_ANY() throws Exception {
-		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptions(ANY).build().createSession();
+		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder().addDescriptionsTo("any").build().createSession();
 		assertObjectEquals("{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$SimpleBean'}", s.getSchema(SimpleBean.class));
 		assertObjectEquals("{type:'object',additionalProperties:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanMap'}", s.getSchema(BeanMap.class));
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList'}", s.getSchema(BeanList.class));
@@ -1167,7 +1166,7 @@ public class JsonSchemaSerializerTest {
 			.allowNestedExamples()
 			.example(BeanList.class, new BeanList())
 			.example(SimpleBean.class, new SimpleBean())
-			.addExamples(COLLECTION, BEAN)
+			.addExamplesTo("collection,bean")
 			.build().createSession();
 		
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}},example:{}},example:[]}", s.getSchema(BeanList.class));
@@ -1178,7 +1177,7 @@ public class JsonSchemaSerializerTest {
 		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder()
 			.example(BeanList.class, new BeanList())
 			.example(SimpleBean.class, new SimpleBean())
-			.addExamples(COLLECTION, BEAN)
+			.addExamplesTo("collection,bean")
 			.build().createSession();
 		
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},example:[]}", s.getSchema(BeanList.class));
@@ -1192,7 +1191,7 @@ public class JsonSchemaSerializerTest {
 	public void allowNestedDescriptions_enabled() throws Exception {
 		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder()
 			.allowNestedDescriptions()
-			.addDescriptions(COLLECTION, BEAN)
+			.addDescriptionsTo("collection,bean")
 			.build().createSession();
 		
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$SimpleBean'},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList'}", s.getSchema(BeanList.class));
@@ -1201,7 +1200,7 @@ public class JsonSchemaSerializerTest {
 	@Test
 	public void allowNestedDescriptions_disabled() throws Exception {
 		JsonSchemaSerializerSession s = JsonSchemaSerializer.DEFAULT_LAX.builder()
-			.addDescriptions(COLLECTION, BEAN)
+			.addDescriptionsTo("collection,bean")
 			.build().createSession();
 		
 		assertObjectEquals("{type:'array',items:{type:'object',properties:{f1:{type:'string'}}},description:'org.apache.juneau.json.JsonSchemaSerializerTest$BeanList'}", s.getSchema(BeanList.class));
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Contact.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Contact.java
index d6db1e3..23daa40 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Contact.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Contact.java
@@ -60,6 +60,33 @@ public class Contact extends SwaggerElement {
 	private String email;
 
 	/**
+	 * Default constructor.
+	 */
+	public Contact() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Contact(Contact copyFrom) {
+		super(copyFrom);
+		
+		this.name = copyFrom.name;
+		this.url = copyFrom.url;
+		this.email = copyFrom.email;
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Contact copy() {
+		return new Contact(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>name</property>.
 	 * 
 	 * <p>
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ExternalDocumentation.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ExternalDocumentation.java
index b693f47..c95e0d9 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ExternalDocumentation.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ExternalDocumentation.java
@@ -58,6 +58,32 @@ public class ExternalDocumentation extends SwaggerElement {
 	private URI url;
 
 	/**
+	 * Default constructor.
+	 */
+	public ExternalDocumentation() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public ExternalDocumentation(ExternalDocumentation copyFrom) {
+		super(copyFrom);
+		
+		this.description = copyFrom.description;
+		this.url = copyFrom.url;
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public ExternalDocumentation copy() {
+		return new ExternalDocumentation(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>description</property>.
 	 * 
 	 * <p>
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
index ebd9b95..242a58c 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/HeaderInfo.java
@@ -49,7 +49,7 @@ import org.apache.juneau.utils.*;
  * 	<li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.Swagger'>Overview &gt; juneau-dto &gt; Swagger</a>
  * </ul>
  */
-@Bean(properties="description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,*")
+@Bean(properties="description,type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,*")
 @SuppressWarnings({"unchecked"})
 public class HeaderInfo extends SwaggerElement {
 
@@ -61,7 +61,8 @@ public class HeaderInfo extends SwaggerElement {
 		type,
 		format,
 		collectionFormat,
-		pattern;
+		pattern,
+		ref;
 	private Number 
 		maximum,
 		minimum,
@@ -78,6 +79,48 @@ public class HeaderInfo extends SwaggerElement {
 	private Items items;
 	private Object _default;
 	private List<Object> _enum;
+	
+	/**
+	 * Default constructor.
+	 */
+	public HeaderInfo() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public HeaderInfo(HeaderInfo copyFrom) {
+		super(copyFrom);
+		
+		this.description = copyFrom.description;
+		this.type = copyFrom.type;
+		this.format = copyFrom.format;
+		this.collectionFormat = copyFrom.collectionFormat;
+		this.pattern = copyFrom.pattern;
+		this.maximum = copyFrom.maximum;
+		this.minimum = copyFrom.minimum;
+		this.multipleOf = copyFrom.multipleOf;
+		this.maxLength = copyFrom.maxLength;
+		this.minLength = copyFrom.minLength;
+		this.maxItems = copyFrom.maxItems;
+		this.minItems = copyFrom.minItems;
+		this.exclusiveMaximum = copyFrom.exclusiveMaximum;
+		this.exclusiveMinimum = copyFrom.exclusiveMinimum;
+		this.uniqueItems = copyFrom.uniqueItems;
+		this._default = copyFrom._default;
+		this.items = copyFrom.items == null ? null : copyFrom.items.copy();
+		this._enum = newList(copyFrom._enum);
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public HeaderInfo copy() {
+		return new HeaderInfo(this);
+	}
 
 	@Override /* SwaggerElement */
 	protected HeaderInfo strict() {
@@ -965,6 +1008,51 @@ public class HeaderInfo extends SwaggerElement {
 		return setMultipleOf(toNumber(value));
 	}
 
+	/**
+	 * Bean property getter:  <property>$ref</property>.
+	 * 
+	 * @return The property value, or <jk>null</jk> if it is not set.
+	 */
+	@BeanProperty("$ref")
+	public String getRef() {
+		return ref;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 * 
+	 * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 */
+	public boolean hasRef() {
+		return ref != null;
+	}
+
+	/**
+	 * Bean property setter:  <property>$ref</property>.
+	 * 
+	 * @param value 
+	 * 	The new value for this property.
+	 * 	<br>Can be <jk>null</jk> to unset the property.
+	 * @return This object (for method chaining).
+	 */
+	@BeanProperty("$ref")
+	public HeaderInfo setRef(Object value) {
+		ref = StringUtils.asString(value);
+		return this;
+	}
+
+	/**
+	 * Same as {@link #setRef(Object)}.
+	 * 
+	 * @param value 
+	 * 	The new value for this property.
+	 * 	<br>Can be <jk>null</jk> to unset the property.
+	 * @return This object (for method chaining).
+	 */
+	public HeaderInfo ref(Object value) {
+		return setRef(value);
+	}
+
 	@Override /* SwaggerElement */
 	public <T> T get(String property, Class<T> type) {
 		if (property == null)
@@ -975,6 +1063,7 @@ public class HeaderInfo extends SwaggerElement {
 			case "format": return toType(getFormat(), type);
 			case "items": return toType(getItems(), type);
 			case "collectionFormat": return toType(getCollectionFormat(), type);
+			case "$ref": return toType(getRef(), type);
 			case "default": return toType(getDefault(), type);
 			case "maximum": return toType(getMaximum(), type);
 			case "exclusiveMaximum": return toType(getExclusiveMaximum(), type);
@@ -1002,6 +1091,7 @@ public class HeaderInfo extends SwaggerElement {
 			case "format": return format(value);
 			case "items": return items(value);
 			case "collectionFormat": return collectionFormat(value);
+			case "$ref": return ref(value);
 			case "default": return _default(value);
 			case "maximum": return maximum(value);
 			case "exclusiveMaximum": return exclusiveMaximum(value);
@@ -1029,6 +1119,7 @@ public class HeaderInfo extends SwaggerElement {
 			.appendIf(format != null, "format")
 			.appendIf(items != null, "items")
 			.appendIf(collectionFormat != null, "collectionFormat")
+			.appendIf(ref != null, "$ref")
 			.appendIf(_default != null, "default")
 			.appendIf(maximum != null, "maximum")
 			.appendIf(exclusiveMaximum != null, "exclusiveMaximum")
@@ -1045,4 +1136,23 @@ public class HeaderInfo extends SwaggerElement {
 		return new MultiSet<>(s, super.keySet());
 		
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public HeaderInfo resolveRefs(Swagger swagger) {
+		
+		if (ref != null)
+			return swagger.findRef(ref, HeaderInfo.class);
+		
+		if (items != null)
+			items = items.resolveRefs(swagger);
+		
+		return this;
+	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Info.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Info.java
index 5dfe36e..8fca4fa 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Info.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Info.java
@@ -80,6 +80,36 @@ public class Info extends SwaggerElement {
 	private License license;
 
 	/**
+	 * Default constructor.
+	 */
+	public Info() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Info(Info copyFrom) {
+		super(copyFrom);
+		
+		this.title = copyFrom.title;
+		this.description = copyFrom.description;
+		this.termsOfService = copyFrom.termsOfService;
+		this.version = copyFrom.version;
+		this.contact = copyFrom.contact == null ? null : copyFrom.contact.copy();
+		this.license = copyFrom.license == null ? null : copyFrom.license.copy();
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Info copy() {
+		return new Info(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>title</property>.
 	 * 
 	 * <p>
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
index 95f3727..56c7b5b 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Items.java
@@ -50,7 +50,7 @@ import org.apache.juneau.utils.*;
  * 	<li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.Swagger'>Overview &gt; juneau-dto &gt; Swagger</a>
  * </ul>
  */
-@Bean(properties="type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,*")
+@Bean(properties="type,format,items,collectionFormat,default,maximum,exclusiveMaximum,minimum,exclusiveMinimum,maxLength,minLength,pattern,maxItems,minItems,uniqueItems,enum,multipleOf,$ref,*")
 public class Items extends SwaggerElement {
 
 	private static final String[] VALID_TYPES = {"string", "number", "integer", "boolean", "array"};
@@ -60,7 +60,8 @@ public class Items extends SwaggerElement {
 		type,
 		format,
 		collectionFormat,
-		pattern;
+		pattern, 
+		ref;
 	private Number 
 		maximum,
 		minimum,
@@ -78,6 +79,49 @@ public class Items extends SwaggerElement {
 	private Object _default;
 	private List<Object> _enum;
 
+	/**
+	 * Default constructor.
+	 */
+	public Items() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Items(Items copyFrom) {
+		super(copyFrom);
+		
+		this.type = copyFrom.type;
+		this.format = copyFrom.format;
+		this.collectionFormat = copyFrom.collectionFormat;
+		this.pattern = copyFrom.pattern;
+		this.ref = copyFrom.ref;
+		this.maximum = copyFrom.maximum;
+		this.minimum = copyFrom.minimum;
+		this.multipleOf = copyFrom.multipleOf;
+		this.maxLength = copyFrom.maxLength;
+		this.minLength = copyFrom.minLength;
+		this.maxItems = copyFrom.maxItems;
+		this.minItems = copyFrom.minItems;
+		this.exclusiveMaximum = copyFrom.exclusiveMaximum;
+		this.exclusiveMinimum = copyFrom.exclusiveMinimum;
+		this.uniqueItems = copyFrom.uniqueItems;
+		this.items = copyFrom.items == null ? null : copyFrom.items.copy();
+		this._default = copyFrom._default;
+		this._enum = newList(copyFrom._enum);
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Items copy() {
+		return new Items(this);
+	}
+	
+	
 	@Override /* SwaggerElement */
 	protected Items strict() {
 		super.strict();
@@ -941,6 +985,51 @@ public class Items extends SwaggerElement {
 		return setMultipleOf(toNumber(value));
 	}
 
+	/**
+	 * Bean property getter:  <property>$ref</property>.
+	 * 
+	 * @return The property value, or <jk>null</jk> if it is not set.
+	 */
+	@BeanProperty("$ref")
+	public String getRef() {
+		return ref;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 * 
+	 * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 */
+	public boolean hasRef() {
+		return ref != null;
+	}
+	
+	/**
+	 * Bean property setter:  <property>$ref</property>.
+	 * 
+	 * @param value 
+	 * 	The new value for this property.
+	 * 	<br>Can be <jk>null</jk> to unset the property.
+	 * @return This object (for method chaining).
+	 */
+	@BeanProperty("$ref")
+	public Items setRef(Object value) {
+		ref = StringUtils.asString(value);
+		return this;
+	}
+
+	/**
+	 * Same as {@link #setRef(Object)}.
+	 * 
+	 * @param value 
+	 * 	The new value for this property.
+	 * 	<br>Can be <jk>null</jk> to unset the property.
+	 * @return This object (for method chaining).
+	 */
+	public Items ref(Object value) {
+		return setRef(value);
+	}
+
 	@Override /* SwaggerElement */
 	public <T> T get(String property, Class<T> type) {
 		if (property == null)
@@ -950,6 +1039,7 @@ public class Items extends SwaggerElement {
 			case "format": return toType(getFormat(), type);
 			case "items": return toType(getItems(), type);
 			case "collectionFormat": return toType(getCollectionFormat(), type);
+			case "$ref": return toType(getRef(), type);
 			case "default": return toType(getDefault(), type);
 			case "maximum": return toType(getMaximum(), type);
 			case "exclusiveMaximum": return toType(getExclusiveMaximum(), type);
@@ -976,6 +1066,7 @@ public class Items extends SwaggerElement {
 			case "format": return format(value);
 			case "items": return items(value);
 			case "collectionFormat": return collectionFormat(value);
+			case "$ref": return ref(value);
 			case "default": return _default(value);
 			case "maximum": return maximum(value);
 			case "exclusiveMaximum": return exclusiveMaximum(value);
@@ -1002,6 +1093,7 @@ public class Items extends SwaggerElement {
 			.appendIf(format != null, "format")
 			.appendIf(items != null, "items")
 			.appendIf(collectionFormat != null, "collectionFormat")
+			.appendIf(ref != null, "$ref")
 			.appendIf(_default != null, "default")
 			.appendIf(maximum != null, "maximum")
 			.appendIf(exclusiveMaximum != null, "exclusiveMaximum")
@@ -1017,4 +1109,24 @@ public class Items extends SwaggerElement {
 			.appendIf(multipleOf != null, "multipleOf");
 		return new MultiSet<>(s, super.keySet());
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public Items resolveRefs(Swagger swagger) {
+		
+		if (ref != null)
+			return swagger.findRef(ref, Items.class);
+		
+		if (items != null)
+			items = items.resolveRefs(swagger);
+
+		return this;
+	}
+
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/License.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/License.java
index 61ef053..cf35643 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/License.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/License.java
@@ -58,6 +58,32 @@ public class License extends SwaggerElement {
 	private URI url;
 
 	/**
+	 * Default constructor.
+	 */
+	public License() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public License(License copyFrom) {
+		super(copyFrom);
+		
+		this.name = copyFrom.name;
+		this.url = copyFrom.url;
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public License copy() {
+		return new License(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>name</property>.
 	 * 
 	 * <p>
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
index 1014542..e5df4c2 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Operation.java
@@ -148,6 +148,59 @@ public class Operation extends SwaggerElement {
 	private Map<String,ResponseInfo> responses;
 
 	/**
+	 * Default constructor.
+	 */
+	public Operation() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Operation(Operation copyFrom) {
+		super(copyFrom);
+
+		this.summary = copyFrom.summary;
+		this.description = copyFrom.description;
+		this.operationId = copyFrom.operationId;
+		this.deprecated = copyFrom.deprecated;
+		this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
+		this.tags = newList(copyFrom.tags);
+		this.schemes = newList(copyFrom.schemes);
+		this.consumes = newList(copyFrom.consumes);
+		this.produces = newList(copyFrom.produces);
+		
+		this.parameters = copyFrom.parameters == null ? null : new ArrayList<ParameterInfo>();
+		if (copyFrom.parameters != null)
+			for (ParameterInfo p : copyFrom.parameters)
+				this.parameters.add(p.copy());
+		
+		this.security = copyFrom.security == null ? null : new ArrayList<Map<String,List<String>>>();
+		if (copyFrom.security != null) {
+			for (Map<String,List<String>> m : copyFrom.security) {
+				Map<String,List<String>> m2 = new LinkedHashMap<>();
+				for (Map.Entry<String,List<String>> e : m.entrySet())
+					m2.put(e.getKey(), newList(e.getValue()));
+				this.security.add(m2);
+			}
+		}
+		
+		this.responses = copyFrom.responses == null ? null : new LinkedHashMap<String,ResponseInfo>();
+		if (copyFrom.responses != null)
+			for (Map.Entry<String,ResponseInfo> e : copyFrom.responses.entrySet()) 
+				this.responses.put(e.getKey(), e.getValue().copy());
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Operation copy() {
+		return new Operation(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>tags</property>.
 	 * 
 	 * <p>
@@ -1118,4 +1171,25 @@ public class Operation extends SwaggerElement {
 			.appendIf(security != null, "security");
 		return new MultiSet<>(s, super.keySet());
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public Operation resolveRefs(Swagger swagger) {
+		
+		if (parameters != null)
+			for (ListIterator<ParameterInfo> i = parameters.listIterator(); i.hasNext();)
+				i.set(i.next().resolveRefs(swagger));
+
+		if (responses != null)
+			for (Map.Entry<String,ResponseInfo> e : responses.entrySet())
+				e.setValue(e.getValue().resolveRefs(swagger));
+		
+		return this;
+	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
index 290c413..b1fe506 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ParameterInfo.java
@@ -126,6 +126,57 @@ public class ParameterInfo extends SwaggerElement {
 	private List<Object> _enum;
 	private Map<String,String> examples;
 
+	/**
+	 * Default constructor.
+	 */
+	public ParameterInfo() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public ParameterInfo(ParameterInfo copyFrom) {
+		super(copyFrom);
+		
+		this.name = copyFrom.name;
+		this.in = copyFrom.in;
+		this.description = copyFrom.description;
+		this.type = copyFrom.type;
+		this.format = copyFrom.format;
+		this.pattern = copyFrom.pattern;
+		this.collectionFormat = copyFrom.collectionFormat;
+		this.maximum = copyFrom.maximum;
+		this.minimum = copyFrom.minimum;
+		this.multipleOf = copyFrom.multipleOf;
+		this.maxLength = copyFrom.maxLength;
+		this.minLength = copyFrom.minLength;
+		this.maxItems = copyFrom.maxItems;
+		this.minItems = copyFrom.minItems;
+		this.required = copyFrom.required;
+		this.allowEmptyValue = copyFrom.allowEmptyValue;
+		this.exclusiveMaximum = copyFrom.exclusiveMaximum;
+		this.exclusiveMinimum = copyFrom.exclusiveMinimum;
+		this.uniqueItems = copyFrom.uniqueItems;
+		this.schema = copyFrom.schema == null ? null : copyFrom.schema.copy();
+		this.items = copyFrom.items == null ? null : copyFrom.items.copy();
+		this._default = copyFrom._default;
+		this._enum = newList(copyFrom._enum);
+		
+		this.examples = copyFrom.examples == null ? null : new LinkedHashMap<String,String>();
+		if (copyFrom.examples != null)
+			this.examples.putAll(copyFrom.examples);
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public ParameterInfo copy() {
+		return new ParameterInfo(this);
+	}
+	
 	@Override /* SwaggerElement */
 	protected ParameterInfo strict() {
 		super.strict();
@@ -1525,4 +1576,23 @@ public class ParameterInfo extends SwaggerElement {
 			.appendIf(examples != null, "examples");
 		return new MultiSet<>(s, super.keySet());
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public ParameterInfo resolveRefs(Swagger swagger) {
+		
+		if (schema != null)
+			schema = schema.resolveRefs(swagger);
+		
+		if (items != null)
+			items = items.resolveRefs(swagger);
+
+		return this;
+	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
index 341a9a8..afec0ce 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ResponseInfo.java
@@ -68,6 +68,41 @@ public class ResponseInfo extends SwaggerElement {
 	private Map<String,Object> examples;
 
 	/**
+	 * Default constructor.
+	 */
+	public ResponseInfo() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public ResponseInfo(ResponseInfo copyFrom) {
+		super(copyFrom);
+		
+		this.description = copyFrom.description;
+		this.schema = copyFrom.schema == null ? null : copyFrom.schema.copy();
+		
+		this.headers = copyFrom.headers == null ? null : new LinkedHashMap<String,HeaderInfo>();
+		if (copyFrom.headers != null) 
+			for (Map.Entry<String,HeaderInfo> e : copyFrom.headers.entrySet())
+				this.headers.put(e.getKey(),	e.getValue().copy());
+		
+		this.examples = copyFrom.examples == null ? null : new LinkedHashMap<String,Object>();
+		if (copyFrom.examples != null)
+			this.examples.putAll(copyFrom.examples);
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public ResponseInfo copy() {
+		return new ResponseInfo(this);
+	}
+	
+	/**
 	 * Copies any non-null fields from the specified object to this object.
 	 * 
 	 * @param r 
@@ -400,4 +435,24 @@ public class ResponseInfo extends SwaggerElement {
 	public boolean hasHeaders() {
 		return headers != null && ! headers.isEmpty();
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public ResponseInfo resolveRefs(Swagger swagger) {
+
+		if (schema != null)
+			schema = schema.resolveRefs(swagger);
+		
+		if (headers != null)
+			for (Map.Entry<String,HeaderInfo> e : headers.entrySet()) 
+				e.setValue(e.getValue().resolveRefs(swagger));
+
+		return this;
+	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
index de5de35..ca5260f 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SchemaInfo.java
@@ -95,9 +95,68 @@ public class SchemaInfo extends SwaggerElement {
 		allOf;
 	private List<String>
 		required;
-	private Map<String,Map<String,Object>> properties;
-	private Map<String,Object> additionalProperties;
-
+	private Map<String,SchemaInfo> properties;
+	private SchemaInfo additionalProperties;
+	
+	/**
+	 * Default constructor.
+	 */
+	public SchemaInfo() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public SchemaInfo(SchemaInfo copyFrom) {
+		super(copyFrom);
+		
+		this.format = copyFrom.format;
+		this.title = copyFrom.title;
+		this.description = copyFrom.description;
+		this.pattern = copyFrom.pattern;
+		this.type = copyFrom.type;
+		this.discriminator = copyFrom.discriminator;
+		this.ref = copyFrom.ref;
+		this.multipleOf = copyFrom.multipleOf;
+		this.maximum = copyFrom.maximum;
+		this.minimum = copyFrom.minimum;
+		this.maxLength = copyFrom.maxLength;
+		this.minLength = copyFrom.minLength;
+		this.maxItems = copyFrom.maxItems;
+		this.minItems = copyFrom.minItems;
+		this.maxProperties = copyFrom.maxProperties;
+		this.minProperties = copyFrom.minProperties;
+		this.exclusiveMaximum = copyFrom.exclusiveMaximum;
+		this.exclusiveMinimum = copyFrom.exclusiveMinimum;
+		this.uniqueItems = copyFrom.uniqueItems;
+		this.readOnly = copyFrom.readOnly;
+		this._default = copyFrom._default;
+		this.example = copyFrom.example;
+		this.items = copyFrom.items == null ? null : copyFrom.items.copy();
+		this.xml = copyFrom.xml == null ? null : copyFrom.xml.copy();
+		this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
+		this._enum = newList(copyFrom._enum);
+		this.allOf = newList(copyFrom.allOf);
+		this.required = newList(copyFrom.required);
+		
+		this.properties = copyFrom.properties == null ? null : new LinkedHashMap<String,SchemaInfo>();
+		if (copyFrom.properties != null)
+			for (Map.Entry<String,SchemaInfo> e : copyFrom.properties.entrySet())
+				this.properties.put(e.getKey(), e.getValue().copy());
+		
+		this.additionalProperties = copyFrom.additionalProperties == null ? null : copyFrom.additionalProperties.copy();
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public SchemaInfo copy() {
+		return new SchemaInfo(this);
+	}
+	
 	/**
 	 * Bean property getter:  <property>format</property>.
 	 * 
@@ -997,7 +1056,7 @@ public class SchemaInfo extends SwaggerElement {
 	 * 
 	 * @return The property value, or <jk>null</jk> if it is not set.
 	 */
-	public Map<String,Map<String,Object>> getProperties() {
+	public Map<String,SchemaInfo> getProperties() {
 		return properties;
 	}
 
@@ -1009,7 +1068,7 @@ public class SchemaInfo extends SwaggerElement {
 	 * 	<br>Can be <jk>null</jk> to unset the property.
 	 * @return This object (for method chaining).
 	 */
-	public SchemaInfo setProperties(Map<String,Map<String,Object>> value) {
+	public SchemaInfo setProperties(Map<String,SchemaInfo> value) {
 		properties = newMap(value);
 		return this;
 	}
@@ -1022,7 +1081,7 @@ public class SchemaInfo extends SwaggerElement {
 	 * 	<br>Ignored if <jk>null</jk>.
 	 * @return This object (for method chaining).
 	 */
-	public SchemaInfo addProperties(Map<String,Map<String,Object>> values) {
+	public SchemaInfo addProperties(Map<String,SchemaInfo> values) {
 		properties = addToMap(properties, values);
 		return this;
 	}
@@ -1044,9 +1103,8 @@ public class SchemaInfo extends SwaggerElement {
 	 * 	<br>Ignored if <jk>null</jk>.
 	 * @return This object (for method chaining).
 	 */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
 	public SchemaInfo properties(Object...values) {
-		properties = addToMap((Map)properties, values, String.class, Map.class, String.class, Object.class);
+		properties = addToMap(properties, values, String.class, SchemaInfo.class);
 		return this;
 	}
 
@@ -1055,7 +1113,7 @@ public class SchemaInfo extends SwaggerElement {
 	 * 
 	 * @return The property value, or <jk>null</jk> if it is not set.
 	 */
-	public Map<String,Object> getAdditionalProperties() {
+	public SchemaInfo getAdditionalProperties() {
 		return additionalProperties;
 	}
 
@@ -1067,55 +1125,21 @@ public class SchemaInfo extends SwaggerElement {
 	 * 	<br>Can be <jk>null</jk> to unset the property.
 	 * @return This object (for method chaining).
 	 */
-	public SchemaInfo setAdditionalProperties(Map<String,Object> value) {
-		additionalProperties = newMap(value);
+	public SchemaInfo setAdditionalProperties(SchemaInfo value) {
+		additionalProperties = value;
 		return this;
 	}
 
 	/**
-	 * Adds one or more values to the <property>additionalProperties</property> property.
-	 * 
-	 * @param values
-	 * 	The values to add to this property.
-	 * 	<br>Ignored if <jk>null</jk>.
-	 * @return This object (for method chaining).
-	 */
-	public SchemaInfo addAdditionalProperties(Map<String,Object> values) {
-		additionalProperties = addToMap(additionalProperties, values);
-		return this;
-	}
-
-	/**
-	 * Adds a single value to the <property>additionalProperties</property> property.
-	 * 
-	 * @param name The extra property name.
-	 * @param value The extra property value.
-	 * @return This object (for method chaining).
-	 */
-	public SchemaInfo additionalProperty(String name, Object value) {
-		additionalProperties = addToMap(additionalProperties, name, value);
-		return this;
-	}
-
-	/**
-	 * Adds one or more values to the <property>additionalProperties</property> property.
+	 * Bean property setter:  <property>additionalProperties</property>.
 	 * 
-	 * @param values
-	 * 	The values to add to this property.
-	 * 	<br>Valid types:
-	 * 	<ul>
-	 * 		<li><code>Map&lt;String,Object&gt;</code>
-	 * 		<li><code>String</code> - JSON object representation of <code>Map&lt;String,Object&gt;</code>
-	 * 			<h5 class='figure'>Example:</h5>
-	 * 			<p class='bcode'>
-	 * 	extraProperties(<js>"{name:'value'}"</js>);
-	 * 			</p>
-	 * 	</ul>
-	 * 	<br>Ignored if <jk>null</jk>.
+	 * @param value 
+	 * 	The new value for this property.
+	 * 	<br>Can be <jk>null</jk> to unset the property.
 	 * @return This object (for method chaining).
 	 */
-	public SchemaInfo additionalProperties(Object...values) {
-		additionalProperties = addToMap(additionalProperties, values, String.class, Object.class);
+	public SchemaInfo additionalProperties(Object value) {
+		additionalProperties = toType(value, SchemaInfo.class);
 		return this;
 	}
 
@@ -1320,6 +1344,15 @@ public class SchemaInfo extends SwaggerElement {
 	}
 
 	/**
+	 * Returns <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 * 
+	 * @return <jk>true</jk> if this object has a <js>"$ref"</js> attribute.
+	 */
+	public boolean hasRef() {
+		return ref != null;
+	}
+
+	/**
 	 * Bean property setter:  <property>$ref</property>.
 	 * 
 	 * @param value 
@@ -1379,6 +1412,7 @@ public class SchemaInfo extends SwaggerElement {
 			case "xml": return toType(getXml(), type);
 			case "externalDocs": return toType(getExternalDocs(), type);
 			case "example": return toType(getExample(), type);
+			case "$ref": return toType(getRef(), type);
 			default: return super.get(property, type);
 		}
 	}
@@ -1411,12 +1445,13 @@ public class SchemaInfo extends SwaggerElement {
 			case "items": return items(value);
 			case "allOf": return setAllOf(null).allOf(value);
 			case "properties": return setProperties(null).properties(value);
-			case "additionalProperties": return setAdditionalProperties(null).additionalProperties(value);
+			case "additionalProperties": return additionalProperties(value);
 			case "discriminator": return discriminator(value);
 			case "readOnly": return readOnly(value);
 			case "xml": return xml(value);
 			case "externalDocs": return externalDocs(value);
 			case "example": return example(value);
+			case "$ref": return ref(value);
 			default: 
 				super.set(property, value);
 				return this;
@@ -1454,10 +1489,13 @@ public class SchemaInfo extends SwaggerElement {
 			.appendIf(readOnly != null, "readOnly")
 			.appendIf(xml != null, "xml")
 			.appendIf(externalDocs != null, "externalDocs")
-			.appendIf(example != null, "example");
+			.appendIf(example != null, "example")
+			.appendIf(ref != null, "$ref");
 		return new MultiSet<>(s, super.keySet());
 	}
 
+	
+	
 	/**
 	 * Returns <jk>true</jk> if this schema info has one or more properties defined on it.
 	 * 
@@ -1466,4 +1504,30 @@ public class SchemaInfo extends SwaggerElement {
 	public boolean hasProperties() {
 		return properties != null && ! properties.isEmpty();
 	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this element.
+	 * 
+	 * @param swagger The swagger document containing the definitions.
+	 * @return 
+	 * 	This object with references resolved.
+	 * 	<br>May or may not be the same object.
+	 */
+	public SchemaInfo resolveRefs(Swagger swagger) {
+		
+		if (ref != null) 
+			return swagger.findRef(ref, SchemaInfo.class);
+		
+		if (items != null)
+			items = items.resolveRefs(swagger);
+		
+		if (properties != null) 
+			for (Map.Entry<String,SchemaInfo> e : properties.entrySet())
+				e.setValue(e.getValue().resolveRefs(swagger));
+			
+		if (additionalProperties != null) 
+			additionalProperties = additionalProperties.resolveRefs(swagger);
+
+		return this;
+	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
index 986002f..0b80e45 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SecurityScheme.java
@@ -74,7 +74,43 @@ public class SecurityScheme extends SwaggerElement {
 		authorizationUrl,
 		tokenUrl;
 	private Map<String,String> scopes;
+	
+	/**
+	 * Default constructor.
+	 */
+	public SecurityScheme() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public SecurityScheme(SecurityScheme copyFrom) {
+		super(copyFrom);
+		
+		this.type = copyFrom.type;
+		this.description = copyFrom.description;
+		this.name = copyFrom.name;
+		this.in = copyFrom.in;
+		this.flow = copyFrom.flow;
+		this.authorizationUrl = copyFrom.authorizationUrl;
+		this.tokenUrl = copyFrom.tokenUrl;
+		
+		this.scopes = copyFrom.scopes == null ? null : new LinkedHashMap<String,String>();
+		if (copyFrom.scopes != null)
+			this.scopes.putAll(copyFrom.scopes);
+	}
 
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public SecurityScheme copy() {
+		return new SecurityScheme(this);
+	}
+	
+	
 	@Override /* SwaggerElement */
 	protected SecurityScheme strict() {
 		super.strict();
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
index c0388e0..c498e44 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Swagger.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.internal.StringUtils.*;
 
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.*;
 import org.apache.juneau.internal.*;
@@ -49,13 +50,89 @@ public class Swagger extends SwaggerElement {
 		produces;
 	private List<Tag> tags;
 	private List<Map<String,List<String>>> security;
-	private Map<String,SchemaInfo> definitions;
+	private Map<String,ObjectMap> definitions;
 	private Map<String,ParameterInfo> parameters;
 	private Map<String,ResponseInfo> responses;
 	private Map<String,SecurityScheme> securityDefinitions;
 	private Map<String,Map<String,Operation>> paths;
 
 	/**
+	 * Default constructor.
+	 */
+	public Swagger() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Swagger(Swagger copyFrom) {
+		super(copyFrom);
+
+		this.swagger = copyFrom.swagger;
+		this.host = copyFrom.host;
+		this.basePath = copyFrom.basePath;
+		this.info = copyFrom.info == null ? null : copyFrom.info.copy();
+		this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
+		this.schemes = newList(copyFrom.schemes);
+		this.consumes = newList(copyFrom.consumes);
+		this.produces = newList(copyFrom.produces);
+
+		this.tags = copyFrom.tags == null ? null : new ArrayList<Tag>();
+		if (copyFrom.tags != null)
+			for (Tag t : copyFrom.tags)
+				this.tags.add(t.copy());
+		
+		this.security = copyFrom.security == null ? null : new ArrayList<Map<String,List<String>>>();
+		if (copyFrom.security != null)
+			for (Map<String,List<String>> m : copyFrom.security) {
+				Map<String,List<String>> m2 = new LinkedHashMap<>();
+				for (Map.Entry<String,List<String>> e : m.entrySet())
+					m2.put(e.getKey(), newList(e.getValue()));
+				this.security.add(m2);
+			}
+
+		// TODO - Definitions are not deep copied, so they should not contain references.
+		this.definitions = copyFrom.definitions == null ? null : new LinkedHashMap<String,ObjectMap>();
+		if (copyFrom.definitions != null)
+			for (Map.Entry<String,ObjectMap> e : copyFrom.definitions.entrySet())
+				this.definitions.put(e.getKey(), new ObjectMap(e.getValue()));
+		
+		this.parameters = copyFrom.parameters == null ? null : new LinkedHashMap<String,ParameterInfo>();
+		if (copyFrom.parameters != null)
+			for (Map.Entry<String,ParameterInfo> e : copyFrom.parameters.entrySet())
+				this.parameters.put(e.getKey(), e.getValue().copy());
+
+		this.responses = copyFrom.responses == null ? null : new LinkedHashMap<String,ResponseInfo>();
+		if (copyFrom.responses != null)
+			for (Map.Entry<String,ResponseInfo> e : copyFrom.responses.entrySet())
+				this.responses.put(e.getKey(), e.getValue().copy());
+
+		this.securityDefinitions = copyFrom.securityDefinitions == null ? null : new LinkedHashMap<String,SecurityScheme>();
+		if (copyFrom.securityDefinitions != null)
+			for (Map.Entry<String,SecurityScheme> e : copyFrom.securityDefinitions.entrySet())
+				this.securityDefinitions.put(e.getKey(), e.getValue().copy());
+
+		this.paths = copyFrom.paths == null ? null : new LinkedHashMap<String,Map<String,Operation>>();
+		if (copyFrom.paths != null)
+			for (Map.Entry<String,Map<String,Operation>> e : copyFrom.paths.entrySet()) {
+				Map<String,Operation> m = new LinkedHashMap<>();
+				for (Map.Entry<String,Operation> e2 : e.getValue().entrySet())
+					m.put(e2.getKey(), e2.getValue().copy());
+				this.paths.put(e.getKey(), m);
+			}
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Swagger copy() {
+		return new Swagger(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>swagger</property>.
 	 * 
 	 * <p>
@@ -617,7 +694,7 @@ public class Swagger extends SwaggerElement {
 	 * 
 	 * @return The property value, or <jk>null</jk> if it is not set.
 	 */
-	public Map<String,SchemaInfo> getDefinitions() {
+	public Map<String,ObjectMap> getDefinitions() {
 		return definitions;
 	}
 
@@ -632,7 +709,7 @@ public class Swagger extends SwaggerElement {
 	 * 	<br>Can be <jk>null</jk> to unset the property.
 	 * @return This object (for method chaining).
 	 */
-	public Swagger setDefinitions(Map<String,SchemaInfo> value) {
+	public Swagger setDefinitions(Map<String,ObjectMap> value) {
 		definitions = newMap(value);
 		return this;
 	}
@@ -648,7 +725,7 @@ public class Swagger extends SwaggerElement {
 	 * 	<br>Ignored if <jk>null</jk>.
 	 * @return This object (for method chaining).
 	 */
-	public Swagger addDefinitions(Map<String,SchemaInfo> values) {
+	public Swagger addDefinitions(Map<String,ObjectMap> values) {
 		definitions = addToMap(definitions, values);
 		return this;
 	}
@@ -660,7 +737,7 @@ public class Swagger extends SwaggerElement {
 	 * @param schema The schema that the name defines.
 	 * @return This object (for method chaining).
 	 */
-	public Swagger definition(String name, SchemaInfo schema) {
+	public Swagger definition(String name, ObjectMap schema) {
 		definitions = addToMap(definitions, name, schema);
 		return this;
 	}
@@ -683,7 +760,7 @@ public class Swagger extends SwaggerElement {
 	 * @return This object (for method chaining).
 	 */
 	public Swagger definitions(Object...values) {
-		definitions = addToMap(definitions, values, String.class, SchemaInfo.class);
+		definitions = addToMap(definitions, values, String.class, ObjectMap.class);
 		return this;
 	}
 
@@ -1281,7 +1358,34 @@ public class Swagger extends SwaggerElement {
 		if (isEmpty(ref))
 			return null;
 		if (! ref.startsWith("#/"))
-			throw new RuntimeException("Unspported reference:  '" + ref + '"');
-		return new PojoRest(this).get(ref.substring(1), c);
+			throw new RuntimeException("Unsupported reference:  '" + ref + '"');
+		try {
+			return new PojoRest(this).get(ref.substring(1), c);
+		} catch (Exception e) {
+			throw new BeanRuntimeException("Reference ''{0}'' could not be converted to type ''{1}''.", ref, c.getName()).initCause(e); 
+		}
+	}
+
+	/**
+	 * Resolves any <js>"$ref"</js> attributes in this document.
+	 * 
+	 * @return This object (for method chaining).
+	 */
+	public Swagger resolveRefs() {
+		
+		if (parameters != null)
+			for (Map.Entry<String,ParameterInfo> e : parameters.entrySet())
+				e.setValue(e.getValue().resolveRefs(this));
+		
+		if (responses != null)
+			for (Map.Entry<String,ResponseInfo> e : responses.entrySet())
+				e.setValue(e.getValue().resolveRefs(this));
+
+		if (paths != null)
+			for (Map.Entry<String,Map<String,Operation>> e : paths.entrySet())
+				for (Map.Entry<String,Operation> e2 : e.getValue().entrySet())
+					e2.setValue(e2.getValue().resolveRefs(this));
+		
+		return this;
 	}
 }
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SwaggerElement.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SwaggerElement.java
index 98dfdfd..8fa663d 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SwaggerElement.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/SwaggerElement.java
@@ -32,6 +32,13 @@ public abstract class SwaggerElement {
 	private boolean strict;
 	private Map<String,Object> extra;
 
+	SwaggerElement() {}
+	
+	SwaggerElement(SwaggerElement copyFrom) {
+		this.strict = copyFrom.strict;
+		this.extra = copyFrom.extra == null ? null : new LinkedHashMap<>(copyFrom.extra);
+	}
+	
 	/**
 	 * Returns <jk>true</jk> if contents should be validated per the Swagger spec.
 	 * 
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Tag.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Tag.java
index 620a04b..2239a6c 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Tag.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Tag.java
@@ -59,6 +59,33 @@ public class Tag extends SwaggerElement {
 		name,
 		description;
 	private ExternalDocumentation externalDocs;
+	
+	/**
+	 * Default constructor.
+	 */
+	public Tag() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Tag(Tag copyFrom) {
+		super(copyFrom);
+		
+		this.name = copyFrom.name;
+		this.description = copyFrom.description;
+		this.externalDocs = copyFrom.externalDocs == null ? null : copyFrom.externalDocs.copy();
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Tag copy() {
+		return new Tag(this);
+	}
 
 	/**
 	 * Bean property getter:  <property>name</property>.
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Xml.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Xml.java
index ee6c3a2..d0a38a3 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Xml.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/Xml.java
@@ -65,6 +65,35 @@ public class Xml extends SwaggerElement {
 		wrapped;
 
 	/**
+	 * Default constructor.
+	 */
+	public Xml() {}
+	
+	/**
+	 * Copy constructor.
+	 * 
+	 * @param copyFrom The object to copy. 
+	 */
+	public Xml(Xml copyFrom) {
+		super(copyFrom);
+		
+		this.name = copyFrom.name;
+		this.namespace = copyFrom.namespace;
+		this.prefix = copyFrom.prefix;
+		this.attribute = copyFrom.attribute;
+		this.wrapped = copyFrom.wrapped;
+	}
+	
+	/**
+	 * Make a deep copy of this object.
+	 * 
+	 * @return A deep copy of this object. 
+	 */
+	public Xml copy() {
+		return new Xml(this);
+	}
+	
+	/**
 	 * Bean property getter:  <property>name</property>.
 	 * 
 	 * <p>
diff --git a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
index b8c13f5..da757f1 100644
--- a/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
+++ b/juneau-core/juneau-dto/src/main/java/org/apache/juneau/dto/swagger/ui/SwaggerUI.java
@@ -25,11 +25,11 @@ import org.apache.juneau.transform.*;
 import org.apache.juneau.utils.*;
 
 /**
- * 
+ * Generates a Swagger-UI interface from a Swagger document.
  */
 public class SwaggerUI extends PojoSwap<Swagger,Div> {
 	
-	static final ClasspathResourceManager RM = new ClasspathResourceManager(SwaggerUI.class);
+	static final ClasspathResourceManager RESOURCES = new ClasspathResourceManager(SwaggerUI.class);
 	
 	@Override
 	public MediaType[] forMediaTypes() {
@@ -38,9 +38,12 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
 	
 	@Override
 	public Div swap(BeanSession session, Swagger s) throws Exception {
+		
+		s = s.copy().resolveRefs();
+		
 		Div outer = div(
-			style(RM.getString("SwaggerUI.css")),
-			script("text/javascript", RM.getString("SwaggerUI.js")),
+			style(RESOURCES.getString("SwaggerUI.css")),
+			script("text/javascript", RESOURCES.getString("SwaggerUI.js")),
 			header(s)
 		)._class("swagger-ui");
 		
@@ -175,7 +178,7 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
 				
 				Td parameterValue = td(
 					div(pi.getDescription())._class("description"),
-					examples(s, pi)
+					examples(pi.getSchema(), pi.getExamples())
 				)._class("parameter-value");
 				
 				parameters.child(tr(parameterKey, parameterValue));
@@ -197,7 +200,7 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
 
 				Td codeValue = td(
 					div(ri.getDescription())._class("description"),
-					examples(s, ri),
+					examples(ri.getSchema(), ri.getExamples()),
 					headers(s, ri)
 				)._class("response-value");
 				
@@ -234,33 +237,15 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
 		return headers;
 	}
 
-	private Div examples(Swagger s, ParameterInfo pi) {
-		return examples(s, resolve(s, pi.getSchema()), pi.getExamples());
-	}
-	
-	private Div examples(Swagger s, ResponseInfo ri) {
-		return examples(s, resolve(s, ri.getSchema()), ri.getExamples());
-	}
-	
-	// If SchemaInfo is a "$ref", resolve it, otherwise a no-op.
-	private SchemaInfo resolve(Swagger s, SchemaInfo si) {
-		String ref = si.getRef();
-		if (ref != null) 
-			si = s.findRef(ref, SchemaInfo.class);
-		if (si == null)
-			throw new BeanRuntimeException("Reference not found in swagger document: {0}", ref); 
-		return si;
-	}
-	
-	private Div examples(Swagger s, SchemaInfo si, Map<String,?> examples) {
-		if (examples == null)
+	private Div examples(SchemaInfo si, Map<String,?> examples) {
+		if (examples == null || si == null)
 			return null;
 		
 		Select select = (Select)select().onchange("selectExample(this)")._class("example-select");
 		select.child(option("model","model"));
 		Div div = div(select)._class("examples");
 		
-		div.child(div(getSchemaModel(s, si))._class("model active").attr("data-name", "model"));
+		div.child(div(si.copy().setExample(null))._class("model active").attr("data-name", "model"));
 
 		for (Map.Entry<String,?> e : examples.entrySet()) {
 			String name = e.getKey();
@@ -271,36 +256,4 @@ public class SwaggerUI extends PojoSwap<Swagger,Div> {
 		
 		return div;
 	}
-	
-	// Generates the model contents.
-	@SuppressWarnings("rawtypes")
-	private ObjectMap getSchemaModel(Swagger s, SchemaInfo si) {
-
-		ObjectMap m = new ObjectMap();
-
-		for (String k1 : si.keySet()) {
-			if (k1.equals("properties")) {
-				ObjectMap m2 = new ObjectMap();
-				for (Map.Entry<String,Map<String,Object>> e : si.getProperties().entrySet()) {
-					String pName = e.getKey();
-					Map<String,Object> pEntry = e.getValue();
-					if (pEntry.containsKey("$ref")) 
-						pEntry = getSchemaModel(s, s.findRef(pEntry.get("$ref").toString(), SchemaInfo.class));
-					if (pEntry.containsKey("items")) {
-						Object items = pEntry.get("items");
-						if (items instanceof Map && ((Map)items).containsKey("$ref"))
-							pEntry.put("items", getSchemaModel(s, s.findRef(((Map)items).get("$ref").toString(), SchemaInfo.class)));
-					}
-					m2.put(pName, pEntry);
-				}
-				m.put(k1, m2);
-			} else if (k1.equals("x-examples")) {
-				// Ignore these.
-			} else {
-				m.append(k1, si.get(k1, Object.class));
-			}
-		}
-		
-		return m;
-	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
index 309f669..9e92f9e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMap.java
@@ -225,8 +225,10 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 
 			if (property.equals(beanTypePropertyName))
 				return null;
-
-			throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
+			
+			p = meta.properties.get("*");
+			if (p == null)
+				throw new BeanRuntimeException(meta.c, "Bean property ''{0}'' not found.", property);
 		}
 		if (meta.beanFilter != null)
 			value = meta.beanFilter.writeProperty(this.bean, property, value);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
index b54d642..4037122 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanPropertyMeta.java
@@ -644,8 +644,8 @@ public final class BeanPropertyMeta {
 								if (! valueType.isObject()) {
 									for (Map.Entry e : (Set<Map.Entry>)valueMap.entrySet()) {
 										Object v = e.getValue();
-										if (v != null && ! valueType.getInnerClass().isInstance(v))
-											throw new BeanRuntimeException(beanMeta.c, "Cannot set property ''{0}'' of type ''{1}'' to object of type ''{2}'' because the value types in the assigned map do not match the specified ''elementClass'' attribute on the property, and the property value is currently null", name, propertyClass.getName(), findClassName(value));
+										if (v != null && ! valueType.getInnerClass().isInstance(v)) 
+											v = session.convertToType(v, valueType);
 									}
 								}
 								invokeSetter(bean, pName, valueMap);
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 114eeda..460f4cc 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
@@ -544,7 +544,7 @@ public class BeanSession extends Session {
 			// Target type is some sort of Collection
 			if (type.isCollection()) {
 				try {
-					Collection l = type.canCreateNewInstance(outer) ? (Collection)type.newInstance(outer) : new ObjectList(this);
+					Collection l = type.canCreateNewInstance(outer) ? (Collection)type.newInstance(outer) : type.isSet() ? new LinkedHashSet<>() : new ObjectList(this);
 					ClassMeta elementType = type.getElementType();
 
 					if (value.getClass().isArray())
@@ -555,6 +555,16 @@ public class BeanSession extends Session {
 							l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
 					else if (value instanceof Map)
 						l.add(elementType.isObject() ? value : convertToMemberType(l, value, elementType));
+					else if (value instanceof String) {
+						String s = value.toString();
+						if (isObjectList(s, false)) {
+							ObjectList l2 = new ObjectList(s);
+							for (Object o : l2)
+								l.add(elementType.isObject() ? o : convertToMemberType(l, o, elementType));
+						} else {
+							throw new InvalidDataConversionException(value.getClass(), type, null);
+						}
+					}
 					else if (! value.toString().isEmpty())
 						throw new InvalidDataConversionException(value.getClass(), type, null);
 					return (T)l;
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 547c07b..02427e4 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
@@ -1138,6 +1138,25 @@ public final class ClassMeta<T> implements Type {
 		return cc == COLLECTION || cc == ARRAY;
 	}
 
+
+	/**
+	 * Returns <jk>true</jk> if this class extends from {@link Set}.
+	 * 
+	 * @return <jk>true</jk> if this class extends from {@link Set}.
+	 */
+	public boolean isSet() {
+		return cc == COLLECTION && isParentClass(Set.class, innerClass);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if this class extends from {@link List}.
+	 * 
+	 * @return <jk>true</jk> if this class extends from {@link List}.
+	 */
+	public boolean isList() {
+		return cc == COLLECTION && isParentClass(List.class, innerClass);
+	}
+
 	/**
 	 * Returns <jk>true</jk> if this class is {@link Class}.
 	 * 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
index 562581e..a64ca5c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
@@ -219,7 +219,7 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 	 * @param m The map whose entries will be copied into this map.
 	 */
 	public ObjectMap(Map<?,?> m) {
-		super();
+		this();
 		for (Map.Entry<?,?> e : m.entrySet())
 			put(e.getKey().toString(), e.getValue());
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
index 5a9b510..0f758df 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Session.java
@@ -49,6 +49,16 @@ public abstract class Session {
 	}
 
 	/**
+	 * Returns <jk>true</jk> if this session has the specified property defined.
+	 * 
+	 * @param key The property key.
+	 * @return <jk>true</jk> if this session has the specified property defined.
+	 */
+	public final boolean hasProperty(String key) {
+		return properties != null && properties.containsKey(key);
+	}
+	
+	/**
 	 * Returns the session property with the specified key.
 	 * 
 	 * <p>
@@ -94,7 +104,7 @@ public abstract class Session {
 	public final <T> T getProperty(String key, Class<T> type, T...def) {
 		return getProperty(key, type, ObjectUtils.firstNonNull(def));
 	}
-
+	
 	/**
 	 * Returns the session class property with the specified name.
 	 * 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
index 5ab788b..5f3df96 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartType.java
@@ -24,7 +24,7 @@ public enum HttpPartType {
 	QUERY,
 
 	/** A form-data parameter */
-	FORM_DATA,
+	FORMDATA,
 
 	/** An HTTP header */
 	HEADER,
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
index 11d1aa6..89bca6a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializer.java
@@ -41,17 +41,17 @@ public class JsonSchemaSerializer extends JsonSerializer {
 	private static final String PREFIX = "JsonSchemaSerializer.";
 
 	/**
-	 * Configuration property:  Add descriptions.
+	 * Configuration property:  Add descriptions to types.
 	 * 
 	 * <h5 class='section'>Property:</h5>
 	 * <ul>
-	 * 	<li><b>Name:</b>  <js>"JsonSchemaSerializer.addDescriptions.ss"</js>
-	 * 	<li><b>Data type:</b>  <code>Set&lt;{@link TypeCategory}&gt;</code>
-	 * 	<li><b>Default:</b>  Empty set.
+	 * 	<li><b>Name:</b>  <js>"JsonSchemaSerializer.addDescriptionsTo.s"</js>
+	 * 	<li><b>Data type:</b>  <code>String</code>
+	 * 	<li><b>Default:</b>  Empty string.
 	 * 	<li><b>Session-overridable:</b>  <jk>true</jk>
 	 * 	<li><b>Methods:</b> 
 	 * 		<ul>
-	 * 			<li class='jm'>{@link JsonSchemaSerializerBuilder#addDescriptions(TypeCategory...)}
+	 * 			<li class='jm'>{@link JsonSchemaSerializerBuilder#addDescriptionsTo(String)}
 	 * 		</ul>
 	 * </ul>
 	 * 
@@ -60,21 +60,35 @@ public class JsonSchemaSerializer extends JsonSerializer {
 	 * Identifies which categories of types that descriptions should be automatically added to generated schemas.
 	 * <p>
 	 * The description is the result of calling {@link ClassMeta#getReadableName()}.
+	 * <p>
+	 * The format is a comma-delimited list of any of the following values:
+	 * 
+	 * <ul class='doctree'>
+	 * 	<li class='jf'>{@link TypeCategory#BEAN BEAN}
+	 * 	<li class='jf'>{@link TypeCategory#COLLECTION COLLECTION}
+	 * 	<li class='jf'>{@link TypeCategory#ARRAY ARRAY}
+	 * 	<li class='jf'>{@link TypeCategory#MAP MAP}
+	 * 	<li class='jf'>{@link TypeCategory#STRING STRING}
+	 * 	<li class='jf'>{@link TypeCategory#NUMBER NUMBER}
+	 * 	<li class='jf'>{@link TypeCategory#BOOLEAN BOOLEAN}
+	 * 	<li class='jf'>{@link TypeCategory#ANY ANY}
+	 * 	<li class='jf'>{@link TypeCategory#OTHER OTHER}
+	 * </ul>
 	 */
-	public static final String JSONSCHEMA_addDescriptions = PREFIX + "addDescriptions.ss";
+	public static final String JSONSCHEMA_addDescriptionsTo = PREFIX + "addDescriptionsTo.s";
 	
 	/**
 	 * Configuration property:  Add examples.
 	 * 
 	 * <h5 class='section'>Property:</h5>
 	 * <ul>
-	 * 	<li><b>Name:</b>  <js>"JsonSchemaSerializer.addExamples.ss"</js>
-	 * 	<li><b>Data type:</b>  <code>Set&lt;{@link TypeCategory}&gt;</code>
-	 * 	<li><b>Default:</b>  Empty set.
+	 * 	<li><b>Name:</b>  <js>"JsonSchemaSerializer.addExamplesTo.s"</js>
+	 * 	<li><b>Data type:</b>  <code>String</code>
+	 * 	<li><b>Default:</b>  Empty string.
 	 * 	<li><b>Session-overridable:</b>  <jk>true</jk>
 	 * 	<li><b>Methods:</b> 
 	 * 		<ul>
-	 * 			<li class='jm'>{@link JsonSchemaSerializerBuilder#addExamples(TypeCategory...)}
+	 * 			<li class='jm'>{@link JsonSchemaSerializerBuilder#addExamplesTo(String)}
 	 * 		</ul>
 	 * </ul>
 	 * 
@@ -88,8 +102,23 @@ public class JsonSchemaSerializer extends JsonSerializer {
 	 * 	<li class='ja'>{@link Example}
 	 * 	<li class='jf'>{@link BeanContext#BEAN_examples}
 	 * </ul>
+	 * 
+	 * <p>
+	 * The format is a comma-delimited list of any of the following values:
+	 * 
+	 * <ul class='doctree'>
+	 * 	<li class='jf'>{@link TypeCategory#BEAN BEAN}
+	 * 	<li class='jf'>{@link TypeCategory#COLLECTION COLLECTION}
+	 * 	<li class='jf'>{@link TypeCategory#ARRAY ARRAY}
+	 * 	<li class='jf'>{@link TypeCategory#MAP MAP}
+	 * 	<li class='jf'>{@link TypeCategory#STRING STRING}
+	 * 	<li class='jf'>{@link TypeCategory#NUMBER NUMBER}
+	 * 	<li class='jf'>{@link TypeCategory#BOOLEAN BOOLEAN}
+	 * 	<li class='jf'>{@link TypeCategory#ANY ANY}
+	 * 	<li class='jf'>{@link TypeCategory#OTHER OTHER}
+	 * </ul>
 	 */
-	public static final String JSONSCHEMA_addExamples = PREFIX + "addExamples.ss";
+	public static final String JSONSCHEMA_addExamplesTo = PREFIX + "addExamplesTo.s";
 	
 	/**
 	 * Configuration property:  Allow nested descriptions.
@@ -295,7 +324,7 @@ public class JsonSchemaSerializer extends JsonSerializer {
 
 	final boolean useBeanDefs, allowNestedExamples, allowNestedDescriptions;
 	final BeanDefMapper beanDefMapper;
-	final Set<TypeCategory> addExamples, addDescriptions;
+	final Set<TypeCategory> addExamplesTo, addDescriptionsTo;
 	final Map<String,ObjectMap> defaultSchemas;
 
 	/**
@@ -317,8 +346,8 @@ public class JsonSchemaSerializer extends JsonSerializer {
 		allowNestedExamples = getBooleanProperty(JSONSCHEMA_allowNestedExamples, false);
 		allowNestedDescriptions = getBooleanProperty(JSONSCHEMA_allowNestedDescriptions, false);
 		beanDefMapper = getInstanceProperty(JSONSCHEMA_beanDefMapper, BeanDefMapper.class, BasicBeanDefMapper.class);
-		addExamples = getSetProperty(JSONSCHEMA_addExamples, TypeCategory.class, Collections.<TypeCategory>emptySet());
-		addDescriptions = getSetProperty(JSONSCHEMA_addDescriptions, TypeCategory.class, Collections.<TypeCategory>emptySet());
+		addExamplesTo = TypeCategory.parse(getStringProperty(JSONSCHEMA_addExamplesTo, null));
+		addDescriptionsTo = TypeCategory.parse(getStringProperty(JSONSCHEMA_addDescriptionsTo, null));
 		defaultSchemas = getMapProperty(JSONSCHEMA_defaultSchemas, ObjectMap.class);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerBuilder.java
index 594a270..0a5680e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerBuilder.java
@@ -63,7 +63,7 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
 	 * 
 	 * <h5 class='section'>See Also:</h5>
 	 * <ul>
-	 * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addDescriptions}
+	 * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addDescriptionsTo}
 	 * </ul>
 	 * 
 	 * @param value 
@@ -71,8 +71,8 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
 	 * 	<br>The default is <jk>false</jk>.
 	 * @return This object (for method chaining).
 	 */
-	public JsonSchemaSerializerBuilder addDescriptions(TypeCategory...value) {
-		return set(JSONSCHEMA_addDescriptions, value);
+	public JsonSchemaSerializerBuilder addDescriptionsTo(String value) {
+		return set(JSONSCHEMA_addDescriptionsTo, value);
 	}
 	
 	/**
@@ -90,7 +90,7 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
 	 * 
 	 * <h5 class='section'>See Also:</h5>
 	 * <ul>
-	 * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamples}
+	 * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamplesTo}
 	 * </ul>
 	 * 
 	 * @param value 
@@ -98,8 +98,8 @@ public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
 	 * 	<br>The default is <jk>false</jk>.
 	 * @return This object (for method chaining).
 	 */
-	public JsonSchemaSerializerBuilder addExamples(TypeCategory...value) {
-		return set(JSONSCHEMA_addExamples, value);
+	public JsonSchemaSerializerBuilder addExamplesTo(String value) {
+		return set(JSONSCHEMA_addExamplesTo, value);
 	}
 	
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerSession.java
index 23b6a82..ea39466 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaSerializerSession.java
@@ -39,7 +39,7 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 	private final BeanDefMapper beanDefMapper;
 	private final Map<String,ObjectMap> defs;
 	private final Map<String,ObjectMap> defaultSchemas;
-	private final Set<TypeCategory> addExamples, addDescriptions;
+	private final Set<TypeCategory> addExamplesTo, addDescriptionsTo;
 
 	/**
 	 * Create a new session using properties specified in the context.
@@ -60,8 +60,8 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 		allowNestedDescriptions = getProperty(JSONSCHEMA_allowNestedDescriptions, boolean.class, ctx.allowNestedDescriptions);
 		beanDefMapper = getInstanceProperty(JSONSCHEMA_beanDefMapper, BeanDefMapper.class, ctx.beanDefMapper);
 		defaultSchemas = getProperty(JSONSCHEMA_defaultSchemas, Map.class, ctx.defaultSchemas);
-		addExamples = getProperty(JSONSCHEMA_addExamples, Set.class, ctx.addExamples);
-		addDescriptions = getProperty(JSONSCHEMA_addDescriptions, Set.class, ctx.addDescriptions);
+		addExamplesTo = hasProperty(JSONSCHEMA_addExamplesTo) ? TypeCategory.parse(getProperty(JSONSCHEMA_addExamplesTo, String.class)) : ctx.addExamplesTo;
+		addDescriptionsTo = hasProperty(JSONSCHEMA_addDescriptionsTo) ? TypeCategory.parse(getProperty(JSONSCHEMA_addDescriptionsTo, String.class)) : ctx.addDescriptionsTo;
 		defs = useBeanDefs ? new LinkedHashMap<String,ObjectMap>() : null;
 	}
 
@@ -258,7 +258,7 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 	
 	private Object getExample(ClassMeta<?> sType, TypeCategory t, boolean exampleAdded) throws Exception {
 		boolean canAdd = allowNestedExamples || ! exampleAdded;
-		if (canAdd && (addExamples.contains(t) || addExamples.contains(ANY))) {
+		if (canAdd && (addExamplesTo.contains(t) || addExamplesTo.contains(ANY))) {
 			Object example = sType.getExample(this);
 			if (example != null)
 				return JsonParser.DEFAULT.parse(serializeJson(example), Object.class);
@@ -268,7 +268,7 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 	
 	private Object getDescription(ClassMeta<?> sType, TypeCategory t, boolean descriptionAdded) {
 		boolean canAdd = allowNestedDescriptions || ! descriptionAdded;
-		if (canAdd && (addDescriptions.contains(t) || addDescriptions.contains(ANY)))
+		if (canAdd && (addDescriptionsTo.contains(t) || addDescriptionsTo.contains(ANY)))
 			return sType.getReadableName();
 		return null;
 	}
@@ -328,4 +328,13 @@ public class JsonSchemaSerializerSession extends JsonSerializerSession {
 			defs.put(id, def);
 		return this;
 	}
+
+	/**
+	 * Returns the value of the {@link JsonSchemaSerializer#JSONSCHEMA_useBeanDefs} setting.
+	 * 
+	 * @return The value of the {@link JsonSchemaSerializer#JSONSCHEMA_useBeanDefs} setting.
+	 */
+	public boolean isUseBeanDefs() {
+		return useBeanDefs;
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java
index 3274e10..15d8393 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java
@@ -12,13 +12,16 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.jsonschema;
 
+import java.util.*;
+
+import org.apache.juneau.internal.*;
 
 /**
  * Represents possible values for the following properties:
  * 
  * <ul class='doctree'>
- * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamples}
- * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addDescriptions}
+ * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamplesTo}
+ * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addDescriptionsTo}
  * </ul>
  */
 public enum TypeCategory {
@@ -52,4 +55,19 @@ public enum TypeCategory {
 
 	/** Anything */
 	ANY;
+	
+	/**
+	 * Parses a comma-delimited list of values into a set of {@link TypeCategory} values.
+	 * 
+	 * @param s The comma-delimited string.
+	 * @return A comma-delimited list of values into a set of {@link TypeCategory} values. 
+	 */
+	public static Set<TypeCategory> parse(String s) {
+		if (s == null || s.isEmpty())
+			return Collections.emptySet();
+		Set<TypeCategory> set = new LinkedHashSet<>();
+		for (String ss : StringUtils.split(s))
+			set.add(valueOf(ss.toUpperCase()));
+		return set;
+	}
 }
diff --git a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
index 3bb7a72..d17524c 100644
--- a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/Var.java
@@ -137,7 +137,7 @@ public abstract class Var {
 	 * @param session The session object used for a single instance of a string resolution.
 	 * @param arg The inside argument of the variable.
 	 * @return The resolved value.
-	 * @throws Exception Any thrown exception will be serialized as <js>"{exceptionMessage}"</js>
+	 * @throws Exception Any exception can be thrown.
 	 */
 	protected String doResolve(VarResolverSession session, String arg) throws Exception {
 		return resolve(session, arg);
@@ -149,7 +149,7 @@ public abstract class Var {
 	 * @param session The session object used for a single instance of a var resolution.
 	 * @param arg The inside argument of the variable.
 	 * @return The resolved value.
-	 * @throws Exception Any thrown exception will be serialized as <js>"{exceptionMessage}"</js>
+	 * @throws Exception Any exception can be thrown.
 	 */
 	public abstract String resolve(VarResolverSession session, String arg) throws Exception;
 
@@ -159,7 +159,7 @@ public abstract class Var {
 	 * @param session The session object used for a single instance of a var resolution.
 	 * @param w The writer to send the resolved value to.
 	 * @param arg The inside argument of the variable.
-	 * @throws Exception Any thrown exception will be serialized as <js>"{exceptionMessage}"</js>
+	 * @throws Exception Any exception can be thrown.
 	 */
 	public abstract void resolveTo(VarResolverSession session, Writer w, String arg) throws Exception;
 }
diff --git a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
index 358756c..553a4a5 100644
--- a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverContext.java
@@ -48,7 +48,7 @@ public class VarResolverContext {
 		Map<String,Var> m = new ConcurrentSkipListMap<>();
 		for (Class<?> c : vars) {
 			if (! isParentClass(Var.class, c))
-				throw new RuntimeException("Invalid variable class.  Must extend from Var");
+				throw new VarResolverException("Invalid variable class.  Must extend from Var");
 			Var v = newInstance(Var.class, c);
 			m.put(v.getName(), v);
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverException.java
similarity index 63%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java
copy to juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverException.java
index 3274e10..b11b066 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/TypeCategory.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverException.java
@@ -10,46 +10,39 @@
 // * "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.jsonschema;
+package org.apache.juneau.svl;
 
+import static org.apache.juneau.internal.StringUtils.*;
+
+import java.text.*;
+
+import org.apache.juneau.*;
 
 /**
- * Represents possible values for the following properties:
- * 
- * <ul class='doctree'>
- * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addExamples}
- * 	<li class='jf'>{@link JsonSchemaSerializer#JSONSCHEMA_addDescriptions}
- * </ul>
+ * Exception that occurs during a var resolver session.
  */
-public enum TypeCategory {
+public class VarResolverException extends FormattedRuntimeException {
+	private static final long serialVersionUID = 1L;
 
-	/** Beans */
-	BEAN, 
-	
-	/** Map */
-	MAP, 
-	
-	/** List/Set */
-	COLLECTION, 
-	
-	/** Array */
-	ARRAY, 
-	
-	/** Boolean (including primitives) */
-	BOOLEAN, 
-	
-	/** Short/Integer/Long/Float/Double (including primitives) */
-	NUMBER, 
-	
-	/** String/CharSequence/Character */
-	STRING, 
-	
-	/** Enums */
-	ENUM, 
-	
-	/** Anything else */
-	OTHER,
+	/**
+	 * Constructor.
+	 * 
+	 * @param message The {@link MessageFormat}-style message.
+	 * @param args Optional {@link MessageFormat}-style arguments.
+	 */
+	public VarResolverException(String message, Object...args) {
+		super(format(message, args));
+	}
 
-	/** Anything */
-	ANY;
+	/**
+	 * Constructor.
+	 * 
+	 * @param causedBy The cause of this exception.
+	 * @param message The {@link MessageFormat}-style message.
+	 * @param args Optional {@link MessageFormat}-style arguments.
+	 */
+	public VarResolverException(Throwable causedBy, String message, Object...args) {
+		this(message, args);
+		initCause(causedBy);
+	}
 }
diff --git a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
index 44092b1..a553b0d 100644
--- a/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
+++ b/juneau-core/juneau-svl/src/main/java/org/apache/juneau/svl/VarResolverSession.java
@@ -18,8 +18,6 @@ import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
-import org.apache.juneau.*;
-
 /**
  * A var resolver session that combines a {@link VarResolver} with one or more session objects.
  * 
@@ -106,9 +104,10 @@ public class VarResolverSession {
 					if (s == null)
 						s = "";
 					return (v.allowRecurse() ? resolve(s) : s);
+				} catch (VarResolverException e) {
+					throw e;
 				} catch (Exception e) {
-					e.printStackTrace();
-					return '{' + e.getLocalizedMessage() + '}';
+					throw new VarResolverException(e, "Problem occurred resolving variable ''{0}''", var); 
 				}
 			}
 			return s;
@@ -162,8 +161,10 @@ public class VarResolverSession {
 				for (Object o2 : c)
 					c2.add(resolve(o2));
 				return (T)c2;
+			} catch (VarResolverException e) {
+				throw e;
 			} catch (Exception e) {
-				return o;
+				throw new VarResolverException(e, "Problem occurred resolving collection."); 
 			}
 		}
 		if (o instanceof Map) {
@@ -175,8 +176,10 @@ public class VarResolverSession {
 				for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
 					m2.put(e.getKey(), resolve(e.getValue()));
 				return (T)m2;
+			} catch (VarResolverException e) {
+				throw e;
 			} catch (Exception e) {
-				return o;
+				throw new VarResolverException(e, "Problem occurred resolving map."); 
 			}
 		}
 		return o;
@@ -345,8 +348,10 @@ public class VarResolverSession {
 										replacement = resolve(replacement);
 									out.append(replacement);
 								}
+							} catch (VarResolverException e) {
+								throw e;
 							} catch (Exception e) {
-								out.append('{').append(e.getLocalizedMessage()).append('}');
+								throw new VarResolverException(e, "Problem occurred resolving variable ''{0}''", varType); 
 							}
 							x = i+1;
 						}
@@ -377,7 +382,7 @@ public class VarResolverSession {
 	 * @return 
 	 * 	The session object.  
 	 * 	<br>Never <jk>null</jk>.
-	 * @throws RuntimeException If session object with specified name does not exist.
+	 * @throws VarResolverException If session object with specified name does not exist.
 	 */
 	@SuppressWarnings("unchecked")
 	public <T> T getSessionObject(Class<T> c, String name) {
@@ -389,11 +394,11 @@ public class VarResolverSession {
 				t = (T)sessionObjects.get(name);
 			}
 		} catch (Exception e) {
-			throw new FormattedRuntimeException(e,
+			throw new VarResolverException(e,
 				"Session object ''{0}'' or context object ''SvlContext.{0}'' could not be converted to type ''{1}''.", name, c);
 		}
 		if (t == null)
-			throw new FormattedRuntimeException(
+			throw new VarResolverException(
 				"Session object ''{0}'' or context object ''SvlContext.{0}'' not found.", name);
 		return t;
 	}
diff --git a/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json b/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json
index 1501eca..37f6ce6 100644
--- a/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json
+++ b/juneau-examples/juneau-examples-rest/src/main/resources/org/apache/juneau/examples/rest/petstore/PetStoreResource.json
@@ -72,96 +72,5 @@
 			"name": "api_key",
 			"in": "header"
 		}
-	},
-	"definitions": {
-		"Order": {
-			"example": {
-				"id": 123,
-				"petId": 123,
-				"quantity": 1,
-				"shipDate": "2018-01-01",
-				"status": "PLACED"
-			}
-		},
-		"User": {
-			"type": "object",
-			"properties": {
-				"id": {
-					"type": "integer",
-					"format": "int64"
-				},
-				"username": {
-					"type": "string"
-				},
-				"firstName": {
-					"type": "string"
-				},
-				"lastName": {
-					"type": "string"
-				},
-				"email": {
-					"type": "string"
-				},
-				"password": {
-					"type": "string"
-				},
-				"phone": {
-					"type": "string"
-				},
-				"userStatus": {
-					"type": "integer",
-					"format": "int32",
-					"description": "User Status"
-				}
-			},
-			"xml": {
-				"name": "User"
-			}
-		},
-		"Category": {
-			"type": "object",
-			"properties": {
-				"id": {
-					"type": "integer",
-					"format": "int64"
-				},
-				"name": {
-					"type": "string"
-				}
-			},
-			"xml": {
-				"name": "Category"
-			}
-		},
-		"Tag": {
-			"type": "object",
-			"properties": {
-				"id": {
-					"type": "integer",
-					"format": "int64"
-				},
-				"name": {
-					"type": "string"
-				}
-			},
-			"xml": {
-				"name": "Tag"
-			}
-		},
-		"ApiResponse": {
-			"type": "object",
-			"properties": {
-				"code": {
-					"type": "integer",
-					"format": "int32"
-				},
-				"type": {
-					"type": "string"
-				},
-				"message": {
-					"type": "string"
-				}
-			}
-		}
 	}
 }
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
index 0cf3796..decd32b 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
@@ -53,6 +53,6 @@ public final class SerializedNameValuePair implements NameValuePair {
 
 	@Override /* NameValuePair */
 	public String getValue() {
-		return serializer.serialize(HttpPartType.FORM_DATA, value);
+		return serializer.serialize(HttpPartType.FORMDATA, value);
 	}
 }
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
index eb1155e..6aec374 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestInfoProvider.java
@@ -15,7 +15,10 @@ package org.apache.juneau.rest;
 import static org.apache.juneau.internal.ReflectionUtils.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.rest.RestParamType.*;
+import static org.apache.juneau.serializer.OutputStreamSerializer.*;
+import static org.apache.juneau.serializer.WriterSerializer.*;
 
+import java.lang.reflect.*;
 import java.lang.reflect.Method;
 import java.util.*;
 import java.util.concurrent.*;
@@ -23,10 +26,13 @@ import java.util.concurrent.*;
 import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
+import org.apache.juneau.jsonschema.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.serializer.*;
 import org.apache.juneau.svl.*;
 import org.apache.juneau.utils.*;
 
@@ -125,6 +131,7 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 		JsonParser jp = JsonParser.DEFAULT;
 		MessageBundle mb = context.getMessages();
 		Class<?> c = context.getResource().getClass();
+		JsonSchemaSerializerSession js = req.getContext().getJsonSchemaSerializer().createSession();
 		
 		// Load swagger JSON from classpath.
 		ObjectMap omSwagger = context.getClasspathResource(ObjectMap.class, MediaType.JSON, getClass().getSimpleName() + ".json", locale);
@@ -214,10 +221,10 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 		s = mb.findFirstString(locale, "externalDocs");
 		if (s != null) 
 			externalDocs.putAll(jp.parse(vr.resolve(s), ObjectMap.class));
-		
-//		JsonSchemaDefinitions defs = new JsonSchemaDefinitions();
-//		for (String defId : definitions.keySet()) 
-//			defs.put(defId, definitions.getObjectMap(defId));
+
+		// Load our existing bean definitions into our session.
+		for (String defId : definitions.keySet()) 
+			js.addBeanDef(defId, definitions.getObjectMap(defId));
 		
 		// Iterate through all the @RestMethod methods.
 		for (RestJavaMethod sm : context.getCallMethods().values()) {
@@ -374,8 +381,8 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 				if ((in == BODY || in == PATH) && ! param.containsKeyNotEmpty("required"))
 					param.put("required", true);
 				
-//				param.put("schema", getSchema(req, param.getObjectMap("schema", true), defs, mp.getType()));
-//				addXExamples(req, param, in.toString(), defs, mp.getType());
+				param.put("schema", getSchema(req, param.getObjectMap("schema", true), js, mp.getType()));
+				addXExamples(req, sm, omSwagger, param, in.toString(), js, mp.getType());
 			}
 			
 			if (! paramMap.isEmpty())
@@ -407,10 +414,10 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 			if (! responses.containsKey("200"))
 				responses.put("200", new ObjectMap().append("description", "Success"));
 			
-//			ObjectMap okResponse = responses.getObjectMap("200");
-//			
-//			okResponse.put("schema", getSchema(req, okResponse.getObjectMap("schema", true), defs, m.getGenericReturnType()));
-//			addXExamples(req, okResponse, "ok", defs, m.getGenericReturnType());
+			ObjectMap okResponse = responses.getObjectMap("200");
+			
+			okResponse.put("schema", getSchema(req, okResponse.getObjectMap("schema", true), js, m.getGenericReturnType()));
+			addXExamples(req, sm, omSwagger, okResponse, "ok", js, m.getGenericReturnType());
 			
 			if (responses.isEmpty())
 				op.remove("responses");
@@ -430,7 +437,7 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 			}
 		}
 		
-//		definitions.putAll(defs);
+		definitions.putAll(js.getBeanDefs());
 		
 		if (definitions.isEmpty())
 			omSwagger.remove("definitions");		
@@ -445,92 +452,82 @@ public class BasicRestInfoProvider implements RestInfoProvider {
 		}
 		
 		swaggers.get(locale).put(hashCode, swagger);
+
+//		JsonSerializer.DEFAULT_LAX_READABLE.println(swagger);
 		
 		return swagger;
 	}
 	
-//	private ObjectMap getSchema(RestRequest req, ObjectMap schema, JsonSchemaDefinitions defs, Type type) throws Exception {
-//		BeanSession bs = req.getBeanSession();
-//		ClassMeta<?> cm = bs.getClassMeta(type);
-//		
-//		if (schema.containsKey("type") || schema.containsKey("$ref")) 
-//			return schema;
-//		if (cm.isBean()) {
-//			schema.put("$ref", defs.getURI(cm));
-//		} else if (cm.isMap() || cm.isCollectionOrArray()) {
-//			schema.putAll(JsonSchemaUtils.getSchema(bs, defs, cm));
-//			Object example = getExample(req, cm, schema.get("example"));
-//			if (example != null)
-//				schema.put("example", example);
-//		} else {
-//			schema.putAll(JsonSchemaUtils.getSchema(bs, defs, cm));
-//		}
-//		return schema;
-//	}
-//	
-//	private void addXExamples(RestRequest req, ObjectMap m, String in, JsonSchemaDefinitions defs, Type type) throws Exception {
-//		
-//		ClassMeta<?> cm = req.getBeanSession().getClassMeta(type);
-//		Object example = defs.getExample(cm);
-//		if (example == null)
-//			return;
-//		
-//		List<MediaType> mediaTypes = "ok".equals("in") ? req.getSerializers().getSupportedMediaTypes() : req.getParsers().getSupportedMediaTypes();
-//		
-//		if ("ok".equals(in) || "body".equals(in)) {
-//			ObjectMap examples = new ObjectMap();
-//			ObjectMap sprops = new ObjectMap().append(WSERIALIZER_useWhitespace, true).append(OSSERIALIZER_binaryFormat, BinaryFormat.SPACED_HEX);
-//			
-//			for (MediaType mt : mediaTypes) {
-//				if (mt != MediaType.HTML) {
-//					Serializer s2 = req.getSerializers().getSerializer(mt);
-//					if (s2 != null) {
-//						SerializerSessionArgs args = new SerializerSessionArgs(sprops, req.getJavaMethod(), req.getLocale(), null, mt, req.getUriContext());
-//						String eVal = s2.createSession(args).serializeToString(example);
-//						examples.put(s2.getMediaTypes()[0].toString(), eVal);
-//					}
-//				}
-//			}
-//			m.put("x-examples", examples);
-//			
-//		} else {
-//			m.put("example", example);
-//		}
-//		
-//	}
-//	
-//	@SuppressWarnings({ "rawtypes", "unchecked" })
-//	private Object getExample(RestRequest req, ClassMeta<?> cm, Object jsonExample) {
-//		try {
-//			BeanSession bs = req.getBeanSession();
-//			
-//			if (cm.isMapOrBean()) {
-//				if (jsonExample instanceof ObjectMap)
-//					return ((ObjectMap)jsonExample).cast(cm);
-//				return cm.getExample(bs);
-//			} else if (cm.isCollectionOrArray()) {
-//				if (jsonExample instanceof ObjectList)
-//					return ((ObjectList)jsonExample).cast(cm);
-//				Object e = cm.getExample(bs);
-//				if (e != null)
-//					return e;
-//				e = cm.getElementType().getExample(bs);
-//				if (e != null) {
-//					if (cm.isCollection()) {
-//						Collection c = (Collection)(cm.canCreateNewInstance() ? cm.newInstance() : new ObjectList());
-//						c.add(e);
-//						return c;
-//					}
-//					Object array = Array.newInstance(cm.getInnerClass(), 1);
-//					Array.set(array, 0, e);
-//					return array;
-//				}
-//			} else {
-//				return jsonExample;
-//			}
-//		} catch (Exception e) { /* Ignore */ }
-//		return null;
-//	}
+	private ObjectMap getSchema(RestRequest req, ObjectMap schema, JsonSchemaSerializerSession js, Type type) throws Exception {
+		BeanSession bs = req.getBeanSession();
+		ClassMeta<?> cm = bs.getClassMeta(type);
+		
+		if (schema.containsKey("type") || schema.containsKey("$ref")) 
+			return schema;
+		
+		if (cm.isBean() && js.isUseBeanDefs()) 
+			schema.put("$ref", js.getBeanDefUri(cm));
+		else
+			schema.putAll(js.getSchema(cm));
+
+		return schema;
+	}
+	
+	
+	private void addXExamples(RestRequest req, RestJavaMethod sm, ObjectMap swagger, ObjectMap m, String in, JsonSchemaSerializerSession js, Type type) throws Exception {
+		
+		ObjectMap schema = resolve(m.getObjectMap("schema"));
+		if (schema == null)
+			return;
+
+		Object example = schema.get("example", Object.class);
+		if (example == null)
+			return;
+		
+		boolean isOk = "ok".equals(in), isBody = "body".equals(in);
+		
+		example = JsonParser.DEFAULT.parse(JsonSerializer.DEFAULT.serialize(example), type);
+		
+		String examplesKey = isOk ? "examples" : "x-examples";  // Parameters don't have an examples attribute.
+
+		ObjectMap examples = schema.getObjectMap(examplesKey);
+		if (examples == null)
+			examples = new ObjectMap();
+
+		if (isOk || isBody) {
+			List<MediaType> mediaTypes = isOk ? sm.getSerializers().getSupportedMediaTypes() : sm.getParsers().getSupportedMediaTypes();
+			ObjectMap sprops = new ObjectMap().append(WSERIALIZER_useWhitespace, true).append(OSSERIALIZER_binaryFormat, BinaryFormat.SPACED_HEX);
+			
+			for (MediaType mt : mediaTypes) {
+				if (mt != MediaType.HTML) {
+					Serializer s2 = sm.getSerializers().getSerializer(mt);
+					if (s2 != null) {
+						SerializerSessionArgs args = new SerializerSessionArgs(sprops, req.getJavaMethod(), req.getLocale(), null, mt, req.getUriContext());
+						String eVal = s2.createSession(args).serializeToString(example);
+						examples.put(s2.getMediaTypes()[0].toString(), eVal);
+					}
+				}
+			}
+		} else {
+			examples.put("example", req.getPartSerializer().serialize(HttpPartType.valueOf(in.toUpperCase()), example));
+		}
+		
+		if (! examples.isEmpty())
+			m.put(examplesKey, examples);
+	}
+	
+	private ObjectMap resolve(ObjectMap m) {
+		if (m == null)
+			return null;
+		if (m.containsKey("$ref")) {
+			String ref = m.getString("$ref");
+			if (ref.startsWith("#/definitions/")) {
+				ref = ref.substring(1);
+				return m.getAt(ref, ObjectMap.class);
+			}
+		}
+		return m;
+	}
 	
 	private static class SwaggerException extends ParseException {
 		private static final long serialVersionUID = 1L;
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
index 4495c08..7c9a5d0 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/BasicRestServlet.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.rest;
 
 import static org.apache.juneau.http.HttpMethodName.*;
+import static org.apache.juneau.jsonschema.JsonSchemaSerializer.*;
 
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.dto.swagger.ui.*;
@@ -174,6 +175,13 @@ import org.apache.juneau.xmlschema.*;
 	),
 	pojoSwaps={
 		SwaggerUI.class
+	},
+	properties={
+		@Property(name=JSONSCHEMA_addDescriptionsTo, value="bean,collection,array,map,enum"),
+		@Property(name=JSONSCHEMA_addExamplesTo, value="bean,collection,array,map"),
+	},
+	flags={ 
+		JSONSCHEMA_useBeanDefs
 	}
 )
 public abstract class BasicRestServlet extends RestServlet implements BasicRestConfig {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
index 1374bde..831b5d8 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RequestFormData.java
@@ -493,7 +493,7 @@ public class RequestFormData extends LinkedHashMap<String,String[]> {
 		try {
 			if (parser == null)
 				parser = this.parser;
-			return parser.parse(HttpPartType.FORM_DATA, val, c);
+			return parser.parse(HttpPartType.FORMDATA, val, c);
 		} catch (Exception e) {
 			throw new ParseException(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 f4d5258..8f9d611 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
@@ -2763,6 +2763,7 @@ public final class RestContext extends BeanContext {
 	private final ParserGroup parsers;
 	private final HttpPartSerializer partSerializer;
 	private final HttpPartParser partParser;
+	private final JsonSchemaSerializer jsonSchemaSerializer;
 	private final EncoderGroup encoders;
 	private final List<MediaType>
 		consumes,
@@ -2893,6 +2894,7 @@ public final class RestContext extends BeanContext {
 			parsers = ParserGroup.create().append(getInstanceArrayProperty(REST_parsers, Parser.class, new Parser[0], true, resource, ps)).build();
 			partSerializer = getInstanceProperty(REST_partSerializer, HttpPartSerializer.class, SimpleUonPartSerializer.class, true, resource, ps);
 			partParser = getInstanceProperty(REST_partSerializer, HttpPartParser.class, UonPartParser.class, true, resource, ps);
+			jsonSchemaSerializer = new JsonSchemaSerializer(ps);
 			encoders = new EncoderGroupBuilder().append(getInstanceArrayProperty(REST_encoders, Encoder.class, new Encoder[0], true, resource, ps)).build();
 			beanContext = BeanContext.create().apply(ps).build();
 
@@ -3926,6 +3928,17 @@ public final class RestContext extends BeanContext {
 	}
 
 	/**
+	 * Returns the JSON-Schema serializer associated with this resource.
+	 * 
+	 * @return 
+	 * 	The JSON-Schema serializer associated with this resource.  
+	 * 	<br>Never <jk>null</jk>.
+	 */
+	public JsonSchemaSerializer getJsonSchemaSerializer() {
+		return jsonSchemaSerializer;
+	}
+
+	/**
 	 * Returns the HTTP-part serializer associated with this resource.
 	 * 
 	 * <h5 class='section'>See Also:</h5>
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
index 390e3e6..f600a0f 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestJavaMethod.java
@@ -568,6 +568,42 @@ public class RestJavaMethod implements Comparable<RestJavaMethod>  {
 		return 0;
 	}
 
+	/**
+	 * Bean property getter:  <property>serializers</property>.
+	 *
+	 * @return The value of the <property>serializers</property> property on this bean, or <jk>null</jk> if it is not set.
+	 */
+	public SerializerGroup getSerializers() {
+		return serializers;
+	}
+
+	/**
+	 * Bean property getter:  <property>parsers</property>.
+	 *
+	 * @return The value of the <property>parsers</property> property on this bean, or <jk>null</jk> if it is not set.
+	 */
+	public ParserGroup getParsers() {
+		return parsers;
+	}
+
+	/**
+	 * Bean property getter:  <property>partSerializer</property>.
+	 *
+	 * @return The value of the <property>partSerializer</property> property on this bean, or <jk>null</jk> if it is not set.
+	 */
+	public HttpPartSerializer getPartSerializer() {
+		return partSerializer;
+	}
+
+	/**
+	 * Bean property getter:  <property>partParser</property>.
+	 *
+	 * @return The value of the <property>partParser</property> property on this bean, or <jk>null</jk> if it is not set.
+	 */
+	public HttpPartParser getPartParser() {
+		return partParser;
+	}
+
 	@Override /* Object */
 	public boolean equals(Object o) {
 		if (! (o instanceof RestJavaMethod))

-- 
To stop receiving notification emails like this one, please contact
jamesbognar@apache.org.