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 2022/01/02 23:17:56 UTC

[juneau] branch master updated: Make it easier to create custom serializers and parsers.

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 819396a  Make it easier to create custom serializers and parsers.
819396a is described below

commit 819396a3389bd1b302b379ef32d7d2304af92679
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Sun Jan 2 18:17:03 2022 -0500

    Make it easier to create custom serializers and parsers.
---
 .../main/java/org/apache/juneau/config/Config.java |  11 +-
 .../apache/juneau/config/store/ClasspathStore.java |   7 +-
 .../apache/juneau/config/store/ConfigStore.java    |   5 +-
 .../org/apache/juneau/config/store/FileStore.java  |   7 +-
 .../apache/juneau/config/store/MemoryStore.java    |   7 +-
 .../main/java/org/apache/juneau/jena/N3Parser.java |   2 +-
 .../java/org/apache/juneau/jena/N3Serializer.java  |   2 +-
 .../java/org/apache/juneau/jena/NTripleParser.java |   2 +-
 .../org/apache/juneau/jena/NTripleSerializer.java  |   2 +-
 .../java/org/apache/juneau/jena/RdfParser.java     |  13 +-
 .../java/org/apache/juneau/jena/RdfSerializer.java |  13 +-
 .../apache/juneau/jena/RdfXmlAbbrevSerializer.java |   2 +-
 .../java/org/apache/juneau/jena/RdfXmlParser.java  |   2 +-
 .../org/apache/juneau/jena/RdfXmlSerializer.java   |   2 +-
 .../java/org/apache/juneau/jena/TurtleParser.java  |   2 +-
 .../org/apache/juneau/jena/TurtleSerializer.java   |   2 +-
 .../main/java/org/apache/juneau/BeanContext.java   |   7 +-
 .../java/org/apache/juneau/BeanContextable.java    |   5 +-
 .../org/apache/juneau/BeanTraverseContext.java     |   5 +-
 .../src/main/java/org/apache/juneau/Context.java   |  97 ++++++++-----
 .../main/java/org/apache/juneau/csv/CsvParser.java |  13 +-
 .../java/org/apache/juneau/csv/CsvSerializer.java  |  13 +-
 .../org/apache/juneau/html/HtmlDocSerializer.java  |  13 +-
 .../java/org/apache/juneau/html/HtmlParser.java    |  13 +-
 .../juneau/html/HtmlSchemaDocSerializer.java       |   7 +-
 .../apache/juneau/html/HtmlSchemaSerializer.java   |  19 ++-
 .../org/apache/juneau/html/HtmlSerializer.java     |  17 ++-
 .../juneau/html/HtmlStrippedDocSerializer.java     |  13 +-
 .../apache/juneau/httppart/SimplePartParser.java   |  16 ++-
 .../juneau/httppart/SimplePartSerializer.java      |  15 ++-
 .../java/org/apache/juneau/json/JsonParser.java    |  15 ++-
 .../apache/juneau/json/JsonSchemaSerializer.java   |  19 ++-
 .../org/apache/juneau/json/JsonSerializer.java     |  17 ++-
 .../org/apache/juneau/json/SimpleJsonParser.java   |   2 +-
 .../apache/juneau/json/SimpleJsonSerializer.java   |   4 +-
 .../juneau/jsonschema/JsonSchemaGenerator.java     |  13 +-
 .../org/apache/juneau/msgpack/MsgPackParser.java   |  17 ++-
 .../apache/juneau/msgpack/MsgPackSerializer.java   |  17 ++-
 .../java/org/apache/juneau/oapi/OpenApiParser.java |  13 +-
 .../org/apache/juneau/oapi/OpenApiSerializer.java  |  13 +-
 .../apache/juneau/parser/InputStreamParser.java    |  43 ++++--
 .../juneau/parser/InputStreamParserSession.java    |  22 ++-
 .../main/java/org/apache/juneau/parser/Parser.java |  63 +++++++--
 .../org/apache/juneau/parser/ParserSession.java    |  35 ++++-
 .../java/org/apache/juneau/parser/ParserSet.java   |  14 +-
 .../org/apache/juneau/parser/ReaderParser.java     |  37 ++++-
 .../apache/juneau/parser/ReaderParserSession.java  |  22 ++-
 .../apache/juneau/plaintext/PlainTextParser.java   |  13 +-
 .../juneau/plaintext/PlainTextSerializer.java      |  13 +-
 .../java/org/apache/juneau/reflect/ClassInfo.java  |  37 +++--
 .../juneau/serializer/OutputStreamSerializer.java  |  39 ++++--
 .../serializer/OutputStreamSerializerSession.java  |  22 ++-
 .../org/apache/juneau/serializer/Serializer.java   |  84 ++++++++++--
 .../juneau/serializer/SerializerSession.java       |  52 +++++--
 .../apache/juneau/serializer/SerializerSet.java    |  14 +-
 .../apache/juneau/serializer/WriterSerializer.java |  40 ++++--
 .../juneau/serializer/WriterSerializerSession.java |  22 ++-
 .../org/apache/juneau/soap/SoapXmlSerializer.java  |  13 +-
 .../java/org/apache/juneau/swap/BuilderSwap.java   |   8 +-
 .../main/java/org/apache/juneau/uon/UonParser.java |  15 ++-
 .../java/org/apache/juneau/uon/UonSerializer.java  |  17 ++-
 .../juneau/urlencoding/UrlEncodingParser.java      |  13 +-
 .../juneau/urlencoding/UrlEncodingSerializer.java  |  19 ++-
 .../org/apache/juneau/xml/XmlDocSerializer.java    |   4 +-
 .../main/java/org/apache/juneau/xml/XmlParser.java |  13 +-
 .../java/org/apache/juneau/xml/XmlSerializer.java  |  23 ++--
 juneau-doc/src/main/javadoc/overview.html          | 150 +++++++++++++--------
 .../examples/core/config/store/SqlStore.java       |   2 +-
 .../apache/juneau/examples/parser/ImageParser.java |  58 +++-----
 .../examples/serializer/ImageSerializer.java       |  58 +++-----
 juneau-examples/juneau-examples-rest/pom.xml       |   5 +
 .../juneau/examples/rest/PhotosResource.java       | 106 +++++++++++++++
 .../rest/test/client/ThirdPartyProxyTest.java      |   2 +-
 .../org/apache/juneau/rest/client/RestClient.java  |  18 +--
 .../apache/juneau/rest/mock/MockRestClient.java    |  12 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   5 +-
 .../java/org/apache/juneau/rest/RestOpContext.java |   2 +-
 .../apache/juneau/testutils/MockReaderParser.java  |  92 +++++--------
 .../apache/juneau/testutils/MockStreamParser.java  |  58 +++-----
 .../juneau/testutils/MockStreamSerializer.java     |  53 +++-----
 .../juneau/testutils/MockWriterSerializer.java     |  99 +++++---------
 .../org/apache/juneau/parser/ParserSetTest.java    |  16 +--
 .../apache/juneau/reflection/ClassInfoTest.java    |  22 +--
 .../juneau/rest/Header_AcceptCharset_Test.java     |   4 +-
 .../org/apache/juneau/rest/Header_Accept_Test.java |   6 +-
 .../juneau/rest/Header_ContentType_Test.java       |   6 +-
 .../test/java/org/apache/juneau/rest/Nls_Test.java |   2 +-
 .../juneau/rest/RestContext_ThreadLocals_Test.java |  77 -----------
 .../org/apache/juneau/rest/RestOp_Params_Test.java |   4 +-
 .../juneau/rest/annotation/RestHook_Test.java      |   4 +-
 .../juneau/rest/annotation/Rest_RVars_Test.java    |   2 +-
 .../juneau/rest/annotation/Restx_Parsers_Test.java |  18 +--
 .../rest/annotation/Restx_Serializers_Test.java    |  20 +--
 .../apache/juneau/rest/client/RestClient_Test.java |   6 +-
 .../juneau/serializer/SerializerSetTest.java       |  22 +--
 .../apache/juneau/transforms/BuilderComboTest.java |   4 +-
 96 files changed, 1273 insertions(+), 821 deletions(-)

diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
index 0b29c45..9df86f3 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/Config.java
@@ -257,14 +257,9 @@ public final class Config extends Context implements ConfigEventListener {
 
 		@Override /* Context.Builder */
 		public Config build() {
-			try {
-				return new Config(this);
-			} catch (IOException e) {
-				throw runtimeException(e);
-			}
+			return build(Config.class);
 		}
 
-
 		//-----------------------------------------------------------------------------------------------------------------
 		// Properties
 		//-----------------------------------------------------------------------------------------------------------------
@@ -523,7 +518,7 @@ public final class Config extends Context implements ConfigEventListener {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -562,7 +557,7 @@ public final class Config extends Context implements ConfigEventListener {
 	 * @param builder The builder for this object.
 	 * @throws IOException Thrown by underlying stream.
 	 */
-	protected Config(Builder builder) throws IOException {
+	public Config(Builder builder) throws IOException {
 		super(builder);
 
 		name = builder.name;
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ClasspathStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ClasspathStore.java
index 4917178..d6387ec 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ClasspathStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ClasspathStore.java
@@ -73,7 +73,6 @@ public class ClasspathStore extends ConfigStore {
 		 */
 		protected Builder() {
 			super();
-			type(ClasspathStore.class);
 		}
 
 		/**
@@ -102,7 +101,7 @@ public class ClasspathStore extends ConfigStore {
 
 		@Override /* Context.Builder */
 		public ClasspathStore build() {
-			return build(ClasspathStore.class, null);
+			return build(ClasspathStore.class);
 		}
 
 		//-----------------------------------------------------------------------------------------------------------------
@@ -154,7 +153,7 @@ public class ClasspathStore extends ConfigStore {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -178,7 +177,7 @@ public class ClasspathStore extends ConfigStore {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected ClasspathStore(Builder builder) {
+	public ClasspathStore(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
index 65151b3..c523a08 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/ConfigStore.java
@@ -81,9 +81,6 @@ public abstract class ConfigStore extends Context implements Closeable {
 		@Override /* Context.Builder */
 		public abstract Builder copy();
 
-		@Override
-		public abstract ConfigStore build();
-
 		//-----------------------------------------------------------------------------------------------------------------
 		// Properties
 		//-----------------------------------------------------------------------------------------------------------------
@@ -133,7 +130,7 @@ public abstract class ConfigStore extends Context implements Closeable {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/FileStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/FileStore.java
index 5108908..4442db4 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/FileStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/FileStore.java
@@ -84,7 +84,6 @@ public class FileStore extends ConfigStore {
 		 */
 		protected Builder() {
 			super();
-			type(FileStore.class);
 			directory = env("ConfigFileStore.directory", ".");
 			charset = env("ConfigFileStore.charset", Charset.defaultCharset());
 			enableWatcher = env("ConfigFileStore.enableWatcher", false);
@@ -131,7 +130,7 @@ public class FileStore extends ConfigStore {
 
 		@Override /* Context.Builder */
 		public FileStore build() {
-			return build(FileStore.class, null);
+			return build(FileStore.class);
 		}
 
 		//-----------------------------------------------------------------------------------------------------------------
@@ -342,7 +341,7 @@ public class FileStore extends ConfigStore {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -375,7 +374,7 @@ public class FileStore extends ConfigStore {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected FileStore(Builder builder) {
+	public FileStore(Builder builder) {
 		super(builder);
 		directory = builder.directory;
 		extensions = builder.extensions;
diff --git a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/MemoryStore.java b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/MemoryStore.java
index 9df337c..be757ad 100644
--- a/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/MemoryStore.java
+++ b/juneau-core/juneau-config/src/main/java/org/apache/juneau/config/store/MemoryStore.java
@@ -70,7 +70,6 @@ public class MemoryStore extends ConfigStore {
 		 */
 		protected Builder() {
 			super();
-			type(MemoryStore.class);
 		}
 
 		/**
@@ -99,7 +98,7 @@ public class MemoryStore extends ConfigStore {
 
 		@Override /* Context.Builder */
 		public MemoryStore build() {
-			return build(MemoryStore.class, null);
+			return build(MemoryStore.class);
 		}
 
 		//-----------------------------------------------------------------------------------------------------------------
@@ -151,7 +150,7 @@ public class MemoryStore extends ConfigStore {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -175,7 +174,7 @@ public class MemoryStore extends ConfigStore {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected MemoryStore(Builder builder) {
+	public MemoryStore(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
index 6ea1f85..5e76fea 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
@@ -51,7 +51,7 @@ public class N3Parser extends RdfParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected N3Parser(RdfParser.Builder builder) {
+	public N3Parser(RdfParser.Builder builder) {
 		super(builder.n3().consumes("text/n3"));
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Serializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Serializer.java
index 70aaf3b..493a9b4 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Serializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Serializer.java
@@ -51,7 +51,7 @@ public class N3Serializer extends RdfSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected N3Serializer(RdfSerializer.Builder builder) {
+	public N3Serializer(RdfSerializer.Builder builder) {
 		super(builder.n3());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleParser.java
index d07619d..154bb11 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleParser.java
@@ -51,7 +51,7 @@ public class NTripleParser extends RdfParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected NTripleParser(RdfParser.Builder builder) {
+	public NTripleParser(RdfParser.Builder builder) {
 		super(builder.ntriple().consumes("text/n-triple"));
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleSerializer.java
index ab8ffb3..0ad5d0c 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/NTripleSerializer.java
@@ -51,7 +51,7 @@ public class NTripleSerializer extends RdfSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected NTripleSerializer(RdfSerializer.Builder builder) {
+	public NTripleSerializer(RdfSerializer.Builder builder) {
 		super(builder.ntriple());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index c016a7d..0c84089 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -100,7 +100,6 @@ public class RdfParser extends ReaderParser implements RdfMetaProvider {
 		 */
 		protected Builder() {
 			super();
-			type(RdfParser.class);
 			trimWhitespace = env("Rdf.trimWhitespace", false);
 			looseCollections = env("Rdf.looseCollections", false);
 			language = env("Rdf.language", "RDF/XML-ABBREV");
@@ -149,7 +148,7 @@ public class RdfParser extends ReaderParser implements RdfMetaProvider {
 
 		@Override /* Context.Builder */
 		public RdfParser build() {
-			return build(RdfParser.class, CACHE);
+			return cache(CACHE).build(RdfParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -1002,6 +1001,12 @@ public class RdfParser extends ReaderParser implements RdfMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -1021,7 +1026,7 @@ public class RdfParser extends ReaderParser implements RdfMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1484,7 +1489,7 @@ public class RdfParser extends ReaderParser implements RdfMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected RdfParser(Builder builder) {
+	public RdfParser(Builder builder) {
 		super((Builder) builder.consumes(getConsumes(builder)));
 
 		trimWhitespace = builder.trimWhitespace;
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index f667d89..805554c 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -100,7 +100,6 @@ public class RdfSerializer extends WriterSerializer implements RdfMetaProvider {
 		 */
 		protected Builder() {
 			super();
-			type(RdfSerializer.class);
 			addBeanTypesRdf = env("Rdf.addBeanTypesRdf", false);
 			addLiteralTypes = env("Rdf.addLiteralTypes", false);
 			addRootProperty = env("Rdf.addRootProperty", false);
@@ -164,7 +163,7 @@ public class RdfSerializer extends WriterSerializer implements RdfMetaProvider {
 
 		@Override /* Context.Builder */
 		public RdfSerializer build() {
-			return build(RdfSerializer.class, CACHE);
+			return cache(CACHE).build(RdfSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -1230,6 +1229,12 @@ public class RdfSerializer extends WriterSerializer implements RdfMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -1249,7 +1254,7 @@ public class RdfSerializer extends WriterSerializer implements RdfMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1866,7 +1871,7 @@ public class RdfSerializer extends WriterSerializer implements RdfMetaProvider {
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected RdfSerializer(Builder builder) {
+	public RdfSerializer(Builder builder) {
 		super(builder.produces(getProduces(builder)).accept(getAccept(builder)));
 		addLiteralTypes = builder.addLiteralTypes;
 		addRootProperty = builder.addRootProperty;
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlAbbrevSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlAbbrevSerializer.java
index 0bd5472..050714f 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlAbbrevSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlAbbrevSerializer.java
@@ -51,7 +51,7 @@ public class RdfXmlAbbrevSerializer extends RdfSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected RdfXmlAbbrevSerializer(RdfSerializer.Builder builder) {
+	public RdfXmlAbbrevSerializer(RdfSerializer.Builder builder) {
 		super(builder.xmlabbrev());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlParser.java
index 916562c..7730918 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlParser.java
@@ -52,7 +52,7 @@ public class RdfXmlParser extends RdfParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected RdfXmlParser(RdfParser.Builder builder) {
+	public RdfXmlParser(RdfParser.Builder builder) {
 		super(builder.xml().consumes("text/xml+rdf"));
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlSerializer.java
index 5b58b04..c8dbd9c 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfXmlSerializer.java
@@ -51,7 +51,7 @@ public class RdfXmlSerializer extends RdfSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected RdfXmlSerializer(RdfSerializer.Builder builder) {
+	public RdfXmlSerializer(RdfSerializer.Builder builder) {
 		super(builder.xml());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleParser.java
index ff6b648..370770f 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleParser.java
@@ -51,7 +51,7 @@ public class TurtleParser extends RdfParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected TurtleParser(RdfParser.Builder builder) {
+	public TurtleParser(RdfParser.Builder builder) {
 		super(builder.turtle().consumes("text/turtle"));
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleSerializer.java
index 6e5559e..21e9113 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/TurtleSerializer.java
@@ -51,7 +51,7 @@ public class TurtleSerializer extends RdfSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected TurtleSerializer(RdfSerializer.Builder builder) {
+	public TurtleSerializer(RdfSerializer.Builder builder) {
 		super(builder.turtle());
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
index 14e8bdb..21251e6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContext.java
@@ -247,7 +247,6 @@ public class BeanContext extends Context {
 		 */
 		protected Builder() {
 			super();
-			type(BeanContext.class);
 			beanClassVisibility = env("BeanContext.beanClassVisibility", PUBLIC);
 			beanConstructorVisibility = env("BeanContext.beanConstructorVisibility", PUBLIC);
 			beanMethodVisibility = env("BeanContext.beanMethodVisibility", PUBLIC);
@@ -362,7 +361,7 @@ public class BeanContext extends Context {
 
 		@Override /* Context.Builder */
 		public BeanContext build() {
-			return build(BeanContext.class, CACHE);
+			return cache(CACHE).build(BeanContext.class);
 		}
 
 		@Override /* Context.Builder */
@@ -3478,7 +3477,7 @@ public class BeanContext extends Context {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -3555,7 +3554,7 @@ public class BeanContext extends Context {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected BeanContext(Builder builder) {
+	public BeanContext(Builder builder) {
 		super(builder);
 
 		hashKey = builder.hashKey();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
index fb65895..b9a88cc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanContextable.java
@@ -97,9 +97,6 @@ public abstract class BeanContextable extends Context {
 		public abstract Builder copy();
 
 		@Override /* Context.Builder */
-		public abstract BeanContextable build();
-
-		@Override /* Context.Builder */
 		public HashKey hashKey() {
 			return HashKey.of(
 				super.hashKey(),
@@ -2996,7 +2993,7 @@ public abstract class BeanContextable extends Context {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
index 36b3622..1bc8afa 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanTraverseContext.java
@@ -95,9 +95,6 @@ public abstract class BeanTraverseContext extends BeanContextable {
 		public abstract Builder copy();
 
 		@Override /* Context.Builder */
-		public abstract BeanTraverseContext build();
-
-		@Override /* Context.Builder */
 		public HashKey hashKey() {
 			return HashKey.of(
 				super.hashKey(),
@@ -337,7 +334,7 @@ public abstract class BeanTraverseContext extends BeanContextable {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
index 968f372..c48cd8a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/Context.java
@@ -12,11 +12,9 @@
 // ***************************************************************************************************************************
 package org.apache.juneau;
 
-import static org.apache.juneau.Visibility.*;
 import static org.apache.juneau.internal.ClassUtils.*;
 import static org.apache.juneau.internal.CollectionUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
-import static org.apache.juneau.reflect.ReflectionFilters.*;
 import static java.util.Arrays.*;
 import static java.util.Optional.*;
 import static java.util.stream.Collectors.*;
@@ -97,9 +95,7 @@ public abstract class Context implements MetaProvider {
 		try {
 			MethodInfo mi = BUILDER_CREATE_METHODS.get(type);
 			if (mi == null) {
-				mi = ClassInfo.of(type).getBuilderCreateMethod();
-				if (mi == null)
-					throw runtimeException("Could not find builder create method on class {0}", type);
+				mi = ClassInfo.of(type).getBuilderCreateMethod().orElseThrow(()->runtimeException("Could not find builder create method on class {0}", type));
 				BUILDER_CREATE_METHODS.put(type, mi);
 			}
 			Builder b = (Builder)mi.invoke(null);
@@ -120,10 +116,13 @@ public abstract class Context implements MetaProvider {
 	@FluentSetters
 	public static abstract class Builder {
 
+		private static final Map<Class<?>,ConstructorInfo> CONTEXT_CONSTRUCTORS = new ConcurrentHashMap<>();
+
 		boolean debug;
-		Class<?> type;
+		Class<? extends Context> type;
 		Context impl;
 		List<Annotation> annotations;
+		Cache<HashKey,? extends Context> cache;
 
 		private final List<Object> builders = new ArrayList<>();
 		private final AnnotationWorkList applied = new AnnotationWorkList();
@@ -132,10 +131,16 @@ public abstract class Context implements MetaProvider {
 		 * Constructor.
 		 * Default settings.
 		 */
+		@SuppressWarnings("unchecked")
 		protected Builder() {
 			debug = env("Context.debug", false);
 			annotations = null;
 			registerBuilders(this);
+
+			// By default, the type being created should be the class declaring the builder.
+			Class<?> dc = getClass().getDeclaringClass();
+			if (Context.class.isAssignableFrom(dc))
+				type((Class<? extends Context>)dc);
 		}
 
 		/**
@@ -162,6 +167,30 @@ public abstract class Context implements MetaProvider {
 			registerBuilders(this);
 		}
 
+		private Context innerBuild() {
+			if (type == null)
+				throw runtimeException("Type not specified for context builder {0}", getClass().getName());
+			if (impl != null && type.isInstance(impl))
+				return type.cast(impl);
+			if (cache != null)
+				return cache.get(hashKey(), ()->getContextConstructor().invoke(this));
+			return getContextConstructor().invoke(this);
+		}
+
+		private ConstructorInfo getContextConstructor() {
+			ConstructorInfo cci = CONTEXT_CONSTRUCTORS.get(type);
+			if (cci == null) {
+				cci = ClassInfo.of(type)
+					.getPublicConstructors()
+					.stream()
+					.filter(x -> x.hasNumParams(1) && x.getParam(0).getParameterType().isParentOf(this.getClass()))
+					.findFirst()
+					.orElseThrow(()->runtimeException("Public constructor not found: {0}({1})", className(type), className(this)));
+				CONTEXT_CONSTRUCTORS.put(type, cci);
+			}
+			return cci;
+		}
+
 		/**
 		 * Copy creator.
 		 *
@@ -174,7 +203,9 @@ public abstract class Context implements MetaProvider {
 		 *
 		 * @return The built object.
 		 */
-		public abstract Context build();
+		public Context build() {
+			return innerBuild();
+		}
 
 		/**
 		 * Returns the hashkey of this builder.
@@ -191,38 +222,30 @@ public abstract class Context implements MetaProvider {
 		}
 
 		/**
-		 * Builds the context from this builder.
+		 * Specifies a cache to use for hashkey-based caching.
 		 *
-		 * <p>
-		 * Looks for a public/protected constructor that takes in this builder bean.
-		 * If <c>cache</c> is specified, then the created bean will be cached using {@link #hashKey()} as the key.
-		 *
-		 * @param c The context class being created.
-		 * @param cache Optional cache to use for caching and retrieving existing instances.
-		 * @return A new context object.
+		 * @param value The cache.
+		 * @return This object.
 		 */
-		protected <T extends Context> T build(Class<T> c, Cache<HashKey,T> cache) {
-			if (impl != null && c.isInstance(impl))
-				return c.cast(impl);
-			if (cache != null)
-				return cache.get(hashKey(), ()->getContextConstructor().invoke(this));
-			return getContextConstructor().invoke(this);
+		@FluentSetter
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			this.cache = value;
+			return this;
 		}
 
-		private ConstructorInfo getContextConstructor() {
-			ConstructorInfo cci = CONTEXT_CONSTRUCTORS.get(type);
-			if (cci == null) {
-				ClassInfo ci = ClassInfo.of(type);
-				cci = ci.getConstructor(isVisible(PROTECTED).and(hasParentArgs(this))).map(x -> x.accessible()).orElse(null);
-				if (cci == null)
-					throw runtimeException("Constructor not found for class {0}", type);
-				CONTEXT_CONSTRUCTORS.put(type, cci);
-			}
-			return cci;
+		/**
+		 * Convenience method for calling {@link #build()} while avoiding a cast.
+		 *
+		 * @param c The type to cast the built object to.
+		 * @return The built context bean.
+		 */
+		@SuppressWarnings("unchecked")
+		public final <T extends Context> T build(Class<T> c) {
+			if (type == null || ! c.isAssignableFrom(type))
+				type = c;
+			return (T)innerBuild();
 		}
 
-		private static final Map<Class<?>,ConstructorInfo> CONTEXT_CONSTRUCTORS = new ConcurrentHashMap<>();
-
 		/**
 		 * Apply a consumer to this builder.
 		 *
@@ -240,11 +263,17 @@ public abstract class Context implements MetaProvider {
 		/**
 		 * Associates a context class with this builder.
 		 *
+		 * <p>
+		 * This is the type of object that this builder creates when the {@link #build()} method is called.
+		 *
+		 * <p>
+		 * By default, it's the outer class of where the builder class is defined.
+		 *
 		 * @param value The context class that this builder should create.
 		 * @return This object.
 		 */
 		@FluentSetter
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			this.type = value;
 			return this;
 		}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
index 86f5706..9416e2d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvParser.java
@@ -72,7 +72,6 @@ public class CsvParser extends ReaderParser implements CsvMetaProvider {
 		protected Builder() {
 			super();
 			consumes("text/csv");
-			type(CsvParser.class);
 		}
 
 		/**
@@ -100,7 +99,7 @@ public class CsvParser extends ReaderParser implements CsvMetaProvider {
 
 		@Override /* Context.Builder */
 		public CsvParser build() {
-			return build(CsvParser.class, CACHE);
+			return cache(CACHE).build(CsvParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -138,6 +137,12 @@ public class CsvParser extends ReaderParser implements CsvMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -157,7 +162,7 @@ public class CsvParser extends ReaderParser implements CsvMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -609,7 +614,7 @@ public class CsvParser extends ReaderParser implements CsvMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected CsvParser(Builder builder) {
+	public CsvParser(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
index 4a30abc..031b954 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/csv/CsvSerializer.java
@@ -72,7 +72,6 @@ public final class CsvSerializer extends WriterSerializer implements CsvMetaProv
 		protected Builder() {
 			super();
 			produces("text/csv");
-			type(CsvSerializer.class);
 		}
 
 		/**
@@ -100,7 +99,7 @@ public final class CsvSerializer extends WriterSerializer implements CsvMetaProv
 
 		@Override /* Context.Builder */
 		public CsvSerializer build() {
-			return build(CsvSerializer.class, CACHE);
+			return cache(CACHE).build(CsvSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -144,6 +143,12 @@ public final class CsvSerializer extends WriterSerializer implements CsvMetaProv
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug(boolean value) {
 			super.debug(value);
@@ -157,7 +162,7 @@ public final class CsvSerializer extends WriterSerializer implements CsvMetaProv
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -753,7 +758,7 @@ public final class CsvSerializer extends WriterSerializer implements CsvMetaProv
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected CsvSerializer(Builder builder) {
+	public CsvSerializer(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 8c1c7e4..c3c94f8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -124,7 +124,6 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 			super();
 			produces("text/html");
 			accept("text/html");
-			type(HtmlDocSerializer.class);
 			asideFloat = AsideFloat.RIGHT;
 			noResultsMessage = "<p>no results</p>";
 			template = BasicHtmlDocTemplate.class;
@@ -183,7 +182,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 
 		@Override /* Context.Builder */
 		public HtmlDocSerializer build() {
-			return build(HtmlDocSerializer.class, CACHE);
+			return cache(CACHE).build(HtmlDocSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -833,6 +832,12 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -852,7 +857,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1636,7 +1641,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected HtmlDocSerializer(Builder builder) {
+	public HtmlDocSerializer(Builder builder) {
 		super(builder);
 		style = ofNullable(builder.style).map(x -> toArray(x)).orElse(new String[0]);
 		stylesheet = ofNullable(builder.stylesheet).map(x -> toArray(x)).orElse(new String[0]);
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
index 7540832..0d357f7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -82,7 +82,6 @@ public class HtmlParser extends XmlParser implements HtmlMetaProvider {
 		protected Builder() {
 			super();
 			consumes("text/html,text/html+stripped");
-			type(HtmlParser.class);
 		}
 
 		/**
@@ -110,7 +109,7 @@ public class HtmlParser extends XmlParser implements HtmlMetaProvider {
 
 		@Override /* Context.Builder */
 		public HtmlParser build() {
-			return build(HtmlParser.class, CACHE);
+			return cache(CACHE).build(HtmlParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -148,6 +147,12 @@ public class HtmlParser extends XmlParser implements HtmlMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -167,7 +172,7 @@ public class HtmlParser extends XmlParser implements HtmlMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -661,7 +666,7 @@ public class HtmlParser extends XmlParser implements HtmlMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected HtmlParser(Builder builder) {
+	public HtmlParser(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
index bb87f49..d7c4a9c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
@@ -89,7 +89,6 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 			super();
 			produces("text/html");
 			accept("text/html+schema");
-			type(HtmlSchemaDocSerializer.class);
 			generatorBuilder = JsonSchemaGenerator.create().beanContext(beanContext());
 		}
 
@@ -120,7 +119,7 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 
 		@Override /* Context.Builder */
 		public HtmlSchemaDocSerializer build() {
-			return (HtmlSchemaDocSerializer)super.build();
+			return build(HtmlSchemaDocSerializer.class);
 		}
 
 		//-----------------------------------------------------------------------------------------------------------------
@@ -304,7 +303,7 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1117,7 +1116,7 @@ public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected HtmlSchemaDocSerializer(HtmlDocSerializer.Builder builder) {
+	public HtmlSchemaDocSerializer(HtmlDocSerializer.Builder builder) {
 		super(builder.detectRecursions().ignoreRecursions());
 
 		generator = JsonSchemaGenerator.create().beanContext(getBeanContext()).build();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
index 31a93cf..da2cc45 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSchemaSerializer.java
@@ -97,7 +97,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(Builder builder) {
+		public Readable(Builder builder) {
 			super(builder.useWhitespace());
 		}
 	}
@@ -110,7 +110,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Simple(Builder builder) {
+		public Simple(Builder builder) {
 			super(builder.quoteChar('\''));
 		}
 	}
@@ -123,7 +123,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SimpleReadable(Builder builder) {
+		public SimpleReadable(Builder builder) {
 			super(builder.quoteChar('\'').useWhitespace());
 		}
 	}
@@ -149,7 +149,6 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 			super();
 			produces("text/html");
 			accept("text/html+schema");
-			type(HtmlSchemaSerializer.class);
 			generatorBuilder = JsonSchemaGenerator.create().beanContext(beanContext());
 		}
 
@@ -180,7 +179,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 
 		@Override /* Context.Builder */
 		public HtmlSchemaSerializer build() {
-			return build(HtmlSchemaSerializer.class, CACHE);
+			return cache(CACHE).build(HtmlSchemaSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -353,6 +352,12 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -372,7 +377,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1093,7 +1098,7 @@ public class HtmlSchemaSerializer extends HtmlSerializer {
 	 *
 	 * @param builder The builder for this serializer.
 	 */
-	protected HtmlSchemaSerializer(Builder builder) {
+	public HtmlSchemaSerializer(Builder builder) {
 		super(builder.detectRecursions().ignoreRecursions());
 
 		generator = builder.generatorBuilder.build();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index 9aec023..9113015 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -178,7 +178,7 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Sq(Builder builder) {
+		public Sq(Builder builder) {
 			super(builder.quoteChar('\''));
 		}
 	}
@@ -191,7 +191,7 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SqReadable(Builder builder) {
+		public SqReadable(Builder builder) {
 			super(builder.quoteChar('\'').useWhitespace());
 		}
 	}
@@ -218,7 +218,6 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 		protected Builder() {
 			super();
 			produces("text/html");
-			type(HtmlSerializer.class);
 			addBeanTypesHtml = env("HtmlSerializer.addBeanTypesHtml", false);
 			addKeyValueTableHeaders = env("HtmlSerializer.addKeyValueTableHeaders", false);
 			disableDetectLabelParameters = env("HtmlSerializer.disableDetectLabelParameters", false);
@@ -264,7 +263,7 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 
 		@Override /* Context.Builder */
 		public HtmlSerializer build() {
-			return build(HtmlSerializer.class, CACHE);
+			return cache(CACHE).build(HtmlSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -743,6 +742,12 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -762,7 +767,7 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1434,7 +1439,7 @@ public class HtmlSerializer extends XmlSerializer implements HtmlMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected HtmlSerializer(Builder builder) {
+	public HtmlSerializer(Builder builder) {
 		super(builder);
 		detectLabelParameters = ! builder.disableDetectLabelParameters;
 		detectLinksInStrings = ! builder.disableDetectLinksInStrings;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
index 354eb3b..35cd40f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
@@ -84,7 +84,6 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 			super();
 			produces("text/html");
 			accept("text/html+stripped");
-			type(HtmlStrippedDocSerializer.class);
 		}
 
 		/**
@@ -112,7 +111,7 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 
 		@Override /* Context.Builder */
 		public HtmlStrippedDocSerializer build() {
-			return build(HtmlStrippedDocSerializer.class, CACHE);
+			return cache(CACHE).build(HtmlStrippedDocSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -150,6 +149,12 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -169,7 +174,7 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -888,7 +893,7 @@ public class HtmlStrippedDocSerializer extends HtmlSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected HtmlStrippedDocSerializer(Builder builder) {
+	public HtmlStrippedDocSerializer(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartParser.java
index 67d545b..7e0f255 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartParser.java
@@ -12,6 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.httppart;
 
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.utils.*;
+
 /**
  * An implementation of {@link HttpPartParser} that takes in the strings and tries to convert them to POJOs using constructors and static create methods.
  *
@@ -75,6 +79,8 @@ public class SimplePartParser extends BaseHttpPartParser {
 	 */
 	public static class Builder extends BaseHttpPartParser.Builder {
 
+		private static final Cache<HashKey,SimplePartParser> CACHE = Cache.of(HashKey.class, SimplePartParser.class).build();
+
 		/**
 		 * Constructor.
 		 */
@@ -93,13 +99,19 @@ public class SimplePartParser extends BaseHttpPartParser {
 
 		@Override
 		public SimplePartParser build() {
-			return new SimplePartParser(this);
+			return cache(CACHE).build(SimplePartParser.class);
 		}
 
 		@Override
 		public Builder copy() {
 			return new Builder(this);
 		}
+
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
 	}
 
 	//-------------------------------------------------------------------------------------------------------------------
@@ -111,7 +123,7 @@ public class SimplePartParser extends BaseHttpPartParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected SimplePartParser(Builder builder) {
+	public SimplePartParser(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartSerializer.java
index 21da4f9..fc7734b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/SimplePartSerializer.java
@@ -12,7 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.httppart;
 
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
 import org.apache.juneau.reflect.*;
+import org.apache.juneau.utils.*;
 
 /**
  * An implementation of {@link HttpPartSerializer} that simply serializes everything using {@link Object#toString()}.
@@ -56,6 +59,8 @@ public class SimplePartSerializer extends BaseHttpPartSerializer {
 	 */
 	public static class Builder extends BaseHttpPartSerializer.Builder {
 
+		private static final Cache<HashKey,SimplePartSerializer> CACHE = Cache.of(HashKey.class, SimplePartSerializer.class).build();
+
 		/**
 		 * Constructor.
 		 */
@@ -74,13 +79,19 @@ public class SimplePartSerializer extends BaseHttpPartSerializer {
 
 		@Override
 		public SimplePartSerializer build() {
-			return new SimplePartSerializer(this);
+			return cache(CACHE).build(SimplePartSerializer.class);
 		}
 
 		@Override
 		public Builder copy() {
 			return new Builder(this);
 		}
+
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
 	}
 
 	//-------------------------------------------------------------------------------------------------------------------
@@ -92,7 +103,7 @@ public class SimplePartSerializer extends BaseHttpPartSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected SimplePartSerializer(Builder builder) {
+	public SimplePartSerializer(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
index 141a6cf..0e9ecfd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -151,7 +151,7 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Strict(Builder builder) {
+		public Strict(Builder builder) {
 			super(builder.strict().validateEnd());
 		}
 	}
@@ -176,7 +176,6 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 		protected Builder() {
 			super();
 			consumes("application/json,text/json");
-			type(JsonParser.class);
 			validateEnd = env("JsonParser.validateEnd", false);
 		}
 
@@ -207,7 +206,7 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 
 		@Override /* Context.Builder */
 		public JsonParser build() {
-			return build(JsonParser.class, CACHE);
+			return cache(CACHE).build(JsonParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -287,6 +286,12 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -306,7 +311,7 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -760,7 +765,7 @@ public class JsonParser extends ReaderParser implements JsonMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected JsonParser(Builder builder) {
+	public JsonParser(Builder builder) {
 		super(builder);
 		validateEnd = builder.validateEnd;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
index 4dcb1ec..b07e040 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
@@ -89,7 +89,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(Builder builder) {
+		public Readable(Builder builder) {
 			super(builder.useWhitespace());
 		}
 	}
@@ -102,7 +102,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Simple(Builder builder) {
+		public Simple(Builder builder) {
 			super(builder.simpleMode().quoteChar('\''));
 		}
 	}
@@ -115,7 +115,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SimpleReadable(Builder builder) {
+		public SimpleReadable(Builder builder) {
 			super(builder.simpleMode().quoteChar('\'').useWhitespace());
 		}
 	}
@@ -141,7 +141,6 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 			super();
 			produces("application/json");
 			accept("application/json+schema,text/json+schema");
-			type(JsonSchemaSerializer.class);
 			generatorBuilder = JsonSchemaGenerator.create().beanContext(beanContext());
 		}
 
@@ -172,7 +171,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 
 		@Override /* Context.Builder */
 		public JsonSchemaSerializer build() {
-			return build(JsonSchemaSerializer.class, CACHE);
+			return cache(CACHE).build(JsonSchemaSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -345,6 +344,12 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -364,7 +369,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1004,7 +1009,7 @@ public class JsonSchemaSerializer extends JsonSerializer implements JsonSchemaMe
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected JsonSchemaSerializer(Builder builder) {
+	public JsonSchemaSerializer(Builder builder) {
 		super(builder.detectRecursions().ignoreRecursions());
 
 		generator = builder.generatorBuilder.build();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 9385fe9..9226d9a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -139,7 +139,7 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(Builder builder) {
+		public Readable(Builder builder) {
 			super(builder.useWhitespace());
 		}
 	}
@@ -155,7 +155,7 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected ReadableSafe(Builder builder) {
+		public ReadableSafe(Builder builder) {
 			super(builder.simpleMode().quoteChar('\'').useWhitespace().detectRecursions());
 		}
 	}
@@ -181,7 +181,6 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 			super();
 			produces("application/json");
 			accept("application/json,text/json");
-			type(JsonSerializer.class);
 			addBeanTypesJson = env("JsonSerializer.addBeanTypes", false);
 			escapeSolidus = env("JsonSerializer.escapeSolidus", false);
 			simpleMode = env("JsonSerializer.simpleMode", false);
@@ -218,7 +217,7 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 
 		@Override /* Context.Builder */
 		public JsonSerializer build() {
-			return build(JsonSerializer.class, CACHE);
+			return cache(CACHE).build(JsonSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -437,6 +436,12 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -456,7 +461,7 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1057,7 +1062,7 @@ public class JsonSerializer extends WriterSerializer implements JsonMetaProvider
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected JsonSerializer(Builder builder) {
+	public JsonSerializer(Builder builder) {
 		super(builder);
 		addBeanTypesJson = builder.addBeanTypesJson;
 		simpleMode = builder.simpleMode;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonParser.java
index c47378d..17615f1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonParser.java
@@ -59,7 +59,7 @@ public class SimpleJsonParser extends JsonParser {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected SimpleJsonParser(JsonParser.Builder builder) {
+	public SimpleJsonParser(JsonParser.Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
index 701e021..729c2d5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/json/SimpleJsonSerializer.java
@@ -71,7 +71,7 @@ public class SimpleJsonSerializer extends JsonSerializer {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(JsonSerializer.Builder builder) {
+		public Readable(JsonSerializer.Builder builder) {
 			super(builder.simpleMode().quoteChar('\'').useWhitespace());
 		}
 	}
@@ -85,7 +85,7 @@ public class SimpleJsonSerializer extends JsonSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected SimpleJsonSerializer(JsonSerializer.Builder builder) {
+	public SimpleJsonSerializer(JsonSerializer.Builder builder) {
 		super(builder.simpleMode().quoteChar('\''));
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
index 361a151..06c6b74 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/jsonschema/JsonSchemaGenerator.java
@@ -90,7 +90,6 @@ public class JsonSchemaGenerator extends BeanTraverseContext implements JsonSche
 			BeanContext.Builder bc = beanContext();
 			jsonSerializerBuilder = JsonSerializer.create().beanContext(bc);
 			jsonParserBuilder = JsonParser.create().beanContext(bc);
-			type(JsonSchemaGenerator.class);
 			registerBuilders(jsonSerializerBuilder, jsonParserBuilder);
 			addDescriptionsTo = null;
 			addExamplesTo = null;
@@ -148,7 +147,7 @@ public class JsonSchemaGenerator extends BeanTraverseContext implements JsonSche
 
 		@Override /* Context.Builder */
 		public JsonSchemaGenerator build() {
-			return build(JsonSchemaGenerator.class, CACHE);
+			return cache(CACHE).build(JsonSchemaGenerator.class);
 		}
 
 		@Override /* Context.Builder */
@@ -426,6 +425,12 @@ public class JsonSchemaGenerator extends BeanTraverseContext implements JsonSche
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
 			return this;
@@ -444,7 +449,7 @@ public class JsonSchemaGenerator extends BeanTraverseContext implements JsonSche
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -863,7 +868,7 @@ public class JsonSchemaGenerator extends BeanTraverseContext implements JsonSche
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected JsonSchemaGenerator(Builder builder) {
+	public JsonSchemaGenerator(Builder builder) {
 		super(builder.detectRecursions().ignoreRecursions());
 
 		useBeanDefs = builder.useBeanDefs;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index 4c3865c..66064c5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -75,7 +75,7 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SpacedHex(Builder builder) {
+		public SpacedHex(Builder builder) {
 			super(
 				builder.binaryFormat(BinaryFormat.SPACED_HEX)
 			);
@@ -90,7 +90,7 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Base64(Builder builder) {
+		public Base64(Builder builder) {
 			super(
 				builder.binaryFormat(BinaryFormat.BASE64)
 			);
@@ -115,7 +115,6 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 		protected Builder() {
 			super();
 			consumes("octal/msgpack");
-			type(MsgPackParser.class);
 		}
 
 		/**
@@ -143,7 +142,7 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 
 		@Override /* Context.Builder */
 		public MsgPackParser build() {
-			return build(MsgPackParser.class, CACHE);
+			return cache(CACHE).build(MsgPackParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -180,6 +179,12 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -199,7 +204,7 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -645,7 +650,7 @@ public class MsgPackParser extends InputStreamParser implements MsgPackMetaProvi
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected MsgPackParser(Builder builder) {
+	public MsgPackParser(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index ed10924..3f88414 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -81,7 +81,7 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SpacedHex(Builder builder) {
+		public SpacedHex(Builder builder) {
 			super(builder.binaryFormat(BinaryFormat.SPACED_HEX));
 		}
 	}
@@ -94,7 +94,7 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Base64(Builder builder) {
+		public Base64(Builder builder) {
 			super(builder.binaryFormat(BinaryFormat.BASE64));
 		}
 	}
@@ -119,7 +119,6 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 		protected Builder() {
 			super();
 			produces("octal/msgpack");
-			type(MsgPackSerializer.class);
 			addBeanTypesMsgPack = env("MsgPackSerializer.addBeanTypesMsgPack", false);
 		}
 
@@ -148,7 +147,7 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 
 		@Override /* Context.Builder */
 		public MsgPackSerializer build() {
-			return build(MsgPackSerializer.class, CACHE);
+			return cache(CACHE).build(MsgPackSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -219,6 +218,12 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -238,7 +243,7 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -789,7 +794,7 @@ public class MsgPackSerializer extends OutputStreamSerializer implements MsgPack
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected MsgPackSerializer(Builder builder) {
+	public MsgPackSerializer(Builder builder) {
 		super(builder);
 		this.addBeanTypesMsgPack = builder.addBeanTypesMsgPack;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
index b52f96e..9c00aa9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiParser.java
@@ -78,7 +78,6 @@ public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
 		protected Builder() {
 			super();
 			consumes("text/openapi");
-			type(OpenApiParser.class);
 			format = HttpPartFormat.NO_FORMAT;
 			collectionFormat = HttpPartCollectionFormat.NO_COLLECTION_FORMAT;
 		}
@@ -112,7 +111,7 @@ public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
 
 		@Override /* Context.Builder */
 		public OpenApiParser build() {
-			return build(OpenApiParser.class, CACHE);
+			return cache(CACHE).build(OpenApiParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -259,6 +258,12 @@ public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -278,7 +283,7 @@ public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -757,7 +762,7 @@ public class OpenApiParser extends UonParser implements OpenApiMetaProvider {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected OpenApiParser(Builder builder) {
+	public OpenApiParser(Builder builder) {
 		super(builder);
 		format = builder.format;
 		collectionFormat = builder.collectionFormat;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
index 4f8422c..085e51c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/oapi/OpenApiSerializer.java
@@ -78,7 +78,6 @@ public class OpenApiSerializer extends UonSerializer implements OpenApiMetaProvi
 		protected Builder() {
 			super();
 			produces("text/openapi");
-			type(OpenApiSerializer.class);
 			format = HttpPartFormat.NO_FORMAT;
 			collectionFormat = HttpPartCollectionFormat.NO_COLLECTION_FORMAT;
 		}
@@ -112,7 +111,7 @@ public class OpenApiSerializer extends UonSerializer implements OpenApiMetaProvi
 
 		@Override /* Context.Builder */
 		public OpenApiSerializer build() {
-			return build(OpenApiSerializer.class, CACHE);
+			return cache(CACHE).build(OpenApiSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -270,6 +269,12 @@ public class OpenApiSerializer extends UonSerializer implements OpenApiMetaProvi
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -289,7 +294,7 @@ public class OpenApiSerializer extends UonSerializer implements OpenApiMetaProvi
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -925,7 +930,7 @@ public class OpenApiSerializer extends UonSerializer implements OpenApiMetaProvi
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected OpenApiSerializer(Builder builder) {
+	public OpenApiSerializer(Builder builder) {
 		super(builder.encoding(false));
 		format = builder.format;
 		collectionFormat = builder.collectionFormat;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
index f161bac..c6cc522 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParser.java
@@ -29,12 +29,6 @@ import org.apache.juneau.utils.*;
  *
  * <h5 class='topic'>Description</h5>
  *
- * This class is typically the parent class of all byte-based parsers.
- * It has 1 abstract method to implement...
- * <ul>
- * 	<li><c>parse(InputStream, ClassMeta, Parser)</c>
- * </ul>
- *
  * <ul class='spaced-list'>
  * 	<li class='note'>This class is thread safe and reusable.
  * </ul>
@@ -44,7 +38,20 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class InputStreamParser extends Parser {
+public class InputStreamParser extends Parser {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -54,7 +61,7 @@ public abstract class InputStreamParser extends Parser {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends Parser.Builder {
+	public static class Builder extends Parser.Builder {
 
 		BinaryFormat binaryFormat;
 
@@ -87,10 +94,14 @@ public abstract class InputStreamParser extends Parser {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract InputStreamParser build();
+		public InputStreamParser build() {
+			return build(InputStreamParser.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -180,7 +191,7 @@ public abstract class InputStreamParser extends Parser {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -629,6 +640,16 @@ public abstract class InputStreamParser extends Parser {
 		return false;
 	}
 
+	@Override /* Context */
+	public InputStreamParserSession.Builder createSession() {
+		return InputStreamParserSession.create(this);
+	}
+
+	@Override /* Context */
+	public InputStreamParserSession getSession() {
+		return createSession().build();
+	}
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// Properties
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
index 469acb1..7acb2df 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/InputStreamParserSession.java
@@ -34,7 +34,21 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class InputStreamParserSession extends ParserSession {
+public class InputStreamParserSession extends ParserSession {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(InputStreamParser ctx) {
+		return new Builder(ctx);
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -44,7 +58,7 @@ public abstract class InputStreamParserSession extends ParserSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends ParserSession.Builder {
+	public static class Builder extends ParserSession.Builder {
 
 		InputStreamParser ctx;
 
@@ -59,7 +73,9 @@ public abstract class InputStreamParserSession extends ParserSession {
 		}
 
 		@Override
-		public abstract InputStreamParserSession build();
+		public InputStreamParserSession build() {
+			return new InputStreamParserSession(this);
+		}
 
 		// <FluentSetters>
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
index 5e1ad87..73d794e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/Parser.java
@@ -131,7 +131,20 @@ import org.apache.juneau.xml.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class Parser extends BeanContextable {
+public class Parser extends BeanContextable {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Static
@@ -168,7 +181,7 @@ public abstract class Parser extends BeanContextable {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends BeanContextable.Builder {
+	public static class Builder extends BeanContextable.Builder {
 
 		boolean autoCloseStreams, strict, trimStrings, unbuffered;
 		String consumes;
@@ -222,10 +235,14 @@ public abstract class Parser extends BeanContextable {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract Parser build();
+		public Parser build() {
+			return build(Parser.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -613,7 +630,7 @@ public abstract class Parser extends BeanContextable {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1010,8 +1027,9 @@ public abstract class Parser extends BeanContextable {
 	}
 
 	@Override /* Context */
-	public abstract Builder copy();
-
+	public Builder copy() {
+		return new Builder(this);
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Abstract methods
@@ -1220,10 +1238,37 @@ public abstract class Parser extends BeanContextable {
 	}
 
 	@Override /* Context */
-	public abstract ParserSession.Builder createSession();
+	public ParserSession.Builder createSession() {
+		return ParserSession.create(this);
+	}
 
 	@Override /* Context */
-	public abstract ParserSession getSession();
+	public ParserSession getSession() {
+		return createSession().build();
+	}
+
+	/**
+	 * Workhorse method.
+	 *
+	 * <p>
+	 * Subclasses are expected to either implement this method or {@link ParserSession#doParse(ParserPipe, ClassMeta)}.
+	 *
+	 * @param session The current session.
+	 * @param pipe Where to get the input from.
+	 * @param type
+	 * 	The class type of the object to create.
+	 * 	If <jk>null</jk> or <code>Object.<jk>class</jk></code>, object type is based on what's being parsed.
+	 * 	For example, when parsing JSON text, it may return a <c>String</c>, <c>Number</c>,
+	 * 	<c>OMap</c>, etc...
+	 * @param <T> The class type of the object to create.
+	 * @return The parsed object.
+	 * @throws IOException Thrown by underlying stream.
+	 * @throws ParseException Malformed input encountered.
+	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
+	 */
+	public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException {
+		throw new UnsupportedOperationException();
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Optional methods
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
index 400693e..505f800 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSession.java
@@ -44,7 +44,21 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class ParserSession extends BeanSession {
+public class ParserSession extends BeanSession {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(Parser ctx) {
+		return new Builder(ctx);
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -54,7 +68,7 @@ public abstract class ParserSession extends BeanSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends BeanSession.Builder {
+	public static class Builder extends BeanSession.Builder {
 
 		Parser ctx;
 		Method javaMethod;
@@ -73,7 +87,9 @@ public abstract class ParserSession extends BeanSession {
 		}
 
 		@Override
-		public abstract ParserSession build();
+		public ParserSession build() {
+			return new ParserSession(this);
+		}
 
 		/**
 		 * The java method that called this serializer, usually the method in a REST servlet.
@@ -249,7 +265,10 @@ public abstract class ParserSession extends BeanSession {
 	 * Workhorse method.
 	 *
 	 * <p>
-	 * Subclasses are expected to implement this method.
+	 * Subclasses are expected to implement this method or {@link Parser#doParse(ParserSession,ParserPipe,ClassMeta)}.
+	 *
+	 * <p>
+	 * The default implementation of this method simply calls {@link Parser#doParse(ParserSession,ParserPipe,ClassMeta)}.
 	 *
 	 * @param pipe Where to get the input from.
 	 * @param type
@@ -263,14 +282,18 @@ public abstract class ParserSession extends BeanSession {
 	 * @throws ParseException Malformed input encountered.
 	 * @throws ExecutableException Exception occurred on invoked constructor/method/field.
 	 */
-	protected abstract <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException;
+	protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
+		return ctx.doParse(this, pipe, type);
+	}
 
 	/**
 	 * Returns <jk>true</jk> if this parser subclasses from {@link ReaderParser}.
 	 *
 	 * @return <jk>true</jk> if this parser subclasses from {@link ReaderParser}.
 	 */
-	public abstract boolean isReaderParser();
+	public boolean isReaderParser() {
+		return false;
+	}
 
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
index ce7babb..1112ed3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ParserSet.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.parser;
 
 import static org.apache.juneau.http.HttpHeaders.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
 import static org.apache.juneau.internal.ThrowableUtils.*;
 import static java.util.Arrays.*;
 import static java.util.Collections.*;
@@ -28,6 +29,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.reflect.*;
 
 /**
  * Represents a group of {@link Parser Parsers} that can be looked up by media type.
@@ -172,7 +174,10 @@ public final class ParserSet {
 		private Object copyBuilder(Object o) {
 			if (o instanceof Parser.Builder) {
 				Parser.Builder x = (Parser.Builder)o;
-				x = x.copy();
+				Parser.Builder x2 = x.copy();
+				if (ne(x.getClass(), x2.getClass()))
+					throw runtimeException("Copy method not implemented on class " + x.getClass().getName());
+				x = x2;
 				if (bcBuilder != null)
 					x.beanContext(bcBuilder);
 				return x;
@@ -299,6 +304,13 @@ public final class ParserSet {
 
 		private Object createBuilder(Object o) {
 			if (o instanceof Class) {
+
+				// Check for no-arg constructor.
+				ConstructorInfo ci = ClassInfo.of((Class<?>)o).getPublicConstructor();
+				if (ci != null)
+					return ci.invoke();
+
+				// Check for builder.
 				@SuppressWarnings("unchecked")
 				Parser.Builder b = Parser.createParserBuilder((Class<? extends Parser>)o);
 				if (bcBuilder != null)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
index 20ade69..7ce68aa 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParser.java
@@ -45,7 +45,20 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class ReaderParser extends Parser {
+public class ReaderParser extends Parser {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -55,7 +68,7 @@ public abstract class ReaderParser extends Parser {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends Parser.Builder {
+	public static class Builder extends Parser.Builder {
 
 		Charset fileCharset, streamCharset;
 
@@ -91,10 +104,14 @@ public abstract class ReaderParser extends Parser {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract ReaderParser build();
+		public ReaderParser build() {
+			return build(ReaderParser.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -218,7 +235,7 @@ public abstract class ReaderParser extends Parser {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -668,6 +685,16 @@ public abstract class ReaderParser extends Parser {
 		return true;
 	}
 
+	@Override /* Context */
+	public ReaderParserSession.Builder createSession() {
+		return ReaderParserSession.create(this);
+	}
+
+	@Override /* Context */
+	public ReaderParserSession getSession() {
+		return createSession().build();
+	}
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// Properties
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
index d5f703f..305ebe7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/parser/ReaderParserSession.java
@@ -37,7 +37,21 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class ReaderParserSession extends ParserSession {
+public class ReaderParserSession extends ParserSession {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(ReaderParser ctx) {
+		return new Builder(ctx);
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -47,7 +61,7 @@ public abstract class ReaderParserSession extends ParserSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends ParserSession.Builder {
+	public static class Builder extends ParserSession.Builder {
 
 		ReaderParser ctx;
 		Charset fileCharset, streamCharset;
@@ -65,7 +79,9 @@ public abstract class ReaderParserSession extends ParserSession {
 		}
 
 		@Override
-		public abstract ReaderParserSession build();
+		public ReaderParserSession build() {
+			return new ReaderParserSession(this);
+		}
 
 		/**
 		 * File charset.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
index 3266476..8e4a320 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
@@ -91,7 +91,6 @@ public class PlainTextParser extends ReaderParser implements PlainTextMetaProvid
 		protected Builder() {
 			super();
 			consumes("text/plain");
-			type(PlainTextParser.class);
 		}
 
 		/**
@@ -119,7 +118,7 @@ public class PlainTextParser extends ReaderParser implements PlainTextMetaProvid
 
 		@Override /* Context.Builder */
 		public PlainTextParser build() {
-			return build(PlainTextParser.class, CACHE);
+			return cache(CACHE).build(PlainTextParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -157,6 +156,12 @@ public class PlainTextParser extends ReaderParser implements PlainTextMetaProvid
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -176,7 +181,7 @@ public class PlainTextParser extends ReaderParser implements PlainTextMetaProvid
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -628,7 +633,7 @@ public class PlainTextParser extends ReaderParser implements PlainTextMetaProvid
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected PlainTextParser(Builder builder) {
+	public PlainTextParser(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
index 683b6b5..45b531a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
@@ -87,7 +87,6 @@ public class PlainTextSerializer extends WriterSerializer implements PlainTextMe
 		protected Builder() {
 			super();
 			produces("text/plain");
-			type(PlainTextSerializer.class);
 		}
 
 		/**
@@ -115,7 +114,7 @@ public class PlainTextSerializer extends WriterSerializer implements PlainTextMe
 
 		@Override /* Context.Builder */
 		public PlainTextSerializer build() {
-			return build(PlainTextSerializer.class, CACHE);
+			return cache(CACHE).build(PlainTextSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -153,6 +152,12 @@ public class PlainTextSerializer extends WriterSerializer implements PlainTextMe
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -172,7 +177,7 @@ public class PlainTextSerializer extends WriterSerializer implements PlainTextMe
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -769,7 +774,7 @@ public class PlainTextSerializer extends WriterSerializer implements PlainTextMe
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected PlainTextSerializer(Builder builder) {
+	public PlainTextSerializer(Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
index d7d4138..e205ed5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/reflect/ClassInfo.java
@@ -718,26 +718,35 @@ public final class ClassInfo {
 	 *
 	 * @return The <c>public static Builder create()</c> method on this class, or <jk>null</jk> if it doesn't exist.
 	 */
-	public MethodInfo getBuilderCreateMethod() {
-		for (MethodInfo m : getPublicMethods()) {
-			if (m.isAll(PUBLIC, STATIC) && m.hasName("create") && (!m.hasReturnType(void.class)) && (!m.hasReturnType(c))) {
-				if (getConstructor(Visibility.PROTECTED, m.getReturnType().inner()) != null)
-					return m;
-			}
-		}
-		return null;
+	public Optional<MethodInfo> getBuilderCreateMethod() {
+		return getPublicConstructors()
+			.stream()
+			.filter(x -> x.hasNumParams(1))
+			.map(x -> x.getParam(0).getParameterType())
+			.filter(x -> ne(x.inner(), c))  // Ignore copy-constructor.
+			.map(x -> getStaticCreator(x))
+			.filter(x -> x.isPresent())
+			.findFirst()
+			.orElse(Optional.empty());
+	}
+
+	private Optional<MethodInfo> getStaticCreator(ClassInfo ci) {
+		return getPublicMethods()
+			.stream()
+			.filter(x -> x.isAll(PUBLIC, STATIC) && x.hasName("create") && x.hasReturnType(ci))
+			.findFirst();
 	}
 
 	/**
 	 * Returns the <c>T build()</c> method on this class.
 	 *
-	 * @return The <c>T build()</c> method on this class, or <jk>null</jk> if it doesn't exist.
+	 * @return The <c>T build()</c> method on this class, or {@link Optional#empty()} if it doesn't exist.
 	 */
-	public MethodInfo getBuilderBuildMethod() {
-		for (MethodInfo m : getDeclaredMethods())
-			if (m.isAll(NOT_STATIC) && m.hasName("build") && (!m.hasParams()) && (!m.hasReturnType(void.class)))
-				return m;
-		return null;
+	public Optional<MethodInfo> getBuilderBuildMethod() {
+		return getDeclaredMethods()
+			.stream()
+			.filter(x -> x.isAll(NOT_STATIC) && x.hasName("build") && (!x.hasParams()) && (!x.hasReturnType(void.class)))
+			.findFirst();
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
index 425c59e..e6f9ca9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
@@ -25,7 +25,6 @@ import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Serializer} for byte-based serializers.
- * {@review}
  *
  * <ul class='spaced-list'>
  * 	<li class='note'>This class is thread safe and reusable.
@@ -36,7 +35,20 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class OutputStreamSerializer extends Serializer {
+public class OutputStreamSerializer extends Serializer {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -46,7 +58,7 @@ public abstract class OutputStreamSerializer extends Serializer {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends Serializer.Builder {
+	public static class Builder extends Serializer.Builder {
 
 		BinaryFormat binaryFormat;
 
@@ -79,10 +91,14 @@ public abstract class OutputStreamSerializer extends Serializer {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract OutputStreamSerializer build();
+		public OutputStreamSerializer build() {
+			return build(OutputStreamSerializer.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -174,7 +190,7 @@ public abstract class OutputStreamSerializer extends Serializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -723,13 +739,14 @@ public abstract class OutputStreamSerializer extends Serializer {
 	}
 
 	@Override /* Context */
-	public abstract Builder copy();
-
-	@Override /* Context */
-	public abstract OutputStreamSerializerSession.Builder createSession();
+	public OutputStreamSerializerSession.Builder createSession() {
+		return OutputStreamSerializerSession.create(this);
+	}
 
 	@Override /* Context */
-	public abstract OutputStreamSerializerSession getSession();
+	public OutputStreamSerializerSession getSession() {
+		return createSession().build();
+	}
 
 	@Override /* Serializer */
 	public final boolean isWriterSerializer() {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
index a5191c7..ed5790c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/OutputStreamSerializerSession.java
@@ -43,7 +43,21 @@ import org.apache.juneau.svl.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class OutputStreamSerializerSession extends SerializerSession {
+public class OutputStreamSerializerSession extends SerializerSession {
+
+	//-----------------------------------------------------------------------------------------------------------------
+	// Static
+	//-----------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(OutputStreamSerializer ctx) {
+		return new Builder(ctx);
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -53,7 +67,7 @@ public abstract class OutputStreamSerializerSession extends SerializerSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public static abstract class Builder extends SerializerSession.Builder {
+	public static class Builder extends SerializerSession.Builder {
 
 		OutputStreamSerializer ctx;
 
@@ -68,7 +82,9 @@ public abstract class OutputStreamSerializerSession extends SerializerSession {
 		}
 
 		@Override
-		public abstract OutputStreamSerializerSession build();
+		public OutputStreamSerializerSession build() {
+			return new OutputStreamSerializerSession(this);
+		}
 
 		// <FluentSetters>
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
index 98bae87..5f37578 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -14,6 +14,7 @@ package org.apache.juneau.serializer;
 
 import static java.util.Optional.*;
 import static org.apache.juneau.collections.OMap.*;
+
 import java.io.*;
 import java.lang.annotation.*;
 import java.lang.reflect.*;
@@ -24,6 +25,7 @@ import org.apache.juneau.annotation.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.soap.*;
 import org.apache.juneau.utils.*;
 
 /**
@@ -43,9 +45,16 @@ import org.apache.juneau.utils.*;
  * </ul>
  *
  * <p>
- * Subclasses should extend directly from {@link OutputStreamSerializer} or {@link WriterSerializer} depending on
+ * Subclasses should (but are not required to) extend directly from {@link OutputStreamSerializer} or {@link WriterSerializer} depending on
  * whether it's a stream or character based serializer.
  *
+ * <p>
+ * Subclasses must implement parsing via one of the following methods:
+ * <ul class='javatree'>
+ * 	<li class='jmp'>{@link #doSerialize(SerializerSession, SerializerPipe, Object)}
+ * 	<li class='jmp'>{@link SerializerSession#doSerialize(SerializerPipe, Object)}
+ * </ul>
+ *
  * <ul class='spaced-list'>
  * 	<li class='note'>This class is thread safe and reusable.
  * </ul>
@@ -55,13 +64,22 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class Serializer extends BeanTraverseContext {
+public class Serializer extends BeanTraverseContext {
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Static
 	//-------------------------------------------------------------------------------------------------------------------
 
 	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
+
+	/**
 	 * Represents no Serializer.
 	 */
 	public static abstract class Null extends Serializer {
@@ -92,7 +110,7 @@ public abstract class Serializer extends BeanTraverseContext {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends BeanTraverseContext.Builder {
+	public static class Builder extends BeanTraverseContext.Builder {
 
 		boolean addBeanTypes, addRootType, keepNullProperties, sortCollections, sortMaps, trimEmptyCollections,
 			trimEmptyMaps, trimStrings;
@@ -170,10 +188,14 @@ public abstract class Serializer extends BeanTraverseContext {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract Serializer build();
+		public Serializer build() {
+			return build(Serializer.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -866,7 +888,7 @@ public abstract class Serializer extends BeanTraverseContext {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1316,17 +1338,19 @@ public abstract class Serializer extends BeanTraverseContext {
 	}
 
 	@Override /* Context */
-	public abstract Builder copy();
+	public Builder copy() {
+		return new Builder(this);
+	}
 
 	@Override /* Context */
-	public abstract SerializerSession.Builder createSession();
+	public SerializerSession.Builder createSession() {
+		return SerializerSession.create(this);
+	}
 
 	@Override /* Context */
-	public abstract SerializerSession getSession();
-
-	//-----------------------------------------------------------------------------------------------------------------
-	// Abstract methods
-	//-----------------------------------------------------------------------------------------------------------------
+	public SerializerSession getSession() {
+		return createSession().build();
+	}
 
 	/**
 	 * Returns <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
@@ -1334,7 +1358,7 @@ public abstract class Serializer extends BeanTraverseContext {
 	 * @return <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
 	 */
 	public boolean isWriterSerializer() {
-		return true;
+		return false;
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
@@ -1405,6 +1429,38 @@ public abstract class Serializer extends BeanTraverseContext {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	/**
+	 * Serializes a POJO to the specified pipe.
+	 *
+	 * @param session The current session.
+	 * @param pipe Where to send the output from the serializer.
+	 * @param o The object to serialize.
+	 * @throws IOException Thrown by underlying stream.
+	 * @throws SerializeException Problem occurred trying to serialize object.
+	 */
+	protected void doSerialize(SerializerSession session, SerializerPipe pipe, Object o) throws IOException, SerializeException {
+		throw new UnsupportedOperationException();
+	}
+
+	/**
+	 * Optional method that specifies HTTP request headers for this serializer.
+	 *
+	 * <p>
+	 * For example, {@link SoapXmlSerializer} needs to set a <c>SOAPAction</c> header.
+	 *
+	 * <p>
+	 * This method is typically meaningless if the serializer is being used stand-alone (i.e. outside of a REST server
+	 * or client).
+	 *
+	 * @param session The current session.
+	 * @return
+	 * 	The HTTP headers to set on HTTP requests.
+	 * 	Never <jk>null</jk>.
+	 */
+	public Map<String,String> getResponseHeaders(SerializerSession session) {
+		return Collections.emptyMap();
+	}
+
+	/**
 	 * Returns the media types handled based on the value of the <c>accept</c> parameter passed into the constructor.
 	 *
 	 * <p>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 3352334..03fce51 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -59,7 +59,21 @@ import org.apache.juneau.swap.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class SerializerSession extends BeanTraverseSession {
+public class SerializerSession extends BeanTraverseSession {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(Serializer ctx) {
+		return new Builder(ctx);
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -69,7 +83,7 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public static abstract class Builder extends BeanTraverseSession.Builder {
+	public static class Builder extends BeanTraverseSession.Builder {
 
 		Serializer ctx;
 		Method javaMethod;
@@ -90,7 +104,9 @@ public abstract class SerializerSession extends BeanTraverseSession {
 		}
 
 		@Override
-		public abstract SerializerSession build();
+		public SerializerSession build() {
+			return new SerializerSession(this);
+		}
 
 		/**
 		 * The java method that called this serializer, usually the method in a REST servlet.
@@ -326,17 +342,22 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	//-----------------------------------------------------------------------------------------------------------------
 
 	/**
-	 * Serializes a POJO to the specified output stream or writer.
+	 * Serializes a POJO to the specified pipe.
 	 *
 	 * <p>
 	 * This method should NOT close the context object.
 	 *
+	 * <p>
+	 * The default implementation of this method simply calls {@link Serializer#doSerialize(SerializerSession,SerializerPipe,Object)}.
+	 *
 	 * @param pipe Where to send the output from the serializer.
 	 * @param o The object to serialize.
 	 * @throws IOException Thrown by underlying stream.
 	 * @throws SerializeException Problem occurred trying to serialize object.
 	 */
-	protected abstract void doSerialize(SerializerPipe pipe, Object o) throws IOException, SerializeException;
+	protected void doSerialize(SerializerPipe pipe, Object o) throws IOException, SerializeException {
+		ctx.doSerialize(this, pipe, o);
+	}
 
 	/**
 	 * Shortcut method for serializing objects directly to either a <c>String</c> or <code><jk>byte</jk>[]</code>
@@ -349,7 +370,9 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	 * 	<br>Stream-based serializers will return a <code><jk>byte</jk>[]</code>.
 	 * @throws SerializeException If a problem occurred trying to convert the output.
 	 */
-	public abstract Object serialize(Object o) throws SerializeException;
+	public Object serialize(Object o) throws SerializeException {
+		throw new UnsupportedOperationException();
+	}
 
 	/**
 	 * Shortcut method for serializing an object to a String.
@@ -361,14 +384,18 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	 * 	<br>Stream-based serializers will return a <code><jk>byte</jk>[]</code> converted to a string based on the {@link OutputStreamSerializer.Builder#binaryFormat(BinaryFormat)} setting.
 	 * @throws SerializeException If a problem occurred trying to convert the output.
 	 */
-	public abstract String serializeToString(Object o) throws SerializeException;
+	public String serializeToString(Object o) throws SerializeException {
+		throw new UnsupportedOperationException();
+	}
 
 	/**
 	 * Returns <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
 	 *
 	 * @return <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
 	 */
-	public abstract boolean isWriterSerializer();
+	public boolean isWriterSerializer() {
+		return false;
+	}
 
 	/**
 	 * Wraps the specified input object into a {@link ParserPipe} object so that it can be easily converted into
@@ -391,7 +418,9 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	 * @return
 	 * 	A new {@link ParserPipe} wrapper around the specified input object.
 	 */
-	protected abstract SerializerPipe createPipe(Object output);
+	protected SerializerPipe createPipe(Object output) {
+		return new SerializerPipe(output);
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Other methods
@@ -824,12 +853,15 @@ public abstract class SerializerSession extends BeanTraverseSession {
 	 * This method is typically meaningless if the serializer is being used stand-alone (i.e. outside of a REST server
 	 * or client).
 	 *
+	 * <p>
+	 * The default implementation of this method simply calls {@link Serializer#getResponseHeaders(SerializerSession)}.
+	 *
 	 * @return
 	 * 	The HTTP headers to set on HTTP requests.
 	 * 	Never <jk>null</jk>.
 	 */
 	public Map<String,String> getResponseHeaders() {
-		return Collections.emptyMap();
+		return ctx.getResponseHeaders(this);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
index ec9b06d..f999c44 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/SerializerSet.java
@@ -17,6 +17,7 @@ import static org.apache.juneau.internal.ThrowableUtils.*;
 import static java.util.Arrays.*;
 import static java.util.Collections.*;
 import static java.util.stream.Collectors.*;
+import static org.apache.juneau.internal.ObjectUtils.*;
 
 import java.util.*;
 import java.util.concurrent.*;
@@ -28,6 +29,7 @@ import org.apache.juneau.collections.*;
 import org.apache.juneau.cp.*;
 import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
+import org.apache.juneau.reflect.*;
 
 /**
  * Represents a group of {@link Serializer Serializers} that can be looked up by media type.
@@ -171,7 +173,10 @@ public final class SerializerSet {
 		private Object copyBuilder(Object o) {
 			if (o instanceof Serializer.Builder) {
 				Serializer.Builder x = (Serializer.Builder)o;
-				x = x.copy();
+				Serializer.Builder x2 = x.copy();
+				if (ne(x.getClass(), x2.getClass()))
+					throw runtimeException("Copy method not implemented on class " + x.getClass().getName());
+				x = x2;
 				if (bcBuilder != null)
 					x.beanContext(bcBuilder);
 				return x;
@@ -295,6 +300,13 @@ public final class SerializerSet {
 
 		private Object createBuilder(Object o) {
 			if (o instanceof Class) {
+
+				// Check for no-arg constructor.
+				ConstructorInfo ci = ClassInfo.of((Class<?>)o).getPublicConstructor();
+				if (ci != null)
+					return ci.invoke();
+
+				// Check for builder create method.
 				@SuppressWarnings("unchecked")
 				Serializer.Builder b = Serializer.createSerializerBuilder((Class<? extends Serializer>)o);
 				if (bcBuilder != null)
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index c202fe4..c6f2dc5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -30,7 +30,6 @@ import org.apache.juneau.utils.*;
 
 /**
  * Subclass of {@link Serializer} for character-based serializers.
- * {@review}
  *
  * <ul class='spaced-list'>
  * 	<li class='note'>This class is thread safe and reusable.
@@ -41,7 +40,20 @@ import org.apache.juneau.utils.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class WriterSerializer extends Serializer {
+public class WriterSerializer extends Serializer {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @return A new builder.
+	 */
+	public static Builder create() {
+		return new Builder();
+	}
 
 	//-------------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -51,7 +63,7 @@ public abstract class WriterSerializer extends Serializer {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public abstract static class Builder extends Serializer.Builder {
+	public static class Builder extends Serializer.Builder {
 
 		boolean useWhitespace;
 		Charset fileCharset, streamCharset;
@@ -102,10 +114,14 @@ public abstract class WriterSerializer extends Serializer {
 		}
 
 		@Override /* Context.Builder */
-		public abstract Builder copy();
+		public Builder copy() {
+			return new Builder(this);
+		}
 
 		@Override /* Context.Builder */
-		public abstract WriterSerializer build();
+		public WriterSerializer build() {
+			return build(WriterSerializer.class);
+		}
 
 		@Override /* Context.Builder */
 		public HashKey hashKey() {
@@ -429,7 +445,7 @@ public abstract class WriterSerializer extends Serializer {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -990,13 +1006,19 @@ public abstract class WriterSerializer extends Serializer {
 	}
 
 	@Override /* Context */
-	public abstract Builder copy();
+	public Builder copy() {
+		return new Builder(this);
+	}
 
 	@Override /* Context */
-	public abstract WriterSerializerSession.Builder createSession();
+	public WriterSerializerSession.Builder createSession() {
+		return WriterSerializerSession.create(this);
+	}
 
 	@Override /* Context */
-	public abstract WriterSerializerSession getSession();
+	public WriterSerializerSession getSession() {
+		return createSession().build();
+	}
 
 	@Override /* Serializer */
 	public final boolean isWriterSerializer() {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
index 4845c59..aba19e4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/serializer/WriterSerializerSession.java
@@ -48,7 +48,21 @@ import org.apache.juneau.svl.*;
  * 	<li class='extlink'>{@source}
  * </ul>
  */
-public abstract class WriterSerializerSession extends SerializerSession {
+public class WriterSerializerSession extends SerializerSession {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
+
+	/**
+	 * Creates a new builder for this object.
+	 *
+	 * @param ctx The context creating this session.
+	 * @return A new builder.
+	 */
+	public static Builder create(WriterSerializer ctx) {
+		return new Builder(ctx);
+	}
 
 	//-----------------------------------------------------------------------------------------------------------------
 	// Builder
@@ -58,7 +72,7 @@ public abstract class WriterSerializerSession extends SerializerSession {
 	 * Builder class.
 	 */
 	@FluentSetters
-	public static abstract class Builder extends SerializerSession.Builder {
+	public static class Builder extends SerializerSession.Builder {
 
 		WriterSerializer ctx;
 		boolean useWhitespace;
@@ -78,7 +92,9 @@ public abstract class WriterSerializerSession extends SerializerSession {
 		}
 
 		@Override
-		public abstract WriterSerializerSession build();
+		public WriterSerializerSession build() {
+			return new WriterSerializerSession(this);
+		}
 
 		/**
 		 * File charset.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
index 8d0246a..0fb4f67 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
@@ -85,7 +85,6 @@ public class SoapXmlSerializer extends XmlSerializer implements SoapXmlMetaProvi
 			super();
 			produces("text/xml");
 			accept("text/xml+soap");
-			type(SoapXmlSerializer.class);
 			soapAction = "http://www.w3.org/2003/05/soap-envelope";
 		}
 
@@ -116,7 +115,7 @@ public class SoapXmlSerializer extends XmlSerializer implements SoapXmlMetaProvi
 
 		@Override /* Context.Builder */
 		public SoapXmlSerializer build() {
-			return build(SoapXmlSerializer.class, CACHE);
+			return cache(CACHE).build(SoapXmlSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -171,6 +170,12 @@ public class SoapXmlSerializer extends XmlSerializer implements SoapXmlMetaProvi
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -190,7 +195,7 @@ public class SoapXmlSerializer extends XmlSerializer implements SoapXmlMetaProvi
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -854,7 +859,7 @@ public class SoapXmlSerializer extends XmlSerializer implements SoapXmlMetaProvi
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected SoapXmlSerializer(Builder builder) {
+	public SoapXmlSerializer(Builder builder) {
 		super(builder);
 		soapAction = builder.soapAction;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/BuilderSwap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/BuilderSwap.java
index e706c4b..41e855c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/BuilderSwap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/swap/BuilderSwap.java
@@ -152,7 +152,7 @@ public class BuilderSwap<T,B> {
 		ConstructorInfo objectConstructor;
 		ConstructorInfo builderConstructor;
 
-		createObjectMethod = bci.getBuilderBuildMethod();
+		createObjectMethod = bci.getBuilderBuildMethod().orElse(null);
 		if (createObjectMethod != null)
 			objectClass = createObjectMethod.getReturnType().inner();
 
@@ -166,7 +166,7 @@ public class BuilderSwap<T,B> {
 			return null;
 
 		builderConstructor = bci.getNoArgConstructor(cVis);
-		createBuilderMethod = pci.getBuilderCreateMethod();
+		createBuilderMethod = pci.getBuilderCreateMethod().orElse(null);
 		if (builderConstructor == null && createBuilderMethod == null)
 			return null;
 
@@ -196,7 +196,7 @@ public class BuilderSwap<T,B> {
 
 		ClassInfo pci = ClassInfo.of(objectClass);
 
-		builderCreateMethod = pci.getBuilderCreateMethod();
+		builderCreateMethod = pci.getBuilderCreateMethod().orElse(null);
 
 		if (builderClass == null && builderCreateMethod != null)
 			builderClass = builderCreateMethod.getReturnType().inner();
@@ -221,7 +221,7 @@ public class BuilderSwap<T,B> {
 		if (builderConstructor == null && builderCreateMethod == null)
 			return null;
 
-		objectCreateMethod = bci.getBuilderBuildMethod();
+		objectCreateMethod = bci.getBuilderBuildMethod().orElse(null);
 		if (objectConstructor == null)
 			objectConstructor = pci.getConstructor(cVis, builderClass);
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
index fd2d298..e65e023 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -81,7 +81,7 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Decoding(Builder builder) {
+		public Decoding(Builder builder) {
 			super(builder.decoding());
 		}
 	}
@@ -106,7 +106,6 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 		protected Builder() {
 			super();
 			consumes("text/uon");
-			type(UonParser.class);
 			decoding = env("UonParser.decoding", false);
 			validateEnd = env("UonParser.validateEnd", false);
 		}
@@ -140,7 +139,7 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 
 		@Override /* Context.Builder */
 		public UonParser build() {
-			return build(UonParser.class, CACHE);
+			return cache(CACHE).build(UonParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -259,6 +258,12 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -278,7 +283,7 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -732,7 +737,7 @@ public class UonParser extends ReaderParser implements HttpPartParser, UonMetaPr
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected UonParser(Builder builder) {
+	public UonParser(Builder builder) {
 		super(builder);
 		decoding = builder.decoding;
 		validateEnd = builder.validateEnd;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
index b6e7729..871abcb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -173,7 +173,7 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(Builder builder) {
+		public Readable(Builder builder) {
 			super(builder.useWhitespace());
 		}
 	}
@@ -188,7 +188,7 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Encoding(Builder builder) {
+		public Encoding(Builder builder) {
 			super(builder.encoding());
 		}
 	}
@@ -236,7 +236,6 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 		protected Builder() {
 			super();
 			produces("text/uon");
-			type(UonSerializer.class);
 			addBeanTypesUon = env("UonSerializer.addBeanTypesUon", false);
 			encoding = env("UonSerializer.encoding", false);
 			paramFormat = env("UonSerializer.paramFormat", ParamFormat.UON);
@@ -276,7 +275,7 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 
 		@Override /* Context.Builder */
 		public UonSerializer build() {
-			return build(UonSerializer.class, CACHE);
+			return cache(CACHE).build(UonSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -492,6 +491,12 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -511,7 +516,7 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1119,7 +1124,7 @@ public class UonSerializer extends WriterSerializer implements HttpPartSerialize
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected UonSerializer(Builder builder) {
+	public UonSerializer(Builder builder) {
 		super(builder);
 
 		encoding = builder.encoding;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index 5018142..f879377 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -92,7 +92,6 @@ public class UrlEncodingParser extends UonParser implements UrlEncodingMetaProvi
 			super();
 			decoding();
 			consumes("application/x-www-form-urlencoded");
-			type(UrlEncodingParser.class);
 			expandedParams = env("UrlEncoding.expandedParams", false);
 		}
 
@@ -123,7 +122,7 @@ public class UrlEncodingParser extends UonParser implements UrlEncodingMetaProvi
 
 		@Override /* Context.Builder */
 		public UrlEncodingParser build() {
-			return build(UrlEncodingParser.class, CACHE);
+			return cache(CACHE).build(UrlEncodingParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -218,6 +217,12 @@ public class UrlEncodingParser extends UonParser implements UrlEncodingMetaProvi
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -237,7 +242,7 @@ public class UrlEncodingParser extends UonParser implements UrlEncodingMetaProvi
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -715,7 +720,7 @@ public class UrlEncodingParser extends UonParser implements UrlEncodingMetaProvi
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected UrlEncodingParser(Builder builder) {
+	public UrlEncodingParser(Builder builder) {
 		super(builder);
 		expandedParams = builder.expandedParams;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 5ef28ac..0b905b8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -171,7 +171,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Expanded(Builder builder) {
+		public Expanded(Builder builder) {
 			super(builder.expandedParams());
 		}
 	}
@@ -186,7 +186,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Readable(Builder builder) {
+		public Readable(Builder builder) {
 			super(builder.useWhitespace());
 		}
 	}
@@ -201,7 +201,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected PlainText(Builder builder) {
+		public PlainText(Builder builder) {
 			super(builder.paramFormatPlain());
 		}
 	}
@@ -226,7 +226,6 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 		protected Builder() {
 			super();
 			produces("application/x-www-form-urlencoded");
-			type(UrlEncodingSerializer.class);
 			expandedParams = env("UrlEncoding.expandedParams", false);
 		}
 
@@ -257,7 +256,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 
 		@Override /* Context.Builder */
 		public UrlEncodingSerializer build() {
-			return build(UrlEncodingSerializer.class, CACHE);
+			return cache(CACHE).build(UrlEncodingSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -355,6 +354,12 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -374,7 +379,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1009,7 +1014,7 @@ public class UrlEncodingSerializer extends UonSerializer implements UrlEncodingM
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected UrlEncodingSerializer(Builder builder) {
+	public UrlEncodingSerializer(Builder builder) {
 		super(builder.encoding());
 		expandedParams = builder.expandedParams;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
index c6479d5..fd4d115 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
@@ -62,7 +62,7 @@ public class XmlDocSerializer extends XmlSerializer {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Ns(XmlSerializer.Builder builder) {
+		public Ns(XmlSerializer.Builder builder) {
 			super(builder.enableNamespaces());
 		}
 	}
@@ -76,7 +76,7 @@ public class XmlDocSerializer extends XmlSerializer {
 	 *
 	 * @param builder The builder for this object.
 	 */
-	protected XmlDocSerializer(XmlSerializer.Builder builder) {
+	public XmlDocSerializer(XmlSerializer.Builder builder) {
 		super(builder);
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
index ee04580..1dd6cc4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -93,7 +93,6 @@ public class XmlParser extends ReaderParser implements XmlMetaProvider {
 		protected Builder() {
 			super();
 			consumes("text/xml,application/xml");
-			type(XmlParser.class);
 			preserveRootElement = env("XmlParser.preserveRootElement", false);
 			validating = env("XmlParser.validating", false);
 			eventAllocator = null;
@@ -136,7 +135,7 @@ public class XmlParser extends ReaderParser implements XmlMetaProvider {
 
 		@Override /* Context.Builder */
 		public XmlParser build() {
-			return build(XmlParser.class, CACHE);
+			return cache(CACHE).build(XmlParser.class);
 		}
 
 		@Override /* Context.Builder */
@@ -302,6 +301,12 @@ public class XmlParser extends ReaderParser implements XmlMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -321,7 +326,7 @@ public class XmlParser extends ReaderParser implements XmlMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -785,7 +790,7 @@ public class XmlParser extends ReaderParser implements XmlMetaProvider {
 	 * @param builder
 	 * 	The property store containing all the settings for this object.
 	 */
-	protected XmlParser(Builder builder) {
+	public XmlParser(Builder builder) {
 		super(builder);
 		validating = builder.validating;
 		preserveRootElement = builder.preserveRootElement;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index f165229..4c92099 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -176,7 +176,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Sq(Builder builder) {
+		public Sq(Builder builder) {
 			super(builder.quoteChar('\''));
 		}
 	}
@@ -189,7 +189,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected SqReadable(Builder builder) {
+		public SqReadable(Builder builder) {
 			super(builder.quoteChar('\'').useWhitespace());
 		}
 	}
@@ -202,7 +202,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected Ns(Builder builder) {
+		public Ns(Builder builder) {
 			super(builder.enableNamespaces());
 		}
 	}
@@ -215,7 +215,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected NsSq(Builder builder) {
+		public NsSq(Builder builder) {
 			super(builder.enableNamespaces().quoteChar('\''));
 		}
 	}
@@ -228,7 +228,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		 *
 		 * @param builder The builder for this object.
 		 */
-		protected NsSqReadable(Builder builder) {
+		public NsSqReadable(Builder builder) {
 			super(builder.enableNamespaces().quoteChar('\'').useWhitespace());
 		}
 	}
@@ -260,7 +260,6 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		protected Builder() {
 			super();
 			produces("text/xml");
-			type(XmlSerializer.class);
 			addBeanTypesXml = env("XmlSerializer.addBeanTypes", false);
 			addNamespaceUrisToRoot = env("XmlSerializer.addNamespaceUrisToRoot", false);
 			disableAutoDetectNamespaces = env("XmlSerializer.disableAutoDetectNamespaces", false);
@@ -307,7 +306,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 
 		@Override /* Context.Builder */
 		public XmlSerializer build() {
-			return build(XmlSerializer.class, CACHE);
+			return cache(CACHE).build(XmlSerializer.class);
 		}
 
 		@Override /* Context.Builder */
@@ -542,6 +541,12 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 			return this;
 		}
 
+		@Override /* GENERATED - org.apache.juneau.Context.Builder */
+		public Builder cache(Cache<HashKey,? extends Context> value) {
+			super.cache(value);
+			return this;
+		}
+
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
 		public Builder debug() {
 			super.debug();
@@ -561,7 +566,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1169,7 +1174,7 @@ public class XmlSerializer extends WriterSerializer implements XmlMetaProvider {
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected XmlSerializer(Builder builder) {
+	public XmlSerializer(Builder builder) {
 		super(builder);
 		autoDetectNamespaces = ! builder.disableAutoDetectNamespaces;
 		enableNamespaces = builder.enableNamespaces;
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 2d4066e..5d0a75f 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -2422,15 +2422,15 @@
 	</p>
 	<ul class='javatree'>
 		<li class='jc'>{@link org.apache.juneau.BeanContext.Builder}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanClassVisibility(Visibility) beanClassVisibility(Visibility)} - Allows non-public POJOs to be treated as beans.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanConstructorVisibility(Visibility) beanConstructorVisibility(Visibility)} - Allows non-public constructors to be used on beans.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanFieldVisibility(Visibility) beanFieldVisibility(Visibility)} - Allows non-public fields to be used as bean properties.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanMethodVisibility(Visibility) beanMethodVisibility(Visibility)} - Allows non-public methods to be used as bean getters and setters.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireDefaultConstructor() beansRequireDefaultConstructor()} - Don't treat a POJO as a bean if it doesn't have a default no-arg constructor.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireSerializable() beansRequireSerializable()} - Don't treat a POJO as a bean if it doesn't implement <c>Serializable</c>.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireSettersForGetters() beansRequireSettersForGetters()} - Ignore getter methods if they don't have setter methods.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#disableBeansRequireSomeProperties() disableBeansRequireSomeProperties()} - Don't treat a POJO as a bean if it doesn't have at least one property defined.
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanClassVisibility(Visibility) beanClassVisibility(Visibility)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanConstructorVisibility(Visibility) beanConstructorVisibility(Visibility)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanFieldVisibility(Visibility) beanFieldVisibility(Visibility)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanMethodVisibility(Visibility) beanMethodVisibility(Visibility)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireDefaultConstructor() beansRequireDefaultConstructor()}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireSerializable() beansRequireSerializable()}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beansRequireSettersForGetters() beansRequireSettersForGetters()}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#disableBeansRequireSomeProperties() disableBeansRequireSomeProperties()}
 			</ul>
 		</li>
 	</ul>
@@ -2439,11 +2439,11 @@
 	</p>
 	<ul class='javatree'>
 		<li class='jc'>{@link org.apache.juneau.BeanContext.Builder}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanProperties(Class,String) beanProperties(Class,String)} - Specifies properties to include and property order during marshalling.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesExcludes(Class,String) beanPropertiesExcludes(Class,String)} - Specifies properties to exclude during marshalling.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesReadOnly(Class,String) beanPropertiesReadOnly(Class,String) } - Specifies read-only properties (ignored during parsing).
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesWriteOnly(Class,String) beanPropertiesWriteOnly(Class,String)} - Specifies write-only properties (ignored during reading).
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanProperties(Class,String) beanProperties(Class,String)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesExcludes(Class,String) beanPropertiesExcludes(Class,String)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesReadOnly(Class,String) beanPropertiesReadOnly(Class,String) }
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#beanPropertiesWriteOnly(Class,String) beanPropertiesWriteOnly(Class,String)}
 			</ul>
 		</li>
 	</ul>
@@ -3336,9 +3336,9 @@
 	</p>
 	<ul class='javatree'>
 		<li class='jc'>{@link org.apache.juneau.BeanContext.Builder}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...) applyAnnotations(Class...)} - Apply annotations from class and all parent classes.
-				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Method...) applyAnnotations(Method...)} - Apply annotations from method and parent methods.
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Class...) applyAnnotations(Class...)}
+				<li class='jm'>{@link org.apache.juneau.BeanContext.Builder#applyAnnotations(Method...) applyAnnotations(Method...)}
 			</ul>
 		</li>
 	</ul>
@@ -5636,9 +5636,9 @@
 		.getBody().assertValue().asString().contains(<js>"OK"</js>)
 		.getBody().as(MyBean.<jk>class</jk>);
 	</p>
-	<p>
-		<i>Note:  The REST API is described later in the documentation.</i>
-	</p>
+	<ul>
+		<li class='note'>The REST API is described later in the documentation.</i>
+	</ul>
 	<p>
 		The assertions API is designed to be used in both code (as it's done in the REST APIs) or for standalone
 		use in unit tests.
@@ -14137,10 +14137,10 @@
 	</p>
 	<ul class='javatree'>
 		<li class='jac'>{@link org.apache.juneau.config.store.ConfigStore}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#read(String) read(String)} - Read a config file.
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#write(String,String,String) write(String,String,String)} - Write a config file.
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#update(String,String) update(String,String)} - Update the contents of a config file.
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#read(String) read(String)}
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#write(String,String,String) write(String,String,String)}
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#update(String,String) update(String,String)}
 			</ul>
 		</li>
 	</ul>
@@ -14186,7 +14186,11 @@
 		The store is defined on the <c>Config</c> object via the following setting:
 	</p>
 	<ul class='javatree'>
-		<li class='jm'>{@link org.apache.juneau.config.Config.Builder#store(ConfigStore)}
+		<li class='jc'>{@link org.apache.juneau.config.Config.Builder}
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.config.Config.Builder#store(ConfigStore) store(ConfigStore)}
+			</ul>
+		</li>
 	</ul>
 	
 	<h5 class='figure'>Example:</h5>
@@ -14417,9 +14421,9 @@
 	</p>
 	<ul class='javatree'>
 		<li class='jac'>{@link org.apache.juneau.config.store.ConfigStore}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#register(String,ConfigStoreListener) register(String,ConfigStoreListener)} - Register a listener on the specified config name.
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#unregister(String,ConfigStoreListener) unregister(String,ConfigStoreListener)} - Unregister a listener on the specified config name.
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#register(String,ConfigStoreListener) register(String,ConfigStoreListener)}
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStore#unregister(String,ConfigStoreListener) unregister(String,ConfigStoreListener)}
 			</ul>
 		</li>
 	</ul>
@@ -14429,8 +14433,8 @@
 	</p>		
 	<ul class='javatree'>
 		<li class='jic'>{@link org.apache.juneau.config.store.ConfigStoreListener}
-			<ul>
-				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStoreListener#onChange(String)} - Called when file changes.  New contents are passed in.
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.config.store.ConfigStoreListener#onChange(String) onChange(String)}
 			</ul>
 		</li>
 	</ul>
@@ -14451,7 +14455,11 @@
 		The following settings can be used to create read-only <c>Config</c> objects:
 	</p>
 	<ul class='javatree'>
-		<li class='jm'>{@link org.apache.juneau.config.Config.Builder#readOnly()}
+		<li class='jc'>{@link org.apache.juneau.config.Config.Builder}
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.config.Config.Builder#readOnly() readOnly()}
+			</ul>
+		</li>
 	</ul>
 	
 	<h5 class='figure'>Example:</h5>
@@ -15276,9 +15284,9 @@
 		which can be manipulated during servlet initialization.
 		(As a general rule, all annotations throughout Juneau have programmatic equivalents.)
 	</p>
-	<p>
-		<i>Note:</i>  {@link org.apache.juneau.rest.BasicRestServletJena} is the equivalent class that includes support for RDF languages.
-	</p>
+	<ul>
+		<li class='note'>{@link org.apache.juneau.rest.BasicRestServletJena} is the equivalent class that includes support for RDF languages.
+	</ul>
 	<p>
 		The {@link org.apache.juneau.rest.BasicRestObject} class is identical to the {@link org.apache.juneau.rest.BasicRestServlet} class except that
 		it does not extend from <c>HttpServlet</c>.
@@ -15709,12 +15717,12 @@
 					<ul class='javatreec'>
 						<li class='jc'>{@link org.apache.juneau.BeanContext}
 						<li class='jc'>{@link org.apache.juneau.config.Config}
-						<li class='jic'>{@link org.apache.juneau.rest.DebugEnablement}
+						<li class='jic'>{@link org.apache.juneau.rest.debug.DebugEnablement}
 						<li class='jc'>{@link org.apache.juneau.encoders.EncoderSet}
 						<li class='jic'>{@link org.apache.juneau.cp.FileFinder}
 						<li class='jc'>{@link org.apache.juneau.jsonschema.JsonSchemaGenerator}
 						<li class='jc'>{@link java.util.Logger}
-						<li class='jc'>{@link org.apache.juneau.mstat.MethodExecStore}
+						<li class='jc'>{@link org.apache.juneau.stats.MethodExecStore}
 						<li class='jc'>{@link org.apache.juneau.parser.ParserSet}
 						<li class='jc'>{@link org.apache.juneau.rest.RestChildren}
 						<li class='jc'>{@link org.apache.juneau.rest.RestContext}
@@ -15723,7 +15731,7 @@
 						<li class='jc'>{@link org.apache.juneau.rest.RestOpContext}
 						<li class='jc'>{@link org.apache.juneau.rest.RestOperations}
 						<li class='jc'>{@link org.apache.juneau.serializer.SerializerSet}
-						<li class='jic'>{@link org.apache.juneau.rest.StaticFiles}
+						<li class='jic'>{@link org.apache.juneau.rest.staticfile.StaticFiles}
 						<li class='jc'>{@link org.apache.juneau.rest.stats.ThrownStore}
 					</ul>
 				</li>
@@ -17429,9 +17437,17 @@
 	<p>
 		Guards are associated with resource classes and methods via the following:
 	</p>
-	<ul class='javatreec'>
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#guards() Rest(guards)} 
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#guards() RestOp(guards)} 
+	<ul class='javatree'>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.Rest#guards() guards} 
+			</ul>
+		</li>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.RestOp#guards() guards} 
+			</ul>
+		</li>
 	</ul>
 	<h5 class='figure'>Example:</h5>
 	<p class='bcode w800'>
@@ -17491,9 +17507,17 @@
 		A simplified format is available for matching based on the user role on the request using the following:
 	</p>
 	
-	<ul class='javatreec'>
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#roleGuard() Rest(roleGuard)} 
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#roleGuard() RestOp(roleGuard)} 
+	<ul class='javatree'>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.Rest#roleGuard() roleGuard} 
+			</ul>
+		</li>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.RestOp#roleGuard() roleGuard} 
+			</ul>
+		</li>
 	</ul>
 	<h5 class='figure'>Example:</h5>
 	<p class='bcode w800'>
@@ -17519,9 +17543,17 @@
 	<p>
 		Converters are associated with resource classes and methods via the following:
 	</p>
-	<ul class='javatreec'>
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest#converters() Rest(converters)} 
-		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp#converters() RestOp(converters)} 
+	<ul class='javatree'>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.Rest} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.Rest#converters() converters} 
+			</ul>
+		</li>
+		<li class='ja'>{@link org.apache.juneau.rest.annotation.RestOp} 
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.rest.annotation.RestOp#converters() converters} 
+			</ul>
+		</li>
 	</ul>
 	<h5 class='figure'>Example:</h5>
 	<p class='bcode w800'>
@@ -17589,7 +17621,10 @@
 		This annotation is used to provide request-localized (based on <c>Accept-Language</c>) messages for the following method:
 	</p>
 	<ul class='javatree'>
-		<li class='jm'>{@link org.apache.juneau.rest.RestRequest#getMessage(String, Object...)}
+		<li class='jc'>{@link org.apache.juneau.rest.RestRequest}
+			<ul class='javatreec'>
+				<li class='jm'>{@link org.apache.juneau.rest.RestRequest#getMessage(String,Object...) getMessage(String,Object)}
+			</ul>
 	</ul>
 	
 	<p>
@@ -18116,7 +18151,7 @@
 	<ul class='javatree'>
 		<li class='jc'>{@link org.apache.juneau.rest.RestContext.Builder}
 			<ul class='javatreec'>
-				<li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createVarResolver(BeanSession,Supplier) createVarResolver(BeanSession,Supplier)}
+				<li class='jmp'>{@link org.apache.juneau.rest.RestContext.Builder#createVarResolver(BeanStore,Class) createVarResolver(BeanStore,Class)}
 				<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#varResolver() varResolver()}
 				<li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#varResolver(Consumer) varResolver(Consumer)}
 			</ul>
@@ -18153,12 +18188,12 @@
 	<ul class='javatree'>
 		<li class='jc'>{@link org.apache.juneau.rest.RestContext}
 			<ul class='javatreec'>
-				<li class='jm'>{@link org.apache.juneau.rest.RestContext#getVarResolver()}
+				<li class='jm'>{@link org.apache.juneau.rest.RestContext#getVarResolver() getVarResolver()}
 			</ul>
 		</li>
 		<li class='jc'>{@link org.apache.juneau.rest.RestRequest}
 			<ul class='javatreec'>
-				<li class='jm'>{@link org.apache.juneau.rest.RestRequest#getVarResolverSession()}
+				<li class='jm'>{@link org.apache.juneau.rest.RestRequest#getVarResolverSession() getVarResolverSession()}
 			</ul>
 		</li>
 	</ul>
@@ -19199,7 +19234,11 @@
 		<br>They are registered in the following location:
 	</p>
 	<ul class='javatree'>
-		<li class='ja'>{@link org.apache.juneau.html.annotation.HtmlDocConfig#widgets() HtmlDocConfig(widgets)}
+		<li class='ja'>{@link org.apache.juneau.html.annotation.HtmlDocConfig}
+			<ul class='javatreec'>
+				<li class='jma'>{@link org.apache.juneau.html.annotation.HtmlDocConfig#widgets() widgets}
+			</ul>
+		</li>
 	</ul>
 	<h5 class='figure'>Example:</h5>
 	<p class='bcode w800'>
@@ -26724,10 +26763,11 @@
 		The <c>juneau-examples-rest</c> project includes various examples of REST resources written
 		using Juneau.
 	</p>
-	<p>
-		Note:  These examples can be deployed as buildable Eclipse projects using Jetty or Spring Boot using instructions
-		in the following sections:
-	</p>
+	<ul>
+		<li class='note'>
+			These examples can be deployed as buildable Eclipse projects using Jetty or Spring Boot using instructions
+			in the following sections:
+	</ul>
 	<ul class='spaced-list'>
 		<li>{@doc juneau-examples-rest-jetty}
 		<li>{@doc juneau-examples-rest-springboot}
diff --git a/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/config/store/SqlStore.java b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/config/store/SqlStore.java
index be47f8e..1fc463c 100644
--- a/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/config/store/SqlStore.java
+++ b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/config/store/SqlStore.java
@@ -108,7 +108,7 @@ public class SqlStore extends ConfigStore {
 
 		@Override
 		public SqlStore build() {
-			return new SqlStore(this);
+			return build(SqlStore.class);
 		}
 	}
 
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/parser/ImageParser.java
similarity index 54%
copy from juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
copy to juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/parser/ImageParser.java
index 6ea1f85..bb6f98d 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
+++ b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/parser/ImageParser.java
@@ -10,48 +10,32 @@
 // * "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.jena;
+package org.apache.juneau.examples.parser;
 
-/**
- * Subclass of {@link RdfParser} for parsing RDF in N3 notation.
- *
- * <ul class='spaced-list'>
- * 	<li class='note'>This class is thread safe and reusable.
- * </ul>
- *
- * <ul class='seealso'>
- * 	<li class='link'>{@doc jmr.RdfDetails}
- * 	<li class='extlink'>{@source}
- * </ul>
- */
-public class N3Parser extends RdfParser {
+import java.awt.image.*;
+import java.io.*;
 
-	//-------------------------------------------------------------------------------------------------------------------
-	// Static
-	//-------------------------------------------------------------------------------------------------------------------
+import javax.imageio.*;
 
-	/** Default N3 parser, all default settings.*/
-	public static final N3Parser DEFAULT = new N3Parser(create());
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
 
-	/**
-	 * Creates a new builder for this object.
-	 *
-	 * @return A new builder.
-	 */
-	public static RdfParser.Builder create() {
-		return RdfParser.create().n3();
-	}
+/**
+ * Example parser that converts byte streams to {@link BufferedImage} objects.
+ */
+@SuppressWarnings("javadoc")
+public class ImageParser extends InputStreamParser {
 
-	//-------------------------------------------------------------------------------------------------------------------
-	// Instance
-	//-------------------------------------------------------------------------------------------------------------------
+	public ImageParser() {
+		super(create().consumes("image/png,image/jpg"));
+	}
 
-	/**
-	 * Constructor.
-	 *
-	 * @param builder The builder for this object.
-	 */
-	protected N3Parser(RdfParser.Builder builder) {
-		super(builder.n3().consumes("text/n3"));
+	@Override /* Parser */
+	@SuppressWarnings("unchecked")
+	public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException {
+		try (InputStream is = pipe.getInputStream()) {
+			BufferedImage image = ImageIO.read(is);
+			return (T)image;
+		}
 	}
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/serializer/ImageSerializer.java
similarity index 54%
copy from juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
copy to juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/serializer/ImageSerializer.java
index 6ea1f85..260799e 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/N3Parser.java
+++ b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/serializer/ImageSerializer.java
@@ -10,48 +10,32 @@
 // * "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.jena;
+package org.apache.juneau.examples.serializer;
 
-/**
- * Subclass of {@link RdfParser} for parsing RDF in N3 notation.
- *
- * <ul class='spaced-list'>
- * 	<li class='note'>This class is thread safe and reusable.
- * </ul>
- *
- * <ul class='seealso'>
- * 	<li class='link'>{@doc jmr.RdfDetails}
- * 	<li class='extlink'>{@source}
- * </ul>
- */
-public class N3Parser extends RdfParser {
+import java.awt.image.*;
+import java.io.*;
 
-	//-------------------------------------------------------------------------------------------------------------------
-	// Static
-	//-------------------------------------------------------------------------------------------------------------------
+import javax.imageio.*;
 
-	/** Default N3 parser, all default settings.*/
-	public static final N3Parser DEFAULT = new N3Parser(create());
+import org.apache.juneau.http.header.*;
+import org.apache.juneau.serializer.*;
 
-	/**
-	 * Creates a new builder for this object.
-	 *
-	 * @return A new builder.
-	 */
-	public static RdfParser.Builder create() {
-		return RdfParser.create().n3();
-	}
+/**
+ * Example serializer that converts {@link BufferedImage} objects to byte streams.
+ */
+@SuppressWarnings("javadoc")
+public class ImageSerializer extends OutputStreamSerializer {
 
-	//-------------------------------------------------------------------------------------------------------------------
-	// Instance
-	//-------------------------------------------------------------------------------------------------------------------
+	public ImageSerializer() {
+		super(create().produces("image/png,image/jpeg"));
+	}
 
-	/**
-	 * Constructor.
-	 *
-	 * @param builder The builder for this object.
-	 */
-	protected N3Parser(RdfParser.Builder builder) {
-		super(builder.n3().consumes("text/n3"));
+	@Override
+	public void doSerialize(SerializerSession session, SerializerPipe pipe, Object o) throws IOException, SerializeException {
+		RenderedImage image = (RenderedImage)o;
+		MediaType mediaType = session.getMediaType();
+		try (OutputStream os = pipe.getOutputStream()) {
+			ImageIO.write(image, mediaType.getType(), os);
+		}
 	}
 }
\ No newline at end of file
diff --git a/juneau-examples/juneau-examples-rest/pom.xml b/juneau-examples/juneau-examples-rest/pom.xml
index 86d350c..2ac8583 100644
--- a/juneau-examples/juneau-examples-rest/pom.xml
+++ b/juneau-examples/juneau-examples-rest/pom.xml
@@ -49,6 +49,11 @@
 			<version>${project.version}</version>
 		</dependency>
 		<dependency>
+			<groupId>org.apache.juneau</groupId>
+			<artifactId>juneau-examples-core</artifactId>
+			<version>${project.version}</version>
+		</dependency>
+		<dependency>
 			<groupId>org.apache.jena</groupId>
 			<artifactId>jena-core</artifactId>
 		</dependency>
diff --git a/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
new file mode 100644
index 0000000..67daa81
--- /dev/null
+++ b/juneau-examples/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -0,0 +1,106 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau.examples.rest;
+
+import java.util.*;
+
+import org.apache.juneau.examples.parser.*;
+import org.apache.juneau.examples.serializer.*;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.http.annotation.*;
+import org.apache.juneau.http.response.*;
+import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.annotation.*;
+
+import java.awt.image.*;
+import java.net.*;
+
+/**
+ * Sample resource that allows images to be uploaded and retrieved.
+ */
+@Rest(
+	path="/photos",
+	messages="nls/PhotosResource",
+	title="Photo REST service",
+	description="Use a tool like Poster to upload and retrieve jpeg and png images."
+)
+@HtmlDocConfig(
+	navlinks="options: ?method=OPTIONS"
+)
+@SuppressWarnings({ "javadoc" })
+public class PhotosResource extends BasicRestServlet {
+
+	private static final long serialVersionUID = 1L;
+
+	// Our cache of photos
+	private Map<Integer,Photo> photos = new TreeMap<>();
+
+	/** Bean class for storing photos */
+	public static class Photo {
+		private int id;
+		BufferedImage image;
+
+		Photo(int id, BufferedImage image) {
+			this.id = id;
+			this.image = image;
+		}
+
+		public URI getURI() throws URISyntaxException {
+			return new URI("photos/"+id);
+		}
+
+		public int getID() {
+			return id;
+		}
+	}
+
+	/** GET request handler for list of all photos */
+	@RestGet("/")
+	public Collection<Photo> getAllPhotos(RestRequest req, RestResponse res) throws Exception {
+		return photos.values();
+	}
+
+	/** GET request handler for single photo */
+	@RestGet(path="/{id}", serializers=ImageSerializer.class)
+	public BufferedImage getPhoto(RestRequest req, @Path("id") int id) throws Exception {
+		Photo p = photos.get(id);
+		if (p == null)
+			throw new NotFound("Photo not found");
+		return p.image;
+	}
+
+	/** PUT request handler */
+	@RestPut(path="/{id}", parsers=ImageParser.class)
+	public String addPhoto(RestRequest req, @Path("id") int id, @Body BufferedImage image) throws Exception {
+		photos.put(id, new Photo(id, image));
+		return "OK";
+	}
+
+	/** POST request handler */
+	@RestPost(path="/", parsers=ImageParser.class)
+	public Photo setPhoto(RestRequest req, @Body BufferedImage image) throws Exception {
+		int id = photos.size();
+		Photo p = new Photo(id, image);
+		photos.put(id, p);
+		return p;
+	}
+
+	/** DELETE request handler */
+	@RestDelete("/{id}")
+	public String deletePhoto(RestRequest req, @Path("id") int id) throws Exception {
+		Photo p = photos.remove(id);
+		if (p == null)
+			throw new NotFound("Photo not found");
+		return "OK";
+	}
+}
\ No newline at end of file
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
index 0debb3e..44d1476 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
@@ -2561,7 +2561,7 @@ public class ThirdPartyProxyTest extends RestTestcase {
 
 			@Override
 			public DummyPartSerializer build() {
-				return new DummyPartSerializer(this);
+				return build(DummyPartSerializer.class);
 			}
 		}
 
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index bae2204..47110d2 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -1095,7 +1095,6 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 		 */
 		protected Builder() {
 			super();
-			type(RestClient.class);
 		}
 
 		@Override /* Context.Builder */
@@ -1105,18 +1104,7 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 
 		@Override /* Context.Builder */
 		public RestClient build() {
-			return build(RestClient.class, null);
-		}
-
-		/**
-		 * Creates client of the specified class.
-		 *
-		 * @param c The subtype to create.
-		 * @return A new client.
-		 */
-		public <T extends RestClient> T build(Class<T> c) {
-			type(c);
-			return build(c, null);
+			return build(RestClient.class);
 		}
 
 		//------------------------------------------------------------------------------------------------------------------
@@ -5740,7 +5728,7 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -6779,7 +6767,7 @@ public class RestClient extends BeanContextable implements HttpClient, Closeable
 	 *
 	 * @param builder The builder for this client.
 	 */
-	protected RestClient(Builder builder) {
+	public RestClient(Builder builder) {
 		super(builder);
 
 		beanStore = builder.beanStore
diff --git a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
index f797923..58ee92d 100644
--- a/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
+++ b/juneau-rest/juneau-rest-mock/src/main/java/org/apache/juneau/rest/mock/MockRestClient.java
@@ -422,7 +422,6 @@ public class MockRestClient extends RestClient implements HttpClientConnection {
 		protected Builder() {
 			super();
 			connectionManager(new MockHttpClientConnectionManager());
-			type(MockRestClient.class);
 		}
 
 		@Override /* Context.Builder */
@@ -586,12 +585,7 @@ public class MockRestClient extends RestClient implements HttpClientConnection {
 
 		@Override /* Context.Builder */
 		public MockRestClient build() {
-			return (MockRestClient)super.build();
-		}
-
-		@Override /* Context.Builder */
-		public <T extends RestClient> T build(Class<T> c) {
-			return super.build(c);
+			return build(MockRestClient.class);
 		}
 
 		// <FluentSetters>
@@ -627,7 +621,7 @@ public class MockRestClient extends RestClient implements HttpClientConnection {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -1917,7 +1911,7 @@ public class MockRestClient extends RestClient implements HttpClientConnection {
 	 * @param builder
 	 * 	The builder for this object.
 	 */
-	protected MockRestClient(Builder builder) {
+	public MockRestClient(Builder builder) {
 		super(preInit(builder));
 		restContext = builder.restContext;
 		contextPath = ofNullable(builder.contextPath).orElse("");
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 cc5bac3..912cf98 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
@@ -288,7 +288,6 @@ public class RestContext extends Context {
 		 * @param servletConfig The servlet config if available.
 		 */
 		protected Builder(Class<?> resourceClass, RestContext parentContext, ServletConfig servletConfig) {
-			type(RestContext.class);
 
 			this.resourceClass = resourceClass;
 			this.inner = servletConfig;
@@ -5867,7 +5866,7 @@ public class RestContext extends Context {
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
@@ -6000,7 +5999,7 @@ public class RestContext extends Context {
 	 * @param builder The builder containing the settings for this bean.
 	 * @throws Exception If any initialization problems were encountered.
 	 */
-	protected RestContext(Builder builder) throws Exception {
+	public RestContext(Builder builder) throws Exception {
 		super(builder);
 
 		startTime = Instant.now();
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
index 297cac3..edd35ca 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/RestOpContext.java
@@ -2191,7 +2191,7 @@ public class RestOpContext extends Context implements Comparable<RestOpContext>
 		}
 
 		@Override /* GENERATED - org.apache.juneau.Context.Builder */
-		public Builder type(Class<?> value) {
+		public Builder type(Class<? extends Context> value) {
 			super.type(value);
 			return this;
 		}
diff --git a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockReaderParser.java b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockReaderParser.java
index 6df6d6a..1aaeccf 100644
--- a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockReaderParser.java
+++ b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockReaderParser.java
@@ -18,7 +18,6 @@ import java.lang.reflect.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.httppart.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 
 /**
@@ -26,65 +25,22 @@ import org.apache.juneau.parser.*;
  */
 public class MockReaderParser extends ReaderParser implements HttpPartParser {
 
-	private final MockReaderParserFunction function;
-	private final MockReaderParserPartFunction partFunction;
-
-	protected MockReaderParser(Builder builder) {
-		super(builder);
-		this.function = builder.function;
-		this.partFunction = builder.partFunction;
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static Builder create() {
 		return new Builder();
 	}
 
-	@Override /* Context */
-	public ReaderParserSession.Builder createSession() {
-		return new ReaderParserSession.Builder(JsonParser.DEFAULT) {
-			@Override
-			public ReaderParserSession build() {
-				return new ReaderParserSession(this) {
-					@Override
-					@SuppressWarnings("unchecked")
-					protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
-						if (function != null)
-							return (T)function.apply(this, pipe.asString(), type);
-						return null;
-					}
-				};
-			}
-		};
-	}
-
-	@Override /* Context */
-	public ReaderParserSession getSession() {
-		return createSession().build();
-	}
-
-	@Override
-	public HttpPartParserSession getPartSession() {
-		return new HttpPartParserSession() {
-			@Override
-			@SuppressWarnings("unchecked")
-			public <T> T parse(HttpPartType partType, HttpPartSchema schema, String in, ClassMeta<T> toType) throws ParseException, SchemaValidationException {
-				return (T)partFunction.apply(partType, schema, in, toType);
-			}
-		};
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Builder
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static class Builder extends ReaderParser.Builder {
 		MockReaderParserFunction function;
 		MockReaderParserPartFunction partFunction;
 
-		public Builder() {
-			super();
-		}
-
-		public Builder(Builder copyFrom) {
-			super(copyFrom);
-		}
-
 		public Builder function(MockReaderParserFunction value) {
 			function = value;
 			return this;
@@ -103,18 +59,40 @@ public class MockReaderParser extends ReaderParser implements HttpPartParser {
 
 		@Override
 		public Builder copy() {
-			return new Builder(this);
+			return this;
 		}
+	}
 
-		@Override
-		public MockReaderParser build() {
-			return build(MockReaderParser.class, null);
-		}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Instance
+	//-------------------------------------------------------------------------------------------------------------------
+
+	private final MockReaderParserFunction function;
+	private final MockReaderParserPartFunction partFunction;
+
+	public MockReaderParser(Builder builder) {
+		super(builder);
+		this.function = builder.function;
+		this.partFunction = builder.partFunction;
+	}
+
+	@Override
+	@SuppressWarnings("unchecked")
+	public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
+		if (function != null)
+			return (T)function.apply((ReaderParserSession)session, pipe.asString(), type);
+		return null;
 	}
 
 	@Override
-	public Builder copy() {
-		throw new NoSuchMethodError("Not implemented.");
+	public HttpPartParserSession getPartSession() {
+		return new HttpPartParserSession() {
+			@Override
+			@SuppressWarnings("unchecked")
+			public <T> T parse(HttpPartType partType, HttpPartSchema schema, String in, ClassMeta<T> toType) throws ParseException, SchemaValidationException {
+				return (T)partFunction.apply(partType, schema, in, toType);
+			}
+		};
 	}
 
 	@Override
diff --git a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamParser.java b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamParser.java
index 214cd51..28696f4 100644
--- a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamParser.java
+++ b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamParser.java
@@ -16,7 +16,6 @@ import java.io.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
 
 /**
@@ -24,39 +23,17 @@ import org.apache.juneau.parser.*;
  */
 public class MockStreamParser extends InputStreamParser {
 
-	private final MockStreamParserFunction function;
-
-	protected MockStreamParser(Builder builder) {
-		super(builder);
-		this.function = builder.function;
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static Builder create() {
 		return new Builder();
 	}
 
-	@Override /* Context */
-	public InputStreamParserSession.Builder createSession() {
-		return new InputStreamParserSession.Builder(MsgPackParser.DEFAULT) {
-			@Override
-			public InputStreamParserSession build() {
-				return new InputStreamParserSession(this) {
-					@SuppressWarnings("unchecked")
-					@Override
-					protected <T> T doParse(ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
-						if (function != null)
-							return (T)function.apply(this, IOUtils.readBytes(pipe.getInputStream()), type);
-						return null;
-					}
-				};
-			}
-		};
-	}
-
-	@Override /* Context */
-	public InputStreamParserSession getSession() {
-		return createSession().build();
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Builder
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static class Builder extends InputStreamParser.Builder {
 		MockStreamParserFunction function;
@@ -74,17 +51,26 @@ public class MockStreamParser extends InputStreamParser {
 
 		@Override
 		public Builder copy() {
-			throw new NoSuchMethodError("Not implemented.");
+			return this;
 		}
+	}
 
-		@Override
-		public MockStreamParser build() {
-			return build(MockStreamParser.class, null);
-		}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Instance
+	//-------------------------------------------------------------------------------------------------------------------
+
+	private final MockStreamParserFunction function;
+
+	public MockStreamParser(Builder builder) {
+		super(builder);
+		this.function = builder.function;
 	}
 
 	@Override
-	public Builder copy() {
-		throw new NoSuchMethodError("Not implemented.");
+	@SuppressWarnings("unchecked")
+	public <T> T doParse(ParserSession session, ParserPipe pipe, ClassMeta<T> type) throws IOException, ParseException, ExecutableException {
+		if (function != null)
+			return (T)function.apply((InputStreamParserSession)session, IOUtils.readBytes(pipe.getInputStream()), type);
+		return null;
 	}
 }
diff --git a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamSerializer.java b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamSerializer.java
index 993a5f2..aa7e9b4 100644
--- a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamSerializer.java
+++ b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockStreamSerializer.java
@@ -24,36 +24,17 @@ import org.apache.juneau.serializer.*;
  */
 public class MockStreamSerializer extends OutputStreamSerializer {
 
-	private final MockStreamSerializerFunction function;
-
-	protected MockStreamSerializer(Builder builder) {
-		super(builder);
-		function = builder.function;
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static Builder create() {
 		return new Builder();
 	}
 
-	@Override /* Context */
-	public OutputStreamSerializerSession.Builder createSession() {
-		return new OutputStreamSerializerSession.Builder(this) {
-			@Override
-			public OutputStreamSerializerSession build() {
-				return new OutputStreamSerializerSession(this) {
-					@Override /* SerializerSession */
-					protected void doSerialize(SerializerPipe out, Object o) throws IOException, SerializeException {
-						out.getOutputStream().write(function.apply(this, o));
-					}
-				};
-			}
-		};
-	}
-
-	@Override /* Context */
-	public OutputStreamSerializerSession getSession() {
-		return createSession().build();
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Builder
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static class Builder extends OutputStreamSerializer.Builder {
 		MockStreamSerializerFunction function = (s,o) -> StringUtils.stringify(o).getBytes();
@@ -83,17 +64,23 @@ public class MockStreamSerializer extends OutputStreamSerializer {
 
 		@Override
 		public Builder copy() {
-			throw new NoSuchMethodError("Not implemented.");
+			return this;
 		}
+	}
 
-		@Override
-		public MockStreamSerializer build() {
-			return build(MockStreamSerializer.class, null);
-		}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Instance
+	//-------------------------------------------------------------------------------------------------------------------
+
+	private final MockStreamSerializerFunction function;
+
+	public MockStreamSerializer(Builder builder) {
+		super(builder);
+		function = builder.function;
 	}
 
-	@Override
-	public Builder copy() {
-		throw new NoSuchMethodError("Not implemented.");
+	@Override /* SerializerSession */
+	protected void doSerialize(SerializerSession session, SerializerPipe out, Object o) throws IOException, SerializeException {
+		out.getOutputStream().write(function.apply((OutputStreamSerializerSession)session, o));
 	}
 }
diff --git a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockWriterSerializer.java b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockWriterSerializer.java
index a55fe32..0c56fab 100644
--- a/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockWriterSerializer.java
+++ b/juneau-utest-utils/src/main/java/org/apache/juneau/testutils/MockWriterSerializer.java
@@ -36,7 +36,7 @@ public class MockWriterSerializer extends WriterSerializer implements HttpPartSe
 	public static final X X = new X(create());
 
 	public static class X extends MockWriterSerializer {
-		protected X(Builder builder) {
+		public X(Builder builder) {
 			super(builder
 				.function((s,o) -> out(o))
 				.partFunction((s,t,o) -> out(o))
@@ -54,73 +54,23 @@ public class MockWriterSerializer extends WriterSerializer implements HttpPartSe
 		}
 	}
 
-	//-----------------------------------------------------------------------------------------------------------------
-	// Instance
-	//-----------------------------------------------------------------------------------------------------------------
-
-	private final MockWriterSerializerFunction function;
-	private final MockWriterSerializerPartFunction partFunction;
-	private final Function<WriterSerializerSession,Map<String,String>> headers;
-
-
-	protected MockWriterSerializer(Builder builder) {
-		super(builder);
-		this.function = builder.function;
-		this.partFunction = builder.partFunction;
-		this.headers = builder.headers;
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Static
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static Builder create() {
 		return new Builder();
 	}
 
-	@Override /* Context */
-	public WriterSerializerSession.Builder createSession() {
-		return new WriterSerializerSession.Builder(this) {
-			@Override
-			public WriterSerializerSession build() {
-				return new WriterSerializerSession(this) {
-					@Override /* SerializerSession */
-					protected void doSerialize(SerializerPipe out, Object o) throws IOException, SerializeException {
-						out.getWriter().write(function.apply(this,o));
-					}
-					@Override /* SerializerSession */
-					public Map<String,String> getResponseHeaders() {
-						return headers.apply(this);
-					}
-				};
-			}
-		};
-	}
-
-	@Override /* Context */
-	public WriterSerializerSession getSession() {
-		return createSession().build();
-	}
-
-	@Override
-	public HttpPartSerializerSession getPartSession() {
-		return new HttpPartSerializerSession() {
-			@Override
-			public String serialize(HttpPartType type, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
-				return partFunction.apply(type, schema, value);
-			}
-		};
-	}
+	//-------------------------------------------------------------------------------------------------------------------
+	// Builder
+	//-------------------------------------------------------------------------------------------------------------------
 
 	public static class Builder extends WriterSerializer.Builder {
 		MockWriterSerializerFunction function = (s,o) -> StringUtils.stringify(o);
 		MockWriterSerializerPartFunction partFunction = (t,s,o) -> StringUtils.stringify(o);
 		Function<WriterSerializerSession,Map<String,String>> headers = (s) -> Collections.emptyMap();
 
-		public Builder() {
-			super();
-		}
-
-		public Builder(Builder copyFrom) {
-			super(copyFrom);
-		}
-
 		public Builder function(MockWriterSerializerFunction value) {
 			function = value;
 			return this;
@@ -150,17 +100,38 @@ public class MockWriterSerializer extends WriterSerializer implements HttpPartSe
 
 		@Override
 		public Builder copy() {
-			return new Builder(this);
+			return this;
 		}
+	}
 
-		@Override
-		public MockWriterSerializer build() {
-			return build(MockWriterSerializer.class, null);
-		}
+	private final MockWriterSerializerFunction function;
+	private final MockWriterSerializerPartFunction partFunction;
+	private final Function<WriterSerializerSession,Map<String,String>> headers;
+
+	public MockWriterSerializer(Builder builder) {
+		super(builder);
+		this.function = builder.function;
+		this.partFunction = builder.partFunction;
+		this.headers = builder.headers;
+	}
+
+	@Override /* SerializerSession */
+	protected void doSerialize(SerializerSession session, SerializerPipe out, Object o) throws IOException, SerializeException {
+		out.getWriter().write(function.apply((WriterSerializerSession)session,o));
+	}
+
+	@Override /* SerializerSession */
+	public Map<String,String> getResponseHeaders(SerializerSession session) {
+		return headers.apply((WriterSerializerSession)session);
 	}
 
 	@Override
-	public Builder copy() {
-		throw new NoSuchMethodError("Not implemented.");
+	public HttpPartSerializerSession getPartSession() {
+		return new HttpPartSerializerSession() {
+			@Override
+			public String serialize(HttpPartType type, HttpPartSchema schema, Object value) throws SerializeException, SchemaValidationException {
+				return partFunction.apply(type, schema, value);
+			}
+		};
 	}
 }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSetTest.java b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSetTest.java
index 87484a9..e227500 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSetTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/parser/ParserSetTest.java
@@ -45,9 +45,9 @@ public class ParserSetTest {
 	}
 
 
-	public static class Parser1 extends JsonParser { protected Parser1(JsonParser.Builder b) { super(b.consumes("text/foo,text/foo_a")); }}
-	public static class Parser2 extends JsonParser { protected Parser2(JsonParser.Builder b) { super(b.consumes("text/foo+bar,text/foo+bar_a")); }}
-	public static class Parser3 extends JsonParser { protected Parser3(JsonParser.Builder b) { super(b.consumes("text/baz,text/baz_a")); }}
+	public static class Parser1 extends JsonParser { public Parser1(JsonParser.Builder b) { super(b.consumes("text/foo,text/foo_a")); }}
+	public static class Parser2 extends JsonParser { public Parser2(JsonParser.Builder b) { super(b.consumes("text/foo+bar,text/foo+bar_a")); }}
+	public static class Parser3 extends JsonParser { public Parser3(JsonParser.Builder b) { super(b.consumes("text/baz,text/baz_a")); }}
 
 	//====================================================================================================
 	// Test inheritence
@@ -70,9 +70,9 @@ public class ParserSetTest {
 		assertObject(s.getSupportedMediaTypes()).asJson().is("['text/5','text/3','text/4','text/4a','text/1','text/2','text/2a']");
 	}
 
-	public static class P1 extends JsonParser { protected P1(JsonParser.Builder b) { super(b.consumes("text/1")); }}
-	public static class P2 extends JsonParser { protected P2(JsonParser.Builder b) { super(b.consumes("text/2,text/2a")); }}
-	public static class P3 extends JsonParser { protected P3(JsonParser.Builder b) { super(b.consumes("text/3")); }}
-	public static class P4 extends JsonParser { protected P4(JsonParser.Builder b) { super(b.consumes("text/4,text/4a"));} }
-	public static class P5 extends JsonParser { protected P5(JsonParser.Builder b) { super(b.consumes("text/5"));}}
+	public static class P1 extends JsonParser { public P1(JsonParser.Builder b) { super(b.consumes("text/1")); }}
+	public static class P2 extends JsonParser { public P2(JsonParser.Builder b) { super(b.consumes("text/2,text/2a")); }}
+	public static class P3 extends JsonParser { public P3(JsonParser.Builder b) { super(b.consumes("text/3")); }}
+	public static class P4 extends JsonParser { public P4(JsonParser.Builder b) { super(b.consumes("text/4,text/4a"));} }
+	public static class P5 extends JsonParser { public P5(JsonParser.Builder b) { super(b.consumes("text/5"));}}
 }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/reflection/ClassInfoTest.java b/juneau-utest/src/test/java/org/apache/juneau/reflection/ClassInfoTest.java
index d76bd08..993e50f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/reflection/ClassInfoTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/reflection/ClassInfoTest.java
@@ -548,7 +548,7 @@ public class ClassInfoTest {
 	static class DCx {}
 	static class DC1 {
 		public static DCx create() {return null;}
-		protected DC1(DCx x) {}
+		public DC1(DCx x) {}
 	}
 	static class DC2 {
 		protected static DCx create() {return null;}
@@ -566,11 +566,11 @@ public class ClassInfoTest {
 
 	@Test
 	public void getBuilderCreateMethod() throws Exception {
-		check("DC1.create()", dc1.getBuilderCreateMethod());
-		check(null, dc2.getBuilderCreateMethod());
-		check(null, dc3.getBuilderCreateMethod());
-		check(null, dc4.getBuilderCreateMethod());
-		check(null, dc5.getBuilderCreateMethod());
+		check("DC1.create()", dc1.getBuilderCreateMethod().orElse(null));
+		check(null, dc2.getBuilderCreateMethod().orElse(null));
+		check(null, dc3.getBuilderCreateMethod().orElse(null));
+		check(null, dc4.getBuilderCreateMethod().orElse(null));
+		check(null, dc5.getBuilderCreateMethod().orElse(null));
 	}
 
 	static class DDx {}
@@ -593,11 +593,11 @@ public class ClassInfoTest {
 
 	@Test
 	public void getBuilderBuildMethod() throws Exception {
-		check("DD1.build()", dd1.getBuilderBuildMethod());
-		check(null, dd2.getBuilderBuildMethod());
-		check(null, dd3.getBuilderBuildMethod());
-		check(null, dd4.getBuilderBuildMethod());
-		check(null, dd5.getBuilderBuildMethod());
+		check("DD1.build()", dd1.getBuilderBuildMethod().orElse(null));
+		check(null, dd2.getBuilderBuildMethod().orElse(null));
+		check(null, dd3.getBuilderBuildMethod().orElse(null));
+		check(null, dd4.getBuilderBuildMethod().orElse(null));
+		check(null, dd5.getBuilderBuildMethod().orElse(null));
 	}
 
 	//-----------------------------------------------------------------------------------------------------------------
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_AcceptCharset_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_AcceptCharset_Test.java
index 460b3aa..969fef1 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_AcceptCharset_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_AcceptCharset_Test.java
@@ -66,13 +66,13 @@ public class Header_AcceptCharset_Test {
 		}
 
 		public static class TestParser extends MockReaderParser {
-			protected TestParser(MockReaderParser.Builder builder) {
+			public TestParser(MockReaderParser.Builder builder) {
 				super(builder.consumes("text/plain").function((session,in,type) -> session.getStreamCharset().toString()));
 			}
 		}
 
 		public static class TestSerializer extends MockWriterSerializer {
-			protected TestSerializer(MockWriterSerializer.Builder builder) {
+			public TestSerializer(MockWriterSerializer.Builder builder) {
 				super(builder.produces("text/plain").function((session,o) -> (o.toString() + "/" + session.getStreamCharset())));
 			}
 		}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_Accept_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_Accept_Test.java
index b83a3ad..325d6ed 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_Accept_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_Accept_Test.java
@@ -30,17 +30,17 @@ public class Header_Accept_Test {
 	//------------------------------------------------------------------------------------------------------------------
 
 	public static class S1 extends MockWriterSerializer {
-		protected S1(MockWriterSerializer.Builder b) {
+		public S1(MockWriterSerializer.Builder b) {
 			super(b.produces("text/s1").function((s,o) -> "s1"));
 		}
 	}
 	public static class S2 extends MockWriterSerializer {
-		protected S2(MockWriterSerializer.Builder b) {
+		public S2(MockWriterSerializer.Builder b) {
 			super(b.produces("text/s2").function((s,o) -> "s2"));
 		}
 	}
 	public static class S3 extends MockWriterSerializer {
-		protected S3(MockWriterSerializer.Builder b) {
+		public S3(MockWriterSerializer.Builder b) {
 			super(b.produces("text/s3").function((s,o) -> "s3"));
 		}
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_ContentType_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_ContentType_Test.java
index bc0406f..d26d58f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Header_ContentType_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Header_ContentType_Test.java
@@ -211,7 +211,7 @@ public class Header_ContentType_Test {
 	// Helpers
 	//------------------------------------------------------------------------------------------------------------------
 
-	public static class P1 extends MockReaderParser { protected P1(MockReaderParser.Builder b) {super(b.consumes("text/p1").function((session,in,type)->"p1"));}}
-	public static class P2 extends MockReaderParser { protected P2(MockReaderParser.Builder b) {super(b.consumes("text/p2").function((session,in,type)->"p2"));}}
-	public static class P3 extends MockReaderParser { protected P3(MockReaderParser.Builder b) {super(b.consumes("text/p3").function((session,in,type)->"p3"));}}
+	public static class P1 extends MockReaderParser { public P1(MockReaderParser.Builder b) {super(b.consumes("text/p1").function((session,in,type)->"p1"));}}
+	public static class P2 extends MockReaderParser { public P2(MockReaderParser.Builder b) {super(b.consumes("text/p2").function((session,in,type)->"p2"));}}
+	public static class P3 extends MockReaderParser { public P3(MockReaderParser.Builder b) {super(b.consumes("text/p3").function((session,in,type)->"p3"));}}
 }
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/Nls_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/Nls_Test.java
index 9fac9f3..f64487a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/Nls_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/Nls_Test.java
@@ -47,7 +47,7 @@ public class Nls_Test {
 		}
 	}
 	public static class A1 extends MockWriterSerializer {
-		protected A1(MockWriterSerializer.Builder builder) {
+		public A1(MockWriterSerializer.Builder builder) {
 			super(builder.accept("*/*").function((s,o)->out(s)));
 		}
 
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_ThreadLocals_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_ThreadLocals_Test.java
deleted file mode 100644
index 955027b..0000000
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestContext_ThreadLocals_Test.java
+++ /dev/null
@@ -1,77 +0,0 @@
-// ***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                                                              *
-// *                                                                                                                         *
-// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
-// *                                                                                                                         *
-// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the License.                                              *
-// ***************************************************************************************************************************
-package org.apache.juneau.rest;
-
-import static org.apache.juneau.assertions.Assertions.*;
-import static org.junit.runners.MethodSorters.*;
-
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.mock.*;
-import org.junit.*;
-
-@FixMethodOrder(NAME_ASCENDING)
-public class RestContext_ThreadLocals_Test {
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Thread-locals on top-level resource.
-	//------------------------------------------------------------------------------------------------------------------
-
-	@SuppressWarnings("serial")
-	@Rest(path="/a")
-	public static class A extends BasicRestServlet {
-		@RestGet
-		public void a() throws Exception {
-			getResponse().getWriter().append(getRequest().getQueryParam("foo").orElse(null));
-		}
-
-		@RestHook(HookEvent.END_CALL)
-		public void assertThreadsNotSet() {
-			assertThrown(()->getRequest()).message().contains("No active request on current thread.");
-			assertThrown(()->getResponse()).message().contains("No active request on current thread.");
-		}
-	}
-	static MockRestClient a = MockRestClient.build(A.class);
-
-	@Test
-	public void a01() throws Exception {
-		a.get("/a?foo=bar").run()
-			.assertBody().contains("bar")
-		;
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Thread-locals on child resource.
-	//------------------------------------------------------------------------------------------------------------------
-
-	@SuppressWarnings("serial")
-	@Rest(
-		children={
-			A.class
-		}
-	)
-	public static class B extends BasicRestServletGroup {
-		@RestHook(HookEvent.END_CALL)
-		public void assertThreadsNotSet2() {
-			assertThrown(()->getRequest()).message().contains("No active request on current thread.");
-			assertThrown(()->getResponse()).message().contains("No active request on current thread.");
-		}
-	}
-	static MockRestClient b = MockRestClient.build(B.class);
-
-	@Test
-	public void b01() throws Exception {
-		b.get("/a/a?foo=bar").run()
-			.assertBody().contains("bar")
-		;
-	}
-}
\ No newline at end of file
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/RestOp_Params_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/RestOp_Params_Test.java
index 67a6a2f..19bd85a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/RestOp_Params_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/RestOp_Params_Test.java
@@ -274,13 +274,13 @@ public class RestOp_Params_Test {
 	}
 
 	public static class B1a extends PlainTextSerializer {
-		protected B1a(PlainTextSerializer.Builder b) {
+		public B1a(PlainTextSerializer.Builder b) {
 			super(b.accept("*/*"));
 		}
 	}
 
 	public static class B1b extends PlainTextParser {
-		protected B1b(PlainTextParser.Builder b) {
+		public B1b(PlainTextParser.Builder b) {
 			super(b.consumes("*/*"));
 		}
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
index 34a3c1f..1c3657c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/RestHook_Test.java
@@ -83,7 +83,7 @@ public class RestHook_Test {
 	}
 
 	public static class A1 extends MockReaderParser {
-		protected A1(MockReaderParser.Builder b) {
+		public A1(MockReaderParser.Builder b) {
 			super(b.consumes("text/a1,text/a2,text/a3").function((session,in,type)->in(session)));
 		}
 
@@ -155,7 +155,7 @@ public class RestHook_Test {
 	}
 
 	public static class B1 extends MockWriterSerializer {
-		protected B1(MockWriterSerializer.Builder b) {
+		public B1(MockWriterSerializer.Builder b) {
 			super(b.produces("test/s1").accept("text/s1,text/s2,text/s3").function((s,o) -> out(s)).headers(s->headers(s)));
 		}
 		public static String out(SerializerSession s) {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
index a2577ee..6663caa 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Rest_RVars_Test.java
@@ -61,7 +61,7 @@ public class Rest_RVars_Test {
 		}
 
 		public static class A1 extends MockWriterSerializer {
-			protected A1(MockWriterSerializer.Builder b) {
+			public A1(MockWriterSerializer.Builder b) {
 				super(b.produces("text/plain").accept("*/*").function((s,o) -> out(s)));
 			}
 			public static String out(SerializerSession s) {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Parsers_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Parsers_Test.java
index c3c4cbe..1a76f39 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Parsers_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Parsers_Test.java
@@ -30,25 +30,25 @@ public class Restx_Parsers_Test {
 	//------------------------------------------------------------------------------------------------------------------
 
 	public static class PA extends MockReaderParser {
-		protected PA(MockReaderParser.Builder b) {
+		public PA(MockReaderParser.Builder b) {
 			super(b.consumes("text/a").function((session,in,type)->"text/a - " + in));
 		}
 	}
 
 	public static class PB extends MockReaderParser {
-		protected PB(MockReaderParser.Builder b) {
+		public PB(MockReaderParser.Builder b) {
 			super(b.consumes("text/b").function((session,in,type)->"text/b - " + in));
 		}
 	}
 
 	public static class PC extends MockReaderParser {
-		protected PC(MockReaderParser.Builder b) {
+		public PC(MockReaderParser.Builder b) {
 			super(b.consumes("text/c").function((session,in,type)->"text/c - " + in));
 		}
 	}
 
 	public static class PD extends MockReaderParser {
-		protected PD(MockReaderParser.Builder b) {
+		public PD(MockReaderParser.Builder b) {
 			super(b.consumes("text/d").function((session,in,type)->"text/d - " + in));
 		}
 	}
@@ -143,11 +143,11 @@ public class Restx_Parsers_Test {
 	// Test parser inheritance.
 	//------------------------------------------------------------------------------------------------------------------
 
-	public static class P1 extends MockReaderParser{ protected P1(MockReaderParser.Builder b) {super(b.consumes("text/p1"));} }
-	public static class P2 extends MockReaderParser{ protected P2(MockReaderParser.Builder b) {super(b.consumes("text/p2"));} }
-	public static class P3 extends MockReaderParser{ protected P3(MockReaderParser.Builder b) {super(b.consumes("text/p3"));} }
-	public static class P4 extends MockReaderParser{ protected P4(MockReaderParser.Builder b) {super(b.consumes("text/p4"));} }
-	public static class P5 extends MockReaderParser{ protected P5(MockReaderParser.Builder b) {super(b.consumes("text/p5"));} }
+	public static class P1 extends MockReaderParser{ public P1(MockReaderParser.Builder b) {super(b.consumes("text/p1"));} }
+	public static class P2 extends MockReaderParser{ public P2(MockReaderParser.Builder b) {super(b.consumes("text/p2"));} }
+	public static class P3 extends MockReaderParser{ public P3(MockReaderParser.Builder b) {super(b.consumes("text/p3"));} }
+	public static class P4 extends MockReaderParser{ public P4(MockReaderParser.Builder b) {super(b.consumes("text/p4"));} }
+	public static class P5 extends MockReaderParser{ public P5(MockReaderParser.Builder b) {super(b.consumes("text/p5"));} }
 
 	@Rest(parsers={P1.class,P2.class})
 	public static class B {}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Serializers_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Serializers_Test.java
index a6bc1de..1c5258c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Serializers_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/annotation/Restx_Serializers_Test.java
@@ -30,25 +30,25 @@ public class Restx_Serializers_Test {
 	//------------------------------------------------------------------------------------------------------------------
 
 	public static class SA extends MockWriterSerializer {
-		protected SA(MockWriterSerializer.Builder b) {
+		public SA(MockWriterSerializer.Builder b) {
 			super(b.produces("text/a").function((s,o)->"text/a - "+o));
 		}
 	}
 
 	public static class SB extends MockWriterSerializer {
-		protected SB(MockWriterSerializer.Builder b) {
+		public SB(MockWriterSerializer.Builder b) {
 			super(b.produces("text/b").function((s,o)->"text/b - "+o));
 		}
 	}
 
 	public static class SC extends MockWriterSerializer {
-		protected SC(MockWriterSerializer.Builder b) {
+		public SC(MockWriterSerializer.Builder b) {
 			super(b.produces("text/a").function((s,o)->"text/c - "+o));
 		}
 	}
 
 	public static class SD extends MockWriterSerializer {
-		protected SD(MockWriterSerializer.Builder b) {
+		public SD(MockWriterSerializer.Builder b) {
 			super(b.produces("text/d").accept("text/a,text/d").function((s,o)->"text/d - "+o));
 		}
 	}
@@ -131,16 +131,16 @@ public class Restx_Serializers_Test {
 	//------------------------------------------------------------------------------------------------------------------
 
 	public static class DummySerializer extends MockWriterSerializer {
-		protected DummySerializer(MockWriterSerializer.Builder b, String produces) {
+		public DummySerializer(MockWriterSerializer.Builder b, String produces) {
 			super(b.produces(produces));
 		}
 	}
 
-	public static class S1 extends DummySerializer{ protected S1(MockWriterSerializer.Builder b) {super(b, "text/s1");} }
-	public static class S2 extends DummySerializer{ protected S2(MockWriterSerializer.Builder b) {super(b, "text/s2");} }
-	public static class S3 extends DummySerializer{ protected S3(MockWriterSerializer.Builder b) {super(b, "text/s3");} }
-	public static class S4 extends DummySerializer{ protected S4(MockWriterSerializer.Builder b) {super(b, "text/s4");} }
-	public static class S5 extends DummySerializer{ protected S5(MockWriterSerializer.Builder b) {super(b, "text/s5");} }
+	public static class S1 extends DummySerializer{ public S1(MockWriterSerializer.Builder b) {super(b, "text/s1");} }
+	public static class S2 extends DummySerializer{ public S2(MockWriterSerializer.Builder b) {super(b, "text/s2");} }
+	public static class S3 extends DummySerializer{ public S3(MockWriterSerializer.Builder b) {super(b, "text/s3");} }
+	public static class S4 extends DummySerializer{ public S4(MockWriterSerializer.Builder b) {super(b, "text/s4");} }
+	public static class S5 extends DummySerializer{ public S5(MockWriterSerializer.Builder b) {super(b, "text/s5");} }
 
 	@Rest(serializers={S1.class,S2.class})
 	public static class B {}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
index 6d2b086..4926b5a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/rest/client/RestClient_Test.java
@@ -71,7 +71,11 @@ public class RestClient_Test {
 	// Override client and builder.
 	//------------------------------------------------------------------------------------------------------------------
 
-	public static class A2 extends RestClient.Builder {}
+	public static class A2 extends RestClient.Builder {
+		public A2() {
+			super();
+		}
+	}
 
 	@Test
 	public void a02_basic_useNoArgConstructor() {
diff --git a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSetTest.java b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSetTest.java
index 04d2f0b..3b7b9dd 100755
--- a/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSetTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/serializer/SerializerSetTest.java
@@ -51,19 +51,19 @@ public class SerializerSetTest {
 
 
 	public static class SA1 extends JsonSerializer {
-		protected SA1(JsonSerializer.Builder builder) {
+		public SA1(JsonSerializer.Builder builder) {
 			super(builder.accept("text/foo+*,text/foo_a+*"));
 		}
 	}
 
 	public static class SA2 extends JsonSerializer {
-		protected SA2(JsonSerializer.Builder builder) {
+		public SA2(JsonSerializer.Builder builder) {
 			super(builder.accept("text/foo+bar+*,text/foo+bar_a+*"));
 		}
 	}
 
 	public static class SA3 extends JsonSerializer {
-		protected SA3(JsonSerializer.Builder builder) {
+		public SA3(JsonSerializer.Builder builder) {
 			super(builder.accept("text/baz+*,text/baz_a+*"));
 		}
 	}
@@ -90,31 +90,31 @@ public class SerializerSetTest {
 	}
 
 	public static class SB1 extends JsonSerializer {
-		protected SB1(JsonSerializer.Builder builder) {
+		public SB1(JsonSerializer.Builder builder) {
 			super(builder.accept("text/1"));
 		}
 	}
 
 	public static class SB2 extends JsonSerializer {
-		protected SB2(JsonSerializer.Builder builder) {
+		public SB2(JsonSerializer.Builder builder) {
 			super(builder.accept("text/2,text/2a"));
 		}
 	}
 
 	public static class SB3 extends JsonSerializer {
-		protected SB3(JsonSerializer.Builder builder) {
+		public SB3(JsonSerializer.Builder builder) {
 			super(builder.accept("text/3"));
 		}
 	}
 
 	public static class SB4 extends JsonSerializer {
-		protected SB4(JsonSerializer.Builder builder) {
+		public SB4(JsonSerializer.Builder builder) {
 			super(builder.accept("text/4,text/4a"));
 		}
 	}
 
 	public static class SB5 extends JsonSerializer {
-		protected SB5(JsonSerializer.Builder builder) {
+		public SB5(JsonSerializer.Builder builder) {
 			super(builder.accept("text/5"));
 		}
 	}
@@ -135,19 +135,19 @@ public class SerializerSetTest {
 	}
 
 	public static class SC1 extends JsonSerializer {
-		protected SC1(JsonSerializer.Builder builder) {
+		public SC1(JsonSerializer.Builder builder) {
 			super(builder.accept("text/*"));
 		}
 	}
 
 	public static class SC2 extends JsonSerializer {
-		protected SC2(JsonSerializer.Builder builder) {
+		public SC2(JsonSerializer.Builder builder) {
 			super(builder.accept("*/json"));
 		}
 	}
 
 	public static class SC3 extends JsonSerializer {
-		protected SC3(JsonSerializer.Builder builder) {
+		public SC3(JsonSerializer.Builder builder) {
 			super(builder.accept("*/*"));
 		}
 	}
diff --git a/juneau-utest/src/test/java/org/apache/juneau/transforms/BuilderComboTest.java b/juneau-utest/src/test/java/org/apache/juneau/transforms/BuilderComboTest.java
index 285359c..810c83a 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/transforms/BuilderComboTest.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/transforms/BuilderComboTest.java
@@ -235,7 +235,7 @@ public class BuilderComboTest extends ComboRoundTripTest {
 		public int a;
 		boolean createdByBuilder;
 
-		protected A(ABuilder x) {
+		public A(ABuilder x) {
 			if (x != null)
 				this.a = x.a;
 		}
@@ -379,7 +379,7 @@ public class BuilderComboTest extends ComboRoundTripTest {
 		public int fooBar;
 		boolean createdByBuilder;
 
-		protected H(HBuilder x) {
+		public H(HBuilder x) {
 			if (x != null)
 				this.fooBar = x.fooBar;
 		}