You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2017/03/10 16:50:57 UTC

[01/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Repository: incubator-juneau
Updated Branches:
  refs/heads/master d59d737c3 -> 95e832e1a


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
index 396e5e1..83c9bcc 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServlet.java
@@ -127,7 +127,7 @@ public abstract class RestServlet extends HttpServlet {
 	// allow the config file to be accessed during object creation.
 	// e.g. private String myConfig = getConfig().getString("myConfig");
 	{
-		varResolver = createVarResolver();
+		VarResolverBuilder vrb = createVarResolver();
 
 		// @RestResource annotations from bottom to top.
 		restResourceAnnotationsChildFirst = ReflectionUtils.findAnnotationsMap(RestResource.class, getClass());
@@ -141,11 +141,13 @@ public abstract class RestServlet extends HttpServlet {
 		}
 
 		try {
-			configFile = createConfigFile();
-			varResolver.setContextObject(ConfigFileVar.SESSION_config, configFile);
+			configFile = createConfigFile(vrb);
+			vrb.contextObject(ConfigFileVar.SESSION_config, configFile);
 		} catch (IOException e) {
 			this.initException = e;
 		}
+
+		varResolver = vrb.build();
 	}
 
 	@Override /* Servlet */
@@ -204,14 +206,14 @@ public abstract class RestServlet extends HttpServlet {
 			properties = createProperties();
 			beanFilters = createBeanFilters();
 			pojoSwaps = createPojoSwaps();
-			context = ContextFactory.create().setProperties(properties).getContext(RestServletContext.class);
+			context = PropertyStore.create().setProperties(properties).getContext(RestServletContext.class);
 			beanContext = createBeanContext(properties, beanFilters, pojoSwaps);
-			urlEncodingSerializer = createUrlEncodingSerializer(properties, beanFilters, pojoSwaps).lock();
-			urlEncodingParser = createUrlEncodingParser(properties, beanFilters, pojoSwaps).lock();
-			serializers = createSerializers(properties, beanFilters, pojoSwaps).lock();
-			parsers = createParsers(properties, beanFilters, pojoSwaps).lock();
+			urlEncodingSerializer = createUrlEncodingSerializer(properties, beanFilters, pojoSwaps).build();
+			urlEncodingParser = createUrlEncodingParser(properties, beanFilters, pojoSwaps).build();
+			serializers = createSerializers(properties, beanFilters, pojoSwaps).build();
+			parsers = createParsers(properties, beanFilters, pojoSwaps).build();
 			converters = createConverters(properties);
-			encoders = createEncoders(properties);
+			encoders = createEncoders(properties).build();
 			guards = createGuards(properties);
 			mimetypesFileTypeMap = createMimetypesFileTypeMap(properties);
 			defaultRequestHeaders = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
@@ -253,13 +255,11 @@ public abstract class RestServlet extends HttpServlet {
 			for (RestServlet child : childResources.values())
 				child.init(servletConfig);
 
-			varResolver.addVars(
-				LocalizationVar.class,
-				RequestVar.class,
-				SerializedRequestAttrVar.class,
-				ServletInitParamVar.class,
-				UrlEncodeVar.class
-			);
+			varResolver = varResolver
+				.builder()
+				.vars(LocalizationVar.class, RequestVar.class, SerializedRequestAttrVar.class, ServletInitParamVar.class, UrlEncodeVar.class)
+				.build()
+			;
 
 		} catch (RestException e) {
 			// Thrown RestExceptions are simply caught and rethrown on subsequent calls to service().
@@ -460,7 +460,7 @@ public abstract class RestServlet extends HttpServlet {
 	 * @throws Exception If bean context not be constructed for any reason.
 	 */
 	protected BeanContext createBeanContext(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		return ContextFactory.create().addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps).setProperties(properties).getBeanContext();
+		return PropertyStore.create().addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps).setProperties(properties).getBeanContext();
 	}
 
 	/**
@@ -474,8 +474,8 @@ public abstract class RestServlet extends HttpServlet {
 	 * @return The new URL-Encoding serializer.
 	 * @throws Exception If the serializer could not be constructed for any reason.
 	 */
-	protected UrlEncodingSerializer createUrlEncodingSerializer(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		return new UrlEncodingSerializer().setProperties(properties).addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
+	protected UrlEncodingSerializerBuilder createUrlEncodingSerializer(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		return new UrlEncodingSerializerBuilder().properties(properties).beanFilters(beanFilters).pojoSwaps(pojoSwaps);
 	}
 
 	/**
@@ -489,8 +489,8 @@ public abstract class RestServlet extends HttpServlet {
 	 * @return The new URL-Encoding parser.
 	 * @throws Exception If the parser could not be constructed for any reason.
 	 */
-	protected UrlEncodingParser createUrlEncodingParser(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		return new UrlEncodingParser().setProperties(properties).addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
+	protected UrlEncodingParserBuilder createUrlEncodingParser(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		return new UrlEncodingParserBuilder().properties(properties).beanFilters(beanFilters).pojoSwaps(pojoSwaps);
 	}
 
 	/**
@@ -509,21 +509,14 @@ public abstract class RestServlet extends HttpServlet {
 	 * @return The group of serializers.
 	 * @throws Exception If serializer group could not be constructed for any reason.
 	 */
-	protected SerializerGroup createSerializers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		SerializerGroup g = new SerializerGroup();
+	protected SerializerGroupBuilder createSerializers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		SerializerGroupBuilder g = new SerializerGroupBuilder();
 
 		// Serializers are loaded in parent-to-child order to allow overrides.
 		for (RestResource r : restResourceAnnotationsParentFirst.values())
-			for (Class<? extends Serializer> c : reverse(r.serializers()))
-				try {
-					g.append(c);
-				} catch (Exception e) {
-					throw new RestServletException("Exception occurred while trying to instantiate Serializer ''{0}''", c.getSimpleName()).initCause(e);
-				}
+			g.append(reverse(r.serializers()));
 
-		g.setProperties(properties);
-		g.addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
-		return g;
+		return g.properties(properties).beanFilters(beanFilters).pojoSwaps(pojoSwaps);
 	}
 
 	/**
@@ -542,21 +535,14 @@ public abstract class RestServlet extends HttpServlet {
 	 * @return The group of parsers.
 	 * @throws Exception If parser group could not be constructed for any reason.
 	 */
-	protected ParserGroup createParsers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		ParserGroup g = new ParserGroup();
+	protected ParserGroupBuilder createParsers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		ParserGroupBuilder g = new ParserGroupBuilder();
 
 		// Parsers are loaded in parent-to-child order to allow overrides.
 		for (RestResource r : restResourceAnnotationsParentFirst.values())
-			for (Class<? extends Parser> p : reverse(r.parsers()))
-				try {
-					g.append(p);
-				} catch (Exception e) {
-					throw new RestServletException("Exception occurred while trying to instantiate Parser ''{0}''", p.getSimpleName()).initCause(e);
-				}
+			g.append(reverse(r.parsers()));
 
-		g.setProperties(properties);
-		g.addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
-		return g;
+		return g.properties(properties).beanFilters(beanFilters).pojoSwaps(pojoSwaps);
 	}
 
 	/**
@@ -599,8 +585,8 @@ public abstract class RestServlet extends HttpServlet {
 	 * @return The new encoder group associated with this servet.
 	 * @throws RestServletException
 	 */
-	protected EncoderGroup createEncoders(ObjectMap properties) throws RestServletException {
-		EncoderGroup g = new EncoderGroup().append(IdentityEncoder.INSTANCE);
+	protected EncoderGroupBuilder createEncoders(ObjectMap properties) throws RestServletException {
+		EncoderGroupBuilder g = new EncoderGroupBuilder().append(IdentityEncoder.INSTANCE);
 
 		// Encoders are loaded in parent-to-child order to allow overrides.
 		for (RestResource r : restResourceAnnotationsParentFirst.values())
@@ -1831,12 +1817,13 @@ public abstract class RestServlet extends HttpServlet {
 	 * <p>
 	 * The default implementation uses the path defined by the {@link RestResource#config() @RestResource.config()} property resolved
 	 * 	by {@link ConfigMgr#DEFAULT}.
+	 * @param vrb
 	 *
 	 * @return The config file for this servlet.
 	 * @throws IOException
 	 */
-	protected ConfigFile createConfigFile() throws IOException {
-		String cf = varResolver.resolve(configPath);
+	protected ConfigFile createConfigFile(VarResolverBuilder vrb) throws IOException {
+		String cf = vrb.build().resolve(configPath);
 		if (cf.isEmpty())
 			return getConfigMgr().create();
 		return getConfigMgr().get(cf);
@@ -1925,7 +1912,7 @@ public abstract class RestServlet extends HttpServlet {
 	}
 
 	/**
-	 * Returns the config manager used to create the config file in {@link #createConfigFile()}.
+	 * Returns the config manager used to create the config file in {@link #createConfigFile(VarResolverBuilder)}.
 	 * <p>
 	 * The default implementation return {@link ConfigMgr#DEFAULT}, but subclasses can override
 	 * 	this if they want to provide their own customized config manager.
@@ -2147,10 +2134,20 @@ public abstract class RestServlet extends HttpServlet {
 				ArrayList<Inherit> si = new ArrayList<Inherit>(Arrays.asList(m.serializersInherit()));
 				ArrayList<Inherit> pi = new ArrayList<Inherit>(Arrays.asList(m.parsersInherit()));
 
+				SerializerGroupBuilder sgb = null;
+				ParserGroupBuilder pgb = null;
+				UrlEncodingParserBuilder uepb = null;
+
 				if (m.serializers().length > 0 || m.parsers().length > 0 || m.properties().length > 0 || m.beanFilters().length > 0 || m.pojoSwaps().length > 0) {
-					mSerializers = (si.contains(SERIALIZERS) || m.serializers().length == 0 ? mSerializers.clone() : new SerializerGroup());
-					mParsers = (pi.contains(PARSERS) || m.parsers().length == 0 ? mParsers.clone() : new ParserGroup());
-					mUrlEncodingParser = mUrlEncodingParser.clone();
+					sgb = new SerializerGroupBuilder();
+					pgb = new ParserGroupBuilder();
+					uepb = new UrlEncodingParserBuilder(mUrlEncodingParser.createPropertyStore());
+
+					if (si.contains(SERIALIZERS) || m.serializers().length == 0)
+						sgb.append(mSerializers.getSerializers());
+
+					if (pi.contains(PARSERS) || m.parsers().length == 0)
+						pgb.append(mParsers.getParsers());
 				}
 
 				httpMethod = m.name().toUpperCase(Locale.ENGLISH);
@@ -2191,47 +2188,46 @@ public abstract class RestServlet extends HttpServlet {
 				this.requiredMatchers = requiredMatchers.toArray(new RestMatcher[requiredMatchers.size()]);
 				this.optionalMatchers = optionalMatchers.toArray(new RestMatcher[optionalMatchers.size()]);
 
-				if (m.serializers().length > 0) {
-					mSerializers.append(m.serializers());
+				if (sgb != null) {
+					sgb.append(m.serializers());
 					if (si.contains(TRANSFORMS))
-						mSerializers.addBeanFilters(getBeanFilters()).addPojoSwaps(getPojoSwaps());
+						sgb.beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps());
 					if (si.contains(PROPERTIES))
-						mSerializers.setProperties(getProperties());
+						sgb.properties(getProperties());
+					for (Property p1 : m.properties())
+						sgb.property(p1.name(), p1.value());
+					sgb.beanFilters(m.beanFilters());
+					sgb.pojoSwaps(m.pojoSwaps());
 				}
 
-				if (m.parsers().length > 0) {
-					mParsers.append(m.parsers());
+				if (pgb != null) {
+					pgb.append(m.parsers());
 					if (pi.contains(TRANSFORMS))
-						mParsers.addBeanFilters(getBeanFilters()).addPojoSwaps(getPojoSwaps());
+						pgb.beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps());
 					if (pi.contains(PROPERTIES))
-						mParsers.setProperties(getProperties());
+						pgb.properties(getProperties());
+					for (Property p1 : m.properties())
+						pgb.property(p1.name(), p1.value());
+					pgb.beanFilters(m.beanFilters());
+					pgb.pojoSwaps(m.pojoSwaps());
+				}
+
+				if (uepb != null) {
+					for (Property p1 : m.properties())
+						uepb.property(p1.name(), p1.value());
+					uepb.beanFilters(m.beanFilters());
+					uepb.pojoSwaps(m.pojoSwaps());
 				}
 
 				if (m.properties().length > 0) {
 					mProperties = new ObjectMap().setInner(getProperties());
 					for (Property p1 : m.properties()) {
-						String n = p1.name(), v = p1.value();
-						mProperties.put(n, v);
-						mSerializers.setProperty(n, v);
-						mParsers.setProperty(n, v);
-						mUrlEncodingParser.setProperty(n, v);
+						mProperties.put(p1.name(), p1.value());
 					}
 				}
 
-				if (m.beanFilters().length > 0) {
-					mSerializers.addBeanFilters(m.beanFilters());
-					mParsers.addBeanFilters(m.beanFilters());
-					mUrlEncodingParser.addBeanFilters(m.beanFilters());
-				}
-
-				if (m.pojoSwaps().length > 0) {
-					mSerializers.addPojoSwaps(m.pojoSwaps());
-					mParsers.addPojoSwaps(m.pojoSwaps());
-					mUrlEncodingParser.addPojoSwaps(m.pojoSwaps());
-				}
-
 				if (m.encoders().length > 0 || ! m.inheritEncoders()) {
-					EncoderGroup g = new EncoderGroup();
+					EncoderGroupBuilder g = new EncoderGroupBuilder();
 					if (m.inheritEncoders())
 						g.append(mEncoders);
 					else
@@ -2244,7 +2240,7 @@ public abstract class RestServlet extends HttpServlet {
 							throw new RestServletException("Exception occurred while trying to instantiate Encoder ''{0}''", c.getSimpleName()).initCause(e);
 						}
 					}
-					mEncoders = g;
+					mEncoders = g.build();
 				}
 
 				mDefaultRequestHeaders = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
@@ -2274,9 +2270,12 @@ public abstract class RestServlet extends HttpServlet {
 					}
 				}
 
-				mSerializers.lock();
-				mParsers.lock();
-				mUrlEncodingParser.lock();
+				if (sgb != null)
+					mSerializers = sgb.build();
+				if (pgb != null)
+					mParsers = pgb.build();
+				if (uepb != null)
+					mUrlEncodingParser = uepb.build();
 
 				// Need this to access methods in anonymous inner classes.
 				method.setAccessible(true);
@@ -2881,9 +2880,9 @@ public abstract class RestServlet extends HttpServlet {
 	 *
 	 * @return The reusable variable resolver for this servlet.
 	 */
-	protected VarResolver createVarResolver() {
-		return new VarResolver()
-			.addVars(
+	protected VarResolverBuilder createVarResolver() {
+		return new VarResolverBuilder()
+			.vars(
 				SystemPropertiesVar.class,
 				EnvVariablesVar.class,
 				ConfigFileVar.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletContext.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletContext.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletContext.java
index 1ea0340..f01c339 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletContext.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletContext.java
@@ -30,7 +30,7 @@ import org.apache.juneau.serializer.*;
  * Some of these properties are only applicable on the servlet class, and others can be specified on the servlet class or method.<br>
  * These distinctions are noted below.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  */
 public final class RestServletContext extends Context {
 
@@ -282,21 +282,21 @@ public final class RestServletContext extends Context {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public RestServletContext(ContextFactory cf) {
-		super(cf);
-		allowHeaderParams = cf.getProperty(REST_allowHeaderParams, boolean.class, true);
-		allowBodyParam = cf.getProperty(REST_allowBodyParam, boolean.class, true);
-		renderResponseStackTraces = cf.getProperty(REST_renderResponseStackTraces, boolean.class, false);
-		useStackTraceHashes = cf.getProperty(REST_useStackTraceHashes, boolean.class, true);
-		defaultCharset = cf.getProperty(REST_defaultCharset, String.class, "utf-8");
-		paramFormat = cf.getProperty(REST_paramFormat, String.class, "");
+	public RestServletContext(PropertyStore ps) {
+		super(ps);
+		allowHeaderParams = ps.getProperty(REST_allowHeaderParams, boolean.class, true);
+		allowBodyParam = ps.getProperty(REST_allowBodyParam, boolean.class, true);
+		renderResponseStackTraces = ps.getProperty(REST_renderResponseStackTraces, boolean.class, false);
+		useStackTraceHashes = ps.getProperty(REST_useStackTraceHashes, boolean.class, true);
+		defaultCharset = ps.getProperty(REST_defaultCharset, String.class, "utf-8");
+		paramFormat = ps.getProperty(REST_paramFormat, String.class, "");
 
 		Set<String> s = new LinkedHashSet<String>();
-		for (String m : StringUtils.split(cf.getProperty(REST_allowMethodParam, String.class, ""), ','))
+		for (String m : StringUtils.split(ps.getProperty(REST_allowMethodParam, String.class, ""), ','))
 			if (m.equals("true"))  // For backwards compatibility when this was a boolean field.
 				s.add("*");
 			else

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
index 2ad34af..8af7efe 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestServletDefault.java
@@ -23,6 +23,7 @@ import org.apache.juneau.msgpack.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.soap.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 
@@ -95,7 +96,7 @@ import org.apache.juneau.xml.*;
  * 	<tr>
  * 		<td class='code'>application/x-java-serialized-object</td>
  * 		<td class='code'>application/x-java-serialized-object</td>
- * 		<td>{@link JavaSerializedObjectSerializer}</td>
+ * 		<td>{@link JsoSerializer}</td>
  * 	</tr>
  * </table>
  * <p>
@@ -132,7 +133,7 @@ import org.apache.juneau.xml.*;
  * 	</tr>
  * </table>
  * <p>
- * It should be noted that we do NOT add {@link JavaSerializedObjectParser} to the list of parsers since this could
+ * It should be noted that we do NOT add {@link JsoParser} to the list of parsers since this could
  * 	cause security issues.  Use caution when using this particular parser as it could inadvertantly cause
  * 	code execution security holes.
  * <p>
@@ -168,7 +169,7 @@ import org.apache.juneau.xml.*;
 		MsgPackSerializer.class,
 		SoapXmlSerializer.class,
 		PlainTextSerializer.class,
-		JavaSerializedObjectSerializer.class
+		JsoSerializer.class
 	},
 	parsers={
 		JsonParser.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
index 3889b84..13adbc2 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/annotation/RestResource.java
@@ -593,4 +593,9 @@ public @interface RestResource {
 	 * If not specified, uses <js>"X-Client-Version"</js>.
 	 */
 	String clientVersionHeader() default "";
+
+	/**
+	 * TODO
+	 */
+	String[] links() default "";
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java b/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
index 76c7a66..fdfd0bb 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/jena/RestServletJenaDefault.java
@@ -25,6 +25,7 @@ import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.soap.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 
@@ -105,7 +106,7 @@ import org.apache.juneau.xml.*;
  * 	<tr>
  * 		<td class='code'>application/x-java-serialized-object</td>
  * 		<td class='code'>application/x-java-serialized-object</td>
- * 		<td>{@link JavaSerializedObjectSerializer}</td>
+ * 		<td>{@link JsoSerializer}</td>
  * 	</tr>
  * 	<tr>
  * 		<td class='code'>text/xml+rdf</td>
@@ -195,13 +196,12 @@ import org.apache.juneau.xml.*;
 		JsonSerializer.Simple.class,
 		JsonSchemaSerializer.class,
 		XmlDocSerializer.class,
-		XmlDocSerializer.Simple.class,
 		XmlSchemaDocSerializer.class,
 		UonSerializer.class,
 		UrlEncodingSerializer.class,
 		MsgPackSerializer.class,
 		SoapXmlSerializer.class,
-		JavaSerializedObjectSerializer.class,
+		JsoSerializer.class,
 		PlainTextSerializer.class,
 		RdfSerializer.Xml.class,
 		RdfSerializer.XmlAbbrev.class,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
index 27fc8a5..da2ff80 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/package.html
@@ -442,7 +442,7 @@
 		<tr>
 			<td class='code'>text/uon</td>
 			<td class='code'>text/uon</td>
-			<td>{@link org.apache.juneau.urlencoding.UonSerializer}</td>
+			<td>{@link org.apache.juneau.uon.UonSerializer}</td>
 		</tr>
 		<tr>
 			<td class='code'>application/x-www-form-urlencoded</td>
@@ -462,7 +462,7 @@
 		<tr>
 			<td class='code'>application/x-java-serialized-object</td>
 			<td class='code'>application/x-java-serialized-object</td>
-			<td>{@link org.apache.juneau.jso.JavaSerializedObjectSerializer}</td>
+			<td>{@link org.apache.juneau.jso.JsoSerializer}</td>
 		</tr>
 	</table>
 	<h6 class='figure'>Valid Content-Type headers for RestServletDefault</h6>
@@ -485,7 +485,7 @@
 		</tr>
 		<tr>
 			<td class='code'>text/uon</td>
-			<td>{@link org.apache.juneau.urlencoding.UonParser}</td>
+			<td>{@link org.apache.juneau.uon.UonParser}</td>
 		</tr>
 		<tr>
 			<td class='code'>application/x-www-form-urlencoded</td>
@@ -1321,12 +1321,10 @@
 
 	<jc>// Example #3 - Serializers defined on servlet by overriding the createSerializers(ObjectMap,Class[],Class[]) method</jc>
 	<ja>@Override</ja>
-	<jk>public</jk> SerializerGroup createSerializers(ObjectMap,Class[],Class[]) {
+	<jk>public</jk> SerializerGroupBuilder createSerializers(ObjectMap,Class[],Class[]) {
 
- 		SerializerGroup g = <jk>new</jk> SerializerGroup()
+ 		<jk>return new</jk> SerializerGroupBuilder()
  			.append(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
-
-		<jk>return</jk> g;
 	}
 		</p>
 		<p class='info'>
@@ -1382,12 +1380,10 @@
 	
 		<jc>// Example #3 - Parsers defined on servlet by overriding the getParserGroup method</jc>
 		<ja>@Override</ja>
-		<jk>public</jk> ParserGroup getParserGroup() {
+		<jk>public</jk> ParserGroupBuilder getParserGroup() {
 	
-	 		ParserGroup g = <jk>new</jk> ParserGroup()
+	 		<jk>return new</jk> ParserGroupBuilder()
 				.append(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
-	
-	 		<jk>return</jk> g;
 	 	}
 		</p>
 		<h6 class='topic'>Additional Information</h6>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/package.html b/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/package.html
index b6a9d7f..239ae95 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/package.html
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/remoteable/package.html
@@ -78,7 +78,7 @@
 	</p>
 	<p>
 		Proxy interfaces are retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method.
-		The {@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String)} method is used to specify the location
+		The {@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String)} method is used to specify the location
 			of the remoteable services servlet running on the server.
 		The remoteable servlet is a specialized subclass of {@link org.apache.juneau.rest.RestServlet} that provides a full-blown
 			REST interface for calling remoteable services (e.g. POJOs) remotely. 
@@ -99,8 +99,9 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>,JsonParser.<jk>class</jk>)
-		.setRemoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>);
+	RestClient client = <jk>new</jk> RestClientBuilder()
+		.remoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>)
+		.build();
 	
 	<jc>// Create a proxy interface.</jc>
 	IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>);
@@ -300,7 +301,7 @@
 	<img class='bordered' src="doc-files/6.png">
 	<p>
 		When specifying the POST body as a <code>&amp;content</code> parameter, the method arguments should be in UON notation.
-		See {@link org.apache.juneau.urlencoding.UonSerializer} for more information about this encoding.
+		See {@link org.apache.juneau.uon.UonSerializer} for more information about this encoding.
 		Usually you can also pass in JSON if you specify <code>&amp;Content-Type=text/json</code> in the URL parameters
 			but passing in unencoded JSON in a URL may not work in all browsers.  Therefore, UON is preferred.
 	</p>


[21/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JsoParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParser.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParser.java
new file mode 100644
index 0000000..fad986f
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParser.java
@@ -0,0 +1,59 @@
+// ***************************************************************************************************************************
+// * 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.jso;
+
+import java.io.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Parses POJOs from HTTP responses as Java {@link ObjectInputStream ObjectInputStreams}.
+ *
+ * <h5 class='section'>Media types:</h5>
+ * <p>
+ * Consumes <code>Content-Type</code> types: <code>application/x-java-serialized-object</code>
+ */
+@Consumes("application/x-java-serialized-object")
+public final class JsoParser extends InputStreamParser {
+
+	/** Default parser, all default settings.*/
+	public static final JsoParser DEFAULT = new JsoParser(PropertyStore.create());
+
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public JsoParser(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public JsoParserBuilder builder() {
+		return new JsoParserBuilder(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@SuppressWarnings("unchecked")
+	@Override /* InputStreamParser */
+	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
+		ObjectInputStream ois = new ObjectInputStream(session.getInputStream());
+		return (T)ois.readObject();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
new file mode 100644
index 0000000..2608028
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoParserBuilder.java
@@ -0,0 +1,457 @@
+// ***************************************************************************************************************************
+// * 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.jso;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building instances of Java Serialized Object parsers.
+ */
+public class JsoParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public JsoParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public JsoParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParser build() {
+		return new JsoParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* Parser */
+	public JsoParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* Parser */
+	public JsoParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public JsoParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* Parser */
+	public JsoParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* Parser */
+	public JsoParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CoreObjectBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializer.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializer.java
new file mode 100644
index 0000000..d95cdbe
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializer.java
@@ -0,0 +1,61 @@
+// ***************************************************************************************************************************
+// * 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.jso;
+
+import java.io.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Serializes POJOs to HTTP responses as Java Serialized Object {@link ObjectOutputStream ObjectOutputStreams}.
+ *
+ * <h5 class='section'>Media types:</h5>
+ * <p>
+ * Handles <code>Accept</code> types: <code>application/x-java-serialized-object</code>
+ * <p>
+ * Produces <code>Content-Type</code> types: <code>application/x-java-serialized-object</code>
+ */
+@Produces("application/x-java-serialized-object")
+public class JsoSerializer extends OutputStreamSerializer {
+
+	/** Default serializer, all default settings.*/
+	public static final JsoSerializer DEFAULT = new JsoSerializer(PropertyStore.create());
+
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public JsoSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public JsoSerializerBuilder builder() {
+		return new JsoSerializerBuilder(propertyStore);
+	}
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* OutputStreamSerializer */
+	protected void doSerialize(SerializerSession session, Object o) throws Exception {
+		ObjectOutputStream oos = new ObjectOutputStream(session.getOutputStream());
+		oos.writeObject(o);
+		oos.flush();
+		oos.close();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
new file mode 100644
index 0000000..c591b91
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/jso/JsoSerializerBuilder.java
@@ -0,0 +1,529 @@
+// ***************************************************************************************************************************
+// * 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.jso;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of Java Serialized Object serializers.
+ */
+public class JsoSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public JsoSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public JsoSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializer build() {
+		return new JsoSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsoSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> JsoSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsoSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
index d8197fc..24cd45e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParser.java
@@ -12,6 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.json;
 
+import static org.apache.juneau.parser.ParserContext.*;
+
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
@@ -48,7 +50,7 @@ import org.apache.juneau.transform.*;
  * 	<ul class='spaced-list'>
  * 		<li> JSON objects (<js>"{...}"</js>) are converted to {@link ObjectMap ObjectMaps}.  <br>
  * 				<b>Note:</b>  If a <code><xa>_type</xa>=<xs>'xxx'</xs></code> attribute is specified on the object, then an attempt is made to convert the object
- * 				to an instance of the specified Java bean class.  See the classProperty setting on the {@link ContextFactory} for more information
+ * 				to an instance of the specified Java bean class.  See the <code>beanTypeName</code> setting on the {@link PropertyStore} for more information
  * 				about parsing beans from JSON.
  * 		<li> JSON arrays (<js>"[...]"</js>) are converted to {@link ObjectList ObjectLists}.
  * 		<li> JSON string literals (<js>"'xyz'"</js>) are converted to {@link String Strings}.
@@ -83,16 +85,51 @@ import org.apache.juneau.transform.*;
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 @Consumes("application/json,text/json")
-public final class JsonParser extends ReaderParser {
+public class JsonParser extends ReaderParser {
 
 	/** Default parser, all default settings.*/
-	public static final JsonParser DEFAULT = new JsonParser().lock();
+	public static final JsonParser DEFAULT = new JsonParser(PropertyStore.create());
 
 	/** Default parser, all default settings.*/
-	public static final JsonParser DEFAULT_STRICT = new JsonParser().setStrict(true).lock();
+	public static final JsonParser DEFAULT_STRICT = new JsonParser.Strict(PropertyStore.create());
 
 	private static final AsciiSet decChars = new AsciiSet("0123456789");
 
+
+	/** Default parser, strict mode. */
+	public static class Strict extends JsonParser {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Strict(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(PARSER_strict, true);
+		}
+	}
+
+
+	private final JsonParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public JsonParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(JsonParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public JsonParserBuilder builder() {
+		return new JsonParserBuilder(propertyStore);
+	}
+
 	private <T> T parseAnything(JsonParserSession session, ClassMeta<T> eType, ParserReader r, Object outer, BeanPropertyMeta pMeta) throws Exception {
 
 		if (eType == null)
@@ -771,7 +808,7 @@ public final class JsonParser extends ReaderParser {
 
 	@Override /* Parser */
 	public JsonParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new JsonParserSession(getContext(JsonParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new JsonParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	@Override /* Parser */
@@ -811,425 +848,4 @@ public final class JsonParser extends ReaderParser {
 		validateEnd(s, r);
 		return a;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	@Override /* Parser */
-	public JsonParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public JsonParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public JsonParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public JsonParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> JsonParser addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public JsonParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public JsonParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public JsonParser clone() {
-		try {
-			return (JsonParser)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
new file mode 100644
index 0000000..ed550cc
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserBuilder.java
@@ -0,0 +1,457 @@
+// ***************************************************************************************************************************
+// * 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.json;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building instances of JSON parsers.
+ */
+public class JsonParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public JsonParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public JsonParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParser build() {
+		return new JsonParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* ParserBuilder */
+	public JsonParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public JsonParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public JsonParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public JsonParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public JsonParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> JsonParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserContext.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserContext.java
index c53d224..b3c5bcd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.parser.*;
 /**
  * Configurable properties on the {@link JsonParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -36,12 +36,12 @@ public final class JsonParserContext extends ParserContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public JsonParserContext(ContextFactory cf) {
-		super(cf);
+	public JsonParserContext(PropertyStore ps) {
+		super(ps);
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserSession.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserSession.java
index 6ce9d20..02ae190 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonParserSession.java
@@ -17,7 +17,6 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.MediaType;
 import org.apache.juneau.parser.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
index 91c4d72..c2c0c43 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializer.java
@@ -13,7 +13,9 @@
 package org.apache.juneau.json;
 
 import static org.apache.juneau.internal.ClassUtils.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
 
+import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
@@ -37,23 +39,29 @@ import org.apache.juneau.transform.*;
 @Produces(value="application/json+schema,text/json+schema",contentType="application/json")
 public final class JsonSchemaSerializer extends JsonSerializer {
 
+	private final JsonSerializerContext ctx;
+
 	/**
 	 * Constructor.
+	 * @param propertyStore Initialize with the specified config property store.
 	 */
-	public JsonSchemaSerializer() {
-		setDetectRecursions(true);
-		setIgnoreRecursions(true);
+	public JsonSchemaSerializer(PropertyStore propertyStore) {
+		this(propertyStore, null);
 	}
 
 	/**
 	 * Constructor.
-	 *
-	 * @param config Initialize with the specified config property store.
+	 * @param propertyStore Initialize with the specified config property store.
+	 * @param overrideProperties
 	 */
-	public JsonSchemaSerializer(ContextFactory config) {
-		getContextFactory().copyFrom(config);
-		setDetectRecursions(true);
-		setIgnoreRecursions(true);
+	public JsonSchemaSerializer(PropertyStore propertyStore, Map<String,Object> overrideProperties) {
+		super(propertyStore);
+		this.ctx = this.propertyStore.create(overrideProperties).getContext(JsonSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+ 	protected ObjectMap getOverrideProperties() {
+		return super.getOverrideProperties().append(SERIALIZER_detectRecursions, true).append(SERIALIZER_ignoreRecursions, true);
 	}
 
 
@@ -61,6 +69,11 @@ public final class JsonSchemaSerializer extends JsonSerializer {
 	// Entry point methods
 	//--------------------------------------------------------------------------------
 
+	@Override /* Serializer */
+	public JsonSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		return new JsonSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
+	}
+
 	@Override /* JsonSerializer */
 	protected void doSerialize(SerializerSession session, Object o) throws Exception {
 		JsonSerializerSession s = (JsonSerializerSession)session;
@@ -142,15 +155,4 @@ public final class JsonSchemaSerializer extends JsonSerializer {
 			l.add(e.toString());
 		return l;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Lockable */
-	public JsonSchemaSerializer lock() {
-		super.lock();
-		return this;
-	}
 }


[20/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
new file mode 100644
index 0000000..aab5768
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSchemaSerializerBuilder.java
@@ -0,0 +1,545 @@
+// ***************************************************************************************************************************
+// * 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.json;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Builder class for building instances of JSON Schema serializers.
+ */
+public class JsonSchemaSerializerBuilder extends JsonSerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public JsonSchemaSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public JsonSchemaSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializer build() {
+		return new JsonSchemaSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* JsonSerializerBuilder */
+	public JsonSchemaSerializerBuilder simple(boolean value) {
+		super.simple(value);
+		return this;
+	}
+
+	@Override /* JsonSerializerBuilder */
+	public JsonSchemaSerializerBuilder simple() {
+		super.simple();
+		return this;
+	}
+
+	@Override /* JsonSerializerBuilder */
+	public JsonSchemaSerializerBuilder escapeSolidus(boolean value) {
+		super.escapeSolidus(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSchemaSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> JsonSchemaSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSchemaSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
index 35c2b05..7464495 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializer.java
@@ -46,7 +46,7 @@ import org.apache.juneau.transform.*;
  * </ul>
  * <p>
  * The types above are considered "JSON-primitive" object types.  Any non-JSON-primitive object types are transformed
- * 	into JSON-primitive object types through {@link org.apache.juneau.transform.PojoSwap PojoSwaps} associated through the {@link CoreApi#addPojoSwaps(Class...)}
+ * 	into JSON-primitive object types through {@link org.apache.juneau.transform.PojoSwap PojoSwaps} associated through the {@link CoreObjectBuilder#pojoSwaps(Class...)}
  * 	method.  Several default transforms are provided for transforming Dates, Enums, Iterators, etc...
  * <p>
  * This serializer provides several serialization options.  Typically, one of the predefined DEFAULT serializers will be sufficient.
@@ -75,13 +75,10 @@ import org.apache.juneau.transform.*;
  * 	String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(someObject);
  *
  * 	<jc>// Create a custom serializer for lax syntax using single quote characters</jc>
- * 	JsonSerializer serializer = <jk>new</jk> JsonSerializer()
- * 		.setSimpleMode(<jk>true</jk>)
- * 		.setQuoteChar(<js>'\''</js>);
+ * 	JsonSerializer serializer = <jk>new</jk> JsonSerializerBuilder().simple().sq().build();
  *
  * 	<jc>// Clone an existing serializer and modify it to use single-quotes</jc>
- * 	JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.clone()
- * 		.setQuoteChar(<js>'\''</js>);
+ * 	JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.builder().sq().build();
  *
  * 	<jc>// Serialize a POJO to JSON</jc>
  * 	String json = serializer.serialize(someObject);
@@ -91,46 +88,73 @@ import org.apache.juneau.transform.*;
 public class JsonSerializer extends WriterSerializer {
 
 	/** Default serializer, all default settings.*/
-	public static final JsonSerializer DEFAULT = new JsonSerializer().lock();
+	public static final JsonSerializer DEFAULT = new JsonSerializer(PropertyStore.create());
 
 	/** Default serializer, all default settings.*/
-	public static final JsonSerializer DEFAULT_READABLE = new Readable().lock();
+	public static final JsonSerializer DEFAULT_READABLE = new Readable(PropertyStore.create());
 
 	/** Default serializer, single quotes, simple mode. */
-	public static final JsonSerializer DEFAULT_LAX = new Simple().lock();
+	public static final JsonSerializer DEFAULT_LAX = new Simple(PropertyStore.create());
 
 	/** Default serializer, single quotes, simple mode, with whitespace. */
-	public static final JsonSerializer DEFAULT_LAX_READABLE = new SimpleReadable().lock();
+	public static final JsonSerializer DEFAULT_LAX_READABLE = new SimpleReadable(PropertyStore.create());
 
 	/**
 	 * Default serializer, single quotes, simple mode, with whitespace and recursion detection.
 	 * Note that recursion detection introduces a small performance penalty.
 	 */
-	public static final JsonSerializer DEFAULT_LAX_READABLE_SAFE = new SimpleReadableSafe().lock();
+	public static final JsonSerializer DEFAULT_LAX_READABLE_SAFE = new SimpleReadableSafe(PropertyStore.create());
+
 
 	/** Default serializer, with whitespace. */
 	public static class Readable extends JsonSerializer {
-		/** Constructor */
-		public Readable() {
-			setUseWhitespace(true);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Readable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
 	/** Default serializer, single quotes, simple mode. */
 	@Produces(value="application/json+simple,text/json+simple",contentType="application/json")
 	public static class Simple extends JsonSerializer {
-		/** Constructor */
-		public Simple() {
-			setSimpleMode(true);
-			setQuoteChar('\'');
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Simple(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(JSON_simpleMode, true).append(SERIALIZER_quoteChar, '\'');
 		}
 	}
 
 	/** Default serializer, single quotes, simple mode, with whitespace. */
-	public static class SimpleReadable extends Simple {
-		/** Constructor */
-		public SimpleReadable() {
-			setUseWhitespace(true);
+	public static class SimpleReadable extends JsonSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public SimpleReadable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(JSON_simpleMode, true).append(SERIALIZER_quoteChar, '\'').append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
@@ -138,13 +162,41 @@ public class JsonSerializer extends WriterSerializer {
 	 * Default serializer, single quotes, simple mode, with whitespace and recursion detection.
 	 * Note that recursion detection introduces a small performance penalty.
 	 */
-	public static class SimpleReadableSafe extends SimpleReadable {
-		/** Constructor */
-		public SimpleReadableSafe() {
-			setDetectRecursions(true);
+	public static class SimpleReadableSafe extends JsonSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public SimpleReadableSafe(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(JSON_simpleMode, true).append(SERIALIZER_quoteChar, '\'').append(SERIALIZER_useWhitespace, true).append(SERIALIZER_detectRecursions, true);
 		}
 	}
 
+
+	private final JsonSerializerContext ctx;
+	private volatile JsonSchemaSerializer schemaSerializer;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public JsonSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(JsonSerializerContext.class);
+//		this.schemaSerializer = new JsonSchemaSerializer(propertyStore, getOverrideProperties());
+	}
+
+	@Override /* CoreObject */
+	public JsonSerializerBuilder builder() {
+		return new JsonSerializerBuilder(propertyStore);
+	}
+
 	/**
 	 * Workhorse method. Determines the type of object, and then calls the
 	 * appropriate type-specific serialization method.
@@ -317,8 +369,9 @@ public class JsonSerializer extends WriterSerializer {
 	 * @return The schema serializer.
 	 */
 	public JsonSchemaSerializer getSchemaSerializer() {
-		JsonSchemaSerializer s = new JsonSchemaSerializer(getContextFactory());
-		return s;
+		if (schemaSerializer == null)
+			schemaSerializer = new JsonSchemaSerializer(propertyStore, getOverrideProperties());
+		return schemaSerializer;
 	}
 
 
@@ -328,7 +381,7 @@ public class JsonSerializer extends WriterSerializer {
 
 	@Override /* Serializer */
 	public JsonSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new JsonSerializerSession(getContext(JsonSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new JsonSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* Serializer */
@@ -336,547 +389,4 @@ public class JsonSerializer extends WriterSerializer {
 		JsonSerializerSession s = (JsonSerializerSession)session;
 		serializeAnything(s, s.getWriter(), o, null, "root", null);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Simple JSON mode.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"JsonSerializer.simpleMode"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, JSON attribute names will only be quoted when necessary.
-	 * Otherwise, they are always quoted.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>JSON_simpleMode</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see JsonSerializerContext#JSON_simpleMode
-	 */
-	public JsonSerializer setSimpleMode(boolean value) throws LockedException {
-		return setProperty(JSON_simpleMode, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Prefix solidus <js>'/'</js> characters with escapes.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"JsonSerializer.escapeSolidus"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, solidus (e.g. slash) characters should be escaped.
-	 * The JSON specification allows for either format.
-	 * However, if you're embedding JSON in an HTML script tag, this setting prevents
-	 * 	confusion when trying to serialize <xt>&lt;\/script&gt;</xt>.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>JSON_escapeSolidus</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see JsonSerializerContext#JSON_escapeSolidus
-	 */
-	public JsonSerializer setEscapeSolidus(boolean value) throws LockedException {
-		return setProperty(JSON_escapeSolidus, value);
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public JsonSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-	@Override /* CoreApi */
-	public JsonSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public JsonSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public JsonSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public JsonSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public JsonSerializer clone() {
-		try {
-			JsonSerializer c = (JsonSerializer)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
new file mode 100644
index 0000000..b226459
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerBuilder.java
@@ -0,0 +1,594 @@
+// ***************************************************************************************************************************
+// * 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.json;
+
+import static org.apache.juneau.json.JsonSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of JSON serializers.
+ */
+public class JsonSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public JsonSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public JsonSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializer build() {
+		return new JsonSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Simple JSON mode.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"JsonSerializer.simpleMode"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, JSON attribute names will only be quoted when necessary.
+	 * Otherwise, they are always quoted.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>JSON_simpleMode</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see JsonSerializerContext#JSON_simpleMode
+	 */
+	public JsonSerializerBuilder simple(boolean value) {
+		return property(JSON_simpleMode, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>setSimpleMode(<jk>true</jk>).sq()</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public JsonSerializerBuilder simple() {
+		return simple(true).sq();
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Prefix solidus <js>'/'</js> characters with escapes.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"JsonSerializer.escapeSolidus"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, solidus (e.g. slash) characters should be escaped.
+	 * The JSON specification allows for either format.
+	 * However, if you're embedding JSON in an HTML script tag, this setting prevents
+	 * 	confusion when trying to serialize <xt>&lt;\/script&gt;</xt>.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>JSON_escapeSolidus</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see JsonSerializerContext#JSON_escapeSolidus
+	 */
+	public JsonSerializerBuilder escapeSolidus(boolean value) {
+		return property(JSON_escapeSolidus, value);
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public JsonSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> JsonSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public JsonSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java
index 9b0afc5..b8ecde8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.serializer.*;
 /**
  * Configurable properties on the {@link JsonSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -92,15 +92,15 @@ public final class JsonSerializerContext extends SerializerContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public JsonSerializerContext(ContextFactory cf) {
-		super(cf);
-		simpleMode = cf.getProperty(JSON_simpleMode, boolean.class, false);
-		escapeSolidus = cf.getProperty(JSON_escapeSolidus, boolean.class, false);
-		addBeanTypeProperties = cf.getProperty(JSON_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	public JsonSerializerContext(PropertyStore ps) {
+		super(ps);
+		simpleMode = ps.getProperty(JSON_simpleMode, boolean.class, false);
+		escapeSolidus = ps.getProperty(JSON_escapeSolidus, boolean.class, false);
+		addBeanTypeProperties = ps.getProperty(JSON_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
index ec5498f..dd8b8a1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/json/JsonSerializerSession.java
@@ -40,7 +40,7 @@ public final class JsonSerializerSession extends SerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/json/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/json/package.html b/juneau-core/src/main/java/org/apache/juneau/json/package.html
index 50443bb..06e6db6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/json/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/json/package.html
@@ -276,11 +276,7 @@
 		We could have also created a new serializer with the same settings using the following code:
 	</p>
 	<p class='bcode'>
-	JsonSerializer s = <jk>new</jk> JsonSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setUseWhitespace(<jk>true</jk>)
-		.setSimpleMode(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	JsonSerializer s = <jk>new</jk> JsonSerializerBuilder().simple().ws().sq().build();
 	</p>
 	
 	<p>
@@ -648,7 +644,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Clone an existing serializer and set property for detecting recursions.</jc>
-	JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.clone().setDetectRecursions(<jk>true</jk>);
+	JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.builder().detectRecursions(<jk>true</jk>).build();
 
 	<jc>// Create a recursive loop.</jc>
 	A a = <jk>new</jk> A();
@@ -1277,7 +1273,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a client to handle JSON requests and responses.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>);
+	RestClient client = <jk>new</jk> RestClientBuilder().build();
 		</p>
 		<p>
 			The client handles all content negotiation based on the registered serializers and parsers.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
index 358f3d2..ce4db63 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParser.java
@@ -38,10 +38,27 @@ import org.apache.juneau.transform.*;
  */
 @SuppressWarnings({ "rawtypes", "unchecked" })
 @Consumes("octal/msgpack")
-public final class MsgPackParser extends InputStreamParser {
+public class MsgPackParser extends InputStreamParser {
 
 	/** Default parser, all default settings.*/
-	public static final MsgPackParser DEFAULT = new MsgPackParser().lock();
+	public static final MsgPackParser DEFAULT = new MsgPackParser(PropertyStore.create());
+
+
+	private final MsgPackParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public MsgPackParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(MsgPackParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public MsgPackParserBuilder builder() {
+		return new MsgPackParserBuilder(propertyStore);
+	}
 
 	/**
 	 * Workhorse method.
@@ -186,7 +203,7 @@ public final class MsgPackParser extends InputStreamParser {
 
 	@Override /* Parser */
 	public MsgPackParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new MsgPackParserSession(getContext(MsgPackParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new MsgPackParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	@Override /* Parser */
@@ -196,425 +213,4 @@ public final class MsgPackParser extends InputStreamParser {
 		T o = parseAnything(s, type, is, s.getOuter(), null);
 		return o;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	@Override /* Parser */
-	public MsgPackParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public MsgPackParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public MsgPackParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public MsgPackParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public MsgPackParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public MsgPackParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public MsgPackParser clone() {
-		try {
-			return (MsgPackParser)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
 }


[15/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
index 1f3e218..33fad70 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroup.java
@@ -12,12 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.serializer;
 
-import static org.apache.juneau.internal.ArrayUtils.*;
-
 import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
 
 /**
  * Represents a group of {@link Serializer Serializers} that can be looked up by media type.
@@ -45,87 +44,40 @@ import org.apache.juneau.*;
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Construct a new serializer group</jc>
- * 	SerializerGroup g = <jk>new</jk> SerializerGroup();
- *
- * 	<jc>// Add some serializers to it</jc>
- * 	g.append(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
- *
- * 	<jc>// Change settings for all serializers in the group and lock it.</jc>
- * 	g.setProperty(SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, <jk>true</jk>)
- * 		.addPojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>)
- * 		.lock();
+ * 	SerializerGroup g = <jk>new</jk> SerializerGroupBuilder();
+ * 		.append(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>); <jc>// Add some serializers to it</jc>
+ * 		.ws().pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>) <jc>// Change settings for all serializers in the group.</jc>
+ * 		.build();
  *
  * 	<jc>// Find the appropriate serializer by Accept type</jc>
  * 	String mediaTypeMatch = g.findMatch(<js>"text/foo, text/json;q=0.8, text/*;q:0.6, *\/*;q=0.0"</js>);
- * 	WriterSerializer s = (WriterSerializer)g.getSerializer(mediaTypeMatch);
+ * 	WriterSerializer s = g.getWriterSerializer(mediaTypeMatch);
  *
  * 	<jc>// Serialize a bean to JSON text </jc>
  * 	AddressBook addressBook = <jk>new</jk> AddressBook();  <jc>// Bean to serialize.</jc>
  * 	String json = s.serialize(addressBook);
  * </p>
  */
-public final class SerializerGroup extends Lockable {
+public final class SerializerGroup {
 
 	// Maps Accept headers to matching serializers.
 	private final Map<String,SerializerMatch> cache = new ConcurrentHashMap<String,SerializerMatch>();
 
-	private final CopyOnWriteArrayList<Serializer> serializers = new CopyOnWriteArrayList<Serializer>();
-
-	/**
-	 * Adds the specified serializer to the beginning of this group.
-	 *
-	 * @param s The serializer to add to this group.
-	 * @return This object (for method chaining).
-	 */
-	public SerializerGroup append(Serializer s) {
-		checkLock();
-		synchronized(this) {
-			cache.clear();
-			serializers.add(0, s);
-		}
-		return this;
-	}
-
-	/**
-	 * Registers the specified serializers with this group.
-	 *
-	 * @param s The serializers to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Serializer} could not be constructed.
-	 */
-	public SerializerGroup append(Class<? extends Serializer>...s) throws Exception {
-		for (Class<? extends Serializer> ss : reverse(s))
-			append(ss);
-		return this;
-	}
+	final Serializer[] serializers;
+	private final PropertyStore propertyStore;
 
 	/**
-	 * Same as {@link #append(Class[])}, except specify a single class to avoid unchecked compile warnings.
+	 * Constructor.
 	 *
-	 * @param s The serializer to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Serializer} could not be constructed.
+	 * @param propertyStore The modifiable properties that were used to initialize the serializers.
+	 * A snapshot of these will be made so that we can clone and modify this group.
+	 * @param serializers The serializers defined in this group.
+	 * The order is important because they will be tried in reverse order (e.g.
+	 * 	newer first) in which they will be tried to match against media types.
 	 */
-	public SerializerGroup append(Class<? extends Serializer> s) throws Exception {
-		try {
-			append(s.newInstance());
-		} catch (NoClassDefFoundError e) {
-			// Ignore if dependent library not found (e.g. Jena).
-			System.err.println(e); // NOT DEBUG
-		}
-		return this;
-	}
-
-	/**
-	 * Adds the serializers in the specified group to this group.
-	 *
-	 * @param g The group containing the serializers to add to this group.
-	 * @return This object (for method chaining).
-	 */
-	public SerializerGroup append(SerializerGroup g) {
-		for (Serializer s : reverse(g.serializers.toArray(new Serializer[g.serializers.size()])))
-			append(s);
-		return this;
+	public SerializerGroup(PropertyStore propertyStore, Serializer[] serializers) {
+		this.propertyStore = PropertyStore.create(propertyStore);
+		this.serializers = ArrayUtils.reverse(serializers);
 	}
 
 	/**
@@ -224,9 +176,9 @@ public final class SerializerGroup extends Lockable {
 	}
 
 	/**
-	 * Returns the media types that all parsers in this group can handle
+	 * Returns the media types that all serializers in this group can handle.
 	 * <p>
-	 * Entries are ordered in the same order as the parsers in the group.
+	 * Entries are ordered in the same order as the serializers in the group.
 	 *
 	 * @return The list of media types.
 	 */
@@ -239,1225 +191,23 @@ public final class SerializerGroup extends Lockable {
 		return l;
 	}
 
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * Calls {@link Serializer#setMaxDepth(int)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_maxDepth
-	 */
-	public SerializerGroup setMaxDepth(int value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setMaxDepth(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setInitialDepth(int)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_initialDepth
-	 */
-	public SerializerGroup setInitialDepth(int value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setInitialDepth(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setDetectRecursions(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_detectRecursions
-	 */
-	public SerializerGroup setDetectRecursions(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setDetectRecursions(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnoreRecursions(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_ignoreRecursions
-	 */
-	public SerializerGroup setIgnoreRecursions(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnoreRecursions(value);
-		return this;
-	}
-
 	/**
-	 * Calls {@link Serializer#setUseWhitespace(boolean)} on all serializers in this group.
+	 * Returns a copy of the property store that was used to create the serializers in this group.
+	 * This method returns a new factory each time so is somewhat expensive.
 	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_useWhitespace
+	 * @return A new copy of the property store passed in to the constructor.
 	 */
-	public SerializerGroup setUseWhitespace(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setUseWhitespace(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setAddBeanTypeProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_addBeanTypeProperties
-	 */
-	public SerializerGroup setAddBeanTypeProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setQuoteChar(char)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_quoteChar
-	 */
-	public SerializerGroup setQuoteChar(char value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setQuoteChar(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setTrimNullProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimNullProperties
-	 */
-	public SerializerGroup setTrimNullProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setTrimNullProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setTrimEmptyCollections(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimEmptyCollections
-	 */
-	public SerializerGroup setTrimEmptyCollections(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setTrimEmptyMaps(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimEmptyMaps
-	 */
-	public SerializerGroup setTrimEmptyMaps(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setTrimStrings(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimStrings
-	 */
-	public SerializerGroup setTrimStrings(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setTrimStrings(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setRelativeUriBase(String)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_relativeUriBase
-	 */
-	public SerializerGroup setRelativeUriBase(String value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setRelativeUriBase(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setAbsolutePathUriBase(String)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_absolutePathUriBase
-	 */
-	public SerializerGroup setAbsolutePathUriBase(String value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setSortCollections(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_sortCollections
-	 */
-	public SerializerGroup setSortCollections(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setSortCollections(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setSortMaps(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_sortMaps
-	 */
-	public SerializerGroup setSortMaps(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setSortMaps(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeansRequireDefaultConstructor(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
-	 */
-	public SerializerGroup setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeansRequireSerializable(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSerializable
-	 */
-	public SerializerGroup setBeansRequireSerializable(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeansRequireSettersForGetters(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSettersForGetters
-	 */
-	public SerializerGroup setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeansRequireSomeProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSomeProperties
-	 */
-	public SerializerGroup setBeansRequireSomeProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanMapPutReturnsOldValue(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
-	 */
-	public SerializerGroup setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanConstructorVisibility(Visibility)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanConstructorVisibility
-	 */
-	public SerializerGroup setBeanConstructorVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanClassVisibility(Visibility)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanClassVisibility
-	 */
-	public SerializerGroup setBeanClassVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanClassVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanFieldVisibility(Visibility)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFieldVisibility
-	 */
-	public SerializerGroup setBeanFieldVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setMethodVisibility(Visibility)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_methodVisibility
-	 */
-	public SerializerGroup setMethodVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setMethodVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setUseJavaBeanIntrospector(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useJavaBeanIntrospector
-	 */
-	public SerializerGroup setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setUseInterfaceProxies(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useInterfaceProxies
-	 */
-	public SerializerGroup setUseInterfaceProxies(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnoreUnknownBeanProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
-	 */
-	public SerializerGroup setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnoreUnknownNullBeanProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
-	 */
-	public SerializerGroup setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnorePropertiesWithoutSetters(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
-	 */
-	public SerializerGroup setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnoreInvocationExceptionsOnGetters(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
-	 */
-	public SerializerGroup setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setIgnoreInvocationExceptionsOnSetters(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
-	 */
-	public SerializerGroup setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setSortProperties(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_sortProperties
-	 */
-	public SerializerGroup setSortProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setSortProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setNotBeanPackages(String...)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public SerializerGroup setNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setNotBeanPackages(Collection)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public SerializerGroup setNotBeanPackages(Collection<String> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addNotBeanPackages(String...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public SerializerGroup addNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addNotBeanPackages(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public SerializerGroup addNotBeanPackages(Collection<String> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeNotBeanPackages(String...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public SerializerGroup removeNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeNotBeanPackages(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public SerializerGroup removeNotBeanPackages(Collection<String> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeNotBeanPackages(values);
-		return this;
+	public PropertyStore createPropertyStore() {
+		return PropertyStore.create(propertyStore);
 	}
 
 	/**
-	 * Calls {@link Serializer#setNotBeanClasses(Class...)} on all serializers in this group.
+	 * Returns a copy of the serializers in this group.
+	 * This method returns a new array each time so is somewhat expensive.
 	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
+	 * @return A new array containing the serializers in this group.
 	 */
-	public SerializerGroup setNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setNotBeanClasses(Collection)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public SerializerGroup setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addNotBeanClasses(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public SerializerGroup addNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addNotBeanClasses(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public SerializerGroup addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeNotBeanClasses(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public SerializerGroup removeNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeNotBeanClasses(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public SerializerGroup removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanFilters(Class...)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public SerializerGroup setBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanFilters(Collection)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public SerializerGroup setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addBeanFilters(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public SerializerGroup addBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addBeanFilters(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public SerializerGroup addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeBeanFilters(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public SerializerGroup removeBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeBeanFilters(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public SerializerGroup removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setPojoSwaps(Class...)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public SerializerGroup setPojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setPojoSwaps(Collection)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public SerializerGroup setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addPojoSwaps(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
-	 */
-	public SerializerGroup addPojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addPojoSwaps(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
-	 */
-	public SerializerGroup addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removePojoSwaps(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
-	 */
-	public SerializerGroup removePojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removePojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removePojoSwaps(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
-	 */
-	public SerializerGroup removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removePojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setImplClasses(Map)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 */
-	public SerializerGroup setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setImplClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addImplClass(Class,Class)} on all serializers in this group.
-	 *
-	 * @param interfaceClass The interface class.
-	 * @param implClass The implementation class.
-	 * @param <T> The class type of the interface.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 * @see BeanContext#BEAN_implClasses_put
-	 */
-	public <T> SerializerGroup addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanDictionary(Class...)} on all serializers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 */
-	public SerializerGroup setBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanDictionary(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public SerializerGroup setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addToBeanDictionary(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public SerializerGroup addToBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addToBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addToBeanDictionary(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public SerializerGroup addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addToBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeFromBeanDictionary(Class...)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public SerializerGroup removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeFromBeanDictionary(Collection)} on all serializers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public SerializerGroup removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setBeanTypePropertyName(String)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanTypePropertyName
-	 */
-	public SerializerGroup setBeanTypePropertyName(String value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setDefaultParser(Class)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_defaultParser
-	 */
-	public SerializerGroup setDefaultParser(Class<?> value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setDefaultParser(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setLocale(Locale)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_locale
-	 */
-	public SerializerGroup setLocale(Locale value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setLocale(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setTimeZone(TimeZone)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_timeZone
-	 */
-	public SerializerGroup setTimeZone(TimeZone value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setTimeZone(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setMediaType(MediaType)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_mediaType
-	 */
-	public SerializerGroup setMediaType(MediaType value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setMediaType(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setDebug(boolean)} on all serializers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_debug
-	 */
-	public SerializerGroup setDebug(boolean value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setDebug(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setProperty(String,Object)} on all serializers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The property value.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object or {@link ContextFactory} object.
-	 * @see ContextFactory#setProperty(String, Object)
-	 */
-	public SerializerGroup setProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#setProperties(ObjectMap)} on all serializers in this group.
-	 *
-	 * @param properties The properties to set on this class.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 * @see ContextFactory#setProperties(java.util.Map)
-	 */
-	public SerializerGroup setProperties(ObjectMap properties) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setProperties(properties);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#addToProperty(String,Object)} on all serializers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The new value to add to the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public SerializerGroup addToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.addToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#putToProperty(String,Object,Object)} on all serializers in this group.
-	 *
-	 * @param name The property name.
-	 * @param key The property value map key.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public SerializerGroup putToProperty(String name, Object key, Object value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.putToProperty(name, key, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#putToProperty(String,Object)} on all serializers in this group.
-	 *
-	 * @param name The property value.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public SerializerGroup putToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.putToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Serializer#removeFromProperty(String,Object)} on all serializers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The property value in the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public SerializerGroup removeFromProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * Calls {@link Serializer#setClassLoader(ClassLoader)} on all serializers in this group.
-	 *
-	 * @param classLoader The new classloader.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#setClassLoader(ClassLoader)
-	 */
-	public SerializerGroup setClassLoader(ClassLoader classLoader) throws LockedException {
-		checkLock();
-		for (Serializer s : serializers)
-			s.setClassLoader(classLoader);
-		return this;
-	}
-
-	/**
-	 * Locks this group and all serializers in this group.
-	 */
-	@Override /* Lockable */
-	public SerializerGroup lock() {
-		super.lock();
-		for (Serializer s : serializers)
-			s.lock();
-		return this;
-	}
-
-	/**
-	 * Clones this group and all serializers in this group.
-	 */
-	@Override /* Lockable */
-	public SerializerGroup clone() throws CloneNotSupportedException {
-		SerializerGroup g = new SerializerGroup();
-
-		List<Serializer> l = new ArrayList<Serializer>(serializers.size());
-		for (Serializer s : serializers)
-			l.add(s.clone());
-
-		g.serializers.addAll(l);
-
-		return g;
+	public Serializer[] getSerializers() {
+		return ArrayUtils.reverse(serializers);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
new file mode 100644
index 0000000..b639358
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerGroupBuilder.java
@@ -0,0 +1,983 @@
+// ***************************************************************************************************************************
+// * 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.serializer;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Builder class for creating instances of {@link SerializerGroup}.
+ */
+public class SerializerGroupBuilder {
+
+	private final List<Object> serializers;
+	private final PropertyStore propertyStore;
+
+	/**
+	 * Create an empty serializer group builder.
+	 */
+	public SerializerGroupBuilder() {
+		this.serializers = new ArrayList<Object>();
+		this.propertyStore = PropertyStore.create();
+	}
+
+	/**
+	 * Clone an existing serializer group builder.
+	 * @param copyFrom The serializer group that we're copying settings and serializers from.
+	 */
+	public SerializerGroupBuilder(SerializerGroup copyFrom) {
+		this.serializers = new ArrayList<Object>(Arrays.asList(copyFrom.serializers));
+		this.propertyStore = copyFrom.createPropertyStore();
+	}
+
+	/**
+	 * Registers the specified serializers with this group.
+	 *
+	 * @param s The serializers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public SerializerGroupBuilder append(Class<?>...s) {
+		serializers.addAll(Arrays.asList(s));
+		return this;
+	}
+
+	/**
+	 * Registers the specified serializers with this group.
+	 *
+	 * @param s The serializers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public SerializerGroupBuilder append(Serializer...s) {
+		serializers.addAll(Arrays.asList(s));
+		return this;
+	}
+
+	/**
+	 * Registers the specified serializers with this group.
+	 *
+	 * @param s The serializers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public SerializerGroupBuilder append(List<Serializer> s) {
+		serializers.addAll(s);
+		return this;
+	}
+
+	/**
+	 * Creates a new {@link SerializerGroup} object using a snapshot of the settings defined in this builder.
+	 * <p>
+	 * This method can be called multiple times to produce multiple serializer groups.
+	 *
+	 * @return A new {@link SerializerGroup} object.
+	 */
+	@SuppressWarnings("unchecked")
+	public SerializerGroup build() {
+		List<Serializer> l = new ArrayList<Serializer>();
+		for (Object s : serializers) {
+			Class<? extends Serializer> c = null;
+			PropertyStore ps = propertyStore;
+			if (s instanceof Class) {
+				c = ((Class<? extends Serializer>)s);
+			} else {
+				// Note that if we added a serializer instance, we want a new instance with this builder's properties
+				// on top of the previous serializer's properties.
+				Serializer s2 = (Serializer)s;
+				ps = s2.createPropertyStore().copyFrom(propertyStore);
+				c = s2.getClass();
+			}
+			try {
+				l.add(c.getConstructor(PropertyStore.class).newInstance(ps));
+			} catch (Exception e) {
+				throw new RuntimeException("Could not instantiate serializer " + c.getName(), e);
+			}
+		}
+		return new SerializerGroup(propertyStore, l.toArray(new Serializer[l.size()]));
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Sets a property on all serializers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The property value.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 */
+	public SerializerGroupBuilder property(String name, Object value) {
+		propertyStore.setProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Sets a set of properties on all serializers in this group.
+	 *
+	 * @param properties The properties to set on this class.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperties(java.util.Map)
+	 */
+	public SerializerGroupBuilder properties(ObjectMap properties) {
+		propertyStore.setProperties(properties);
+		return this;
+	}
+
+	/**
+	 * Adds a value to a SET property on all serializers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The new value to add to the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public SerializerGroupBuilder addToProperty(String name, Object value) {
+		propertyStore.addToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property on all serializers in this group.
+	 *
+	 * @param name The property name.
+	 * @param key The property value map key.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public SerializerGroupBuilder putToProperty(String name, Object key, Object value) {
+		propertyStore.putToProperty(name, key, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property on all serializers in this group.
+	 *
+	 * @param name The property value.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public SerializerGroupBuilder putToProperty(String name, Object value) {
+		propertyStore.putToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Removes a value from a SET property on all serializers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The property value in the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public SerializerGroupBuilder removeFromProperty(String name, Object value) {
+		propertyStore.removeFromProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_maxDepth} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_maxDepth
+	 */
+	public SerializerGroupBuilder maxDepth(int value) {
+		return property(SERIALIZER_maxDepth, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_initialDepth} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_initialDepth
+	 */
+	public SerializerGroupBuilder initialDepth(int value) {
+		return property(SERIALIZER_initialDepth, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_detectRecursions} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_detectRecursions
+	 */
+	public SerializerGroupBuilder detectRecursions(boolean value) {
+		return property(SERIALIZER_detectRecursions, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_ignoreRecursions} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_ignoreRecursions
+	 */
+	public SerializerGroupBuilder ignoreRecursions(boolean value) {
+		return property(SERIALIZER_ignoreRecursions, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_useWhitespace} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_useWhitespace
+	 */
+	public SerializerGroupBuilder useWhitespace(boolean value) {
+		return property(SERIALIZER_useWhitespace, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_addBeanTypeProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_addBeanTypeProperties
+	 */
+	public SerializerGroupBuilder addBeanTypeProperties(boolean value) {
+		return property(SERIALIZER_addBeanTypeProperties, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_quoteChar} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_quoteChar
+	 */
+	public SerializerGroupBuilder quoteChar(char value) {
+		return property(SERIALIZER_quoteChar, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimNullProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimNullProperties
+	 */
+	public SerializerGroupBuilder trimNullProperties(boolean value) {
+		return property(SERIALIZER_trimNullProperties, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimEmptyCollections} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyCollections
+	 */
+	public SerializerGroupBuilder trimEmptyCollections(boolean value) {
+		return property(SERIALIZER_trimEmptyCollections, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimEmptyMaps} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyMaps
+	 */
+	public SerializerGroupBuilder trimEmptyMaps(boolean value) {
+		return property(SERIALIZER_trimEmptyMaps, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimStrings} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimStrings
+	 */
+	public SerializerGroupBuilder trimStrings(boolean value) {
+		return property(SERIALIZER_trimStrings, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_relativeUriBase} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_relativeUriBase
+	 */
+	public SerializerGroupBuilder relativeUriBase(String value) {
+		return property(SERIALIZER_relativeUriBase, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_absolutePathUriBase} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_absolutePathUriBase
+	 */
+	public SerializerGroupBuilder absolutePathUriBase(String value) {
+		return property(SERIALIZER_absolutePathUriBase, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_sortCollections} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortCollections
+	 */
+	public SerializerGroupBuilder sortCollections(boolean value) {
+		return property(SERIALIZER_sortCollections, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_sortMaps} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortMaps
+	 */
+	public SerializerGroupBuilder sortMaps(boolean value) {
+		return property(SERIALIZER_sortMaps, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireDefaultConstructor} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
+	 */
+	public SerializerGroupBuilder beansRequireDefaultConstructor(boolean value) {
+		return property(BEAN_beansRequireDefaultConstructor, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSerializable} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSerializable
+	 */
+	public SerializerGroupBuilder beansRequireSerializable(boolean value) {
+		return property(BEAN_beansRequireSerializable, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSettersForGetters} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSettersForGetters
+	 */
+	public SerializerGroupBuilder beansRequireSettersForGetters(boolean value) {
+		return property(BEAN_beansRequireSettersForGetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSomeProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSomeProperties
+	 */
+	public SerializerGroupBuilder beansRequireSomeProperties(boolean value) {
+		return property(BEAN_beansRequireSomeProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanMapPutReturnsOldValue} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
+	 */
+	public SerializerGroupBuilder beanMapPutReturnsOldValue(boolean value) {
+		return property(BEAN_beanMapPutReturnsOldValue, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanConstructorVisibility} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanConstructorVisibility
+	 */
+	public SerializerGroupBuilder beanConstructorVisibility(Visibility value) {
+		return property(BEAN_beanConstructorVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanClassVisibility} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanClassVisibility
+	 */
+	public SerializerGroupBuilder beanClassVisibility(Visibility value) {
+		return property(BEAN_beanClassVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFieldVisibility} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFieldVisibility
+	 */
+	public SerializerGroupBuilder beanFieldVisibility(Visibility value) {
+		return property(BEAN_beanFieldVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_methodVisibility} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_methodVisibility
+	 */
+	public SerializerGroupBuilder methodVisibility(Visibility value) {
+		return property(BEAN_methodVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_useJavaBeanIntrospector} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useJavaBeanIntrospector
+	 */
+	public SerializerGroupBuilder useJavaBeanIntrospector(boolean value) {
+		return property(BEAN_useJavaBeanIntrospector, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_useInterfaceProxies} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useInterfaceProxies
+	 */
+	public SerializerGroupBuilder useInterfaceProxies(boolean value) {
+		return property(BEAN_useInterfaceProxies, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreUnknownBeanProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
+	 */
+	public SerializerGroupBuilder ignoreUnknownBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownBeanProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreUnknownNullBeanProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
+	 */
+	public SerializerGroupBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownNullBeanProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignorePropertiesWithoutSetters} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
+	 */
+	public SerializerGroupBuilder ignorePropertiesWithoutSetters(boolean value) {
+		return property(BEAN_ignorePropertiesWithoutSetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreInvocationExceptionsOnGetters} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
+	 */
+	public SerializerGroupBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnGetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreInvocationExceptionsOnSetters} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
+	 */
+	public SerializerGroupBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnSetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_sortProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_sortProperties
+	 */
+	public SerializerGroupBuilder sortProperties(boolean value) {
+		return property(BEAN_sortProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public SerializerGroupBuilder notBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_add} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public SerializerGroupBuilder notBeanPackages(Collection<String> value) {
+		return property(BEAN_notBeanPackages_add, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public SerializerGroupBuilder setNotBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public SerializerGroupBuilder setNotBeanPackages(Collection<String> values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public SerializerGroupBuilder removeNotBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public SerializerGroupBuilder removeNotBeanPackages(Collection<String> values) {
+		return property(BEAN_notBeanPackages_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_add
+	 */
+	public SerializerGroupBuilder notBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public SerializerGroupBuilder notBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public SerializerGroupBuilder setNotBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public SerializerGroupBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public SerializerGroupBuilder removeNotBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public SerializerGroupBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public SerializerGroupBuilder beanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public SerializerGroupBuilder beanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public SerializerGroupBuilder setBeanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public SerializerGroupBuilder setBeanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public SerializerGroupBuilder removeBeanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public SerializerGroupBuilder removeBeanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public SerializerGroupBuilder pojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public SerializerGroupBuilder pojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public SerializerGroupBuilder setPojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public SerializerGroupBuilder setPojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public SerializerGroupBuilder removePojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public SerializerGroupBuilder removePojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_implClasses} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 */
+	public SerializerGroupBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		return property(BEAN_implClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_implClasses_put} property on all serializers in this group.
+	 *
+	 * @param interfaceClass The interface class.
+	 * @param implClass The implementation class.
+	 * @param <T> The class type of the interface.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 * @see BeanContext#BEAN_implClasses_put
+	 */
+	public <T> SerializerGroupBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		return putToProperty(BEAN_implClasses, interfaceClass, implClass);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_add} property on all serializers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public SerializerGroupBuilder beanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_add} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public SerializerGroupBuilder beanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public SerializerGroupBuilder setBeanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary} property on all serializers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public SerializerGroupBuilder setBeanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public SerializerGroupBuilder removeFromBeanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_remove} property on all serializers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public SerializerGroupBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanTypePropertyName} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanTypePropertyName
+	 */
+	public SerializerGroupBuilder beanTypePropertyName(String value) {
+		return property(BEAN_beanTypePropertyName, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_defaultParser} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_defaultParser
+	 */
+	public SerializerGroupBuilder defaultParser(Class<?> value) {
+		return property(BEAN_defaultParser, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_locale} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_locale
+	 */
+	public SerializerGroupBuilder locale(Locale value) {
+		return property(BEAN_locale, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_timeZone} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_timeZone
+	 */
+	public SerializerGroupBuilder timeZone(TimeZone value) {
+		return property(BEAN_timeZone, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_mediaType} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_mediaType
+	 */
+	public SerializerGroupBuilder mediaType(MediaType value) {
+		return property(BEAN_mediaType, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_debug} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_debug
+	 */
+	public SerializerGroupBuilder debug(boolean value) {
+		return property(BEAN_debug, value);
+	}
+
+	/**
+	 * Specifies the classloader to use when resolving classes from strings for all serializers in this group.
+	 * <p>
+	 * Can be used for resolving class names when the classes being created are in a different
+	 * 	classloader from the Juneau code.
+	 * <p>
+	 * If <jk>null</jk>, the system classloader will be used to resolve classes.
+	 *
+	 * @param classLoader The new classloader.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setClassLoader(ClassLoader)
+	 */
+	public SerializerGroupBuilder classLoader(ClassLoader classLoader) {
+		propertyStore.setClassLoader(classLoader);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
index 34477b7..2fdfd0b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerSession.java
@@ -86,7 +86,7 @@ public class SerializerSession extends BeanSession {
 	 * </ul>
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.


[29/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
index 63db46c..538a2d6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonTest.java
@@ -24,20 +24,19 @@ import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.jena.annotation.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.testbeans.*;
 import org.junit.*;
 
 @SuppressWarnings({"serial","javadoc"})
 public class CommonTest {
 
-	private RdfSerializer getBasicSerializer() {
-		return new RdfSerializer()
-			.setQuoteChar('\'')
-			.setUseWhitespace(false)
-			.setProperty(RDF_rdfxml_allowBadUris, true)
-			.setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
-			.setProperty(RDF_rdfxml_showXmlDeclaration, false);
+	private RdfSerializerBuilder getBasicSerializer() {
+		return new RdfSerializerBuilder()
+			.sq()
+			.useWhitespace(false)
+			.property(RDF_rdfxml_allowBadUris, true)
+			.property(RDF_rdfxml_showDoctypeDeclaration, false)
+			.property(RDF_rdfxml_showXmlDeclaration, false);
 	}
 
 	private String strip(String s) {
@@ -49,18 +48,18 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:s1 rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:s2>s2</jp:s2></rdf:Description>", strip(r));
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:s2>s2</jp:s2></rdf:Description>", strip(r));
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -81,19 +80,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f1 rdf:parseType='Resource'></jp:f1><jp:f2 rdf:parseType='Resource'><jp:f2a rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:f2b rdf:parseType='Resource'><jp:s2>s2</jp:s2></jp:f2b></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f2 rdf:parseType='Resource'><jp:f2a rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><jp:f2b rdf:parseType='Resource'><jp:s2>s2</jp:s2></jp:f2b></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, B.class);
 		assertNull(t2.f1);
@@ -115,19 +114,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f1><rdf:Seq/></jp:f1><jp:f2><rdf:Seq><rdf:li rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f2><rdf:Seq><rdf:li rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, C.class);
 		assertNull(t2.f1);
@@ -150,19 +149,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f1><rdf:Seq/></jp:f1><jp:f2><rdf:Seq><rdf:li rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:f2><rdf:Seq><rdf:li rdf:resource='http://www.w3.org/1999/02/22-rdf-syntax-ns#nil'/><rdf:li rdf:parseType='Resource'><jp:s2>s2</jp:s2></rdf:li></rdf:Seq></jp:f2></rdf:Description>", strip(r));
 		t2 = p.parse(r, D.class);
 		assertNull(t2.f1);
@@ -184,12 +183,12 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testBeanPropertyProperties() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		E1 t1 = E1.create(), t2;
 		String r;
 
-		r = s.serialize(t1);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description><jp:x1 rdf:parseType='Resource'><jp:f1>1</jp:f1></jp:x1><jp:x2 rdf:parseType='Resource'><jp:f1>1</jp:f1></jp:x2><jp:x3><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x3><jp:x4><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x4><jp:x5><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x5><jp:x6><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:f1>1</jp:f1></rdf:li></rdf:Seq></jp:x6></rdf:Description>", strip(r));
 		t2 = p.parse(r, E1.class);
 		assertEqualObjects(t1, t2);
@@ -225,14 +224,14 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testBeanPropertyProperiesOnListOfBeans() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		List<F> l1 = new LinkedList<F>(), l2;
 		F t = F.create();
 		t.x1.add(F.create());
 		l1.add(t);
 
-		String r = s.serialize(l1);
+		String r = s.build().serialize(l1);
 		assertEquals("<rdf:Seq><rdf:li rdf:parseType='Resource'><jp:x1><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:x2>2</jp:x2></rdf:li></rdf:Seq></jp:x1><jp:x2>2</jp:x2></rdf:li></rdf:Seq>", strip(r));
 		l2 = p.parse(r, LinkedList.class, F.class);
 		assertEqualObjects(l1, l2);
@@ -255,7 +254,7 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testURIAttr() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 
 		G t = new G();
@@ -263,7 +262,7 @@ public class CommonTest {
 		t.f1 = new URI("http://f1");
 		t.f2 = new URL("http://f2");
 
-		String xml = s.serialize(t);
+		String xml = s.build().serialize(t);
 		t = p.parse(xml, G.class);
 		assertEquals("http://uri", t.uri.toString());
 		assertEquals("http://f1", t.f1.toString());
@@ -281,13 +280,13 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		WriterSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		TestURI t = new TestURI();
 		String r;
 		String expected = "";
 
-		s.setRelativeUriBase(null);
-		r = stripAndSort(s.serialize(t));
+		s.relativeUriBase(null);
+		r = stripAndSort(s.build().serialize(t));
 		expected = ""
 			+"</rdf:Description>>"
 			+"\n<<rdf:Description rdf:about='f0/x0'>"
@@ -308,12 +307,12 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = stripAndSort(s.serialize(t));
+		s.relativeUriBase("");  // Same as null.
+		r = stripAndSort(s.build().serialize(t));
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = stripAndSort(s.serialize(t));
+		s.relativeUriBase("/cr");
+		r = stripAndSort(s.build().serialize(t));
 		expected = ""
 			+"</rdf:Description>>"
 			+"\n<<rdf:Description rdf:about='/cr/f0/x0'>"
@@ -334,12 +333,12 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = stripAndSort(s.serialize(t));
+		s.relativeUriBase("/cr/");  // Same as above
+		r = stripAndSort(s.build().serialize(t));
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = stripAndSort(s.serialize(t));
+		s.relativeUriBase("/");
+		r = stripAndSort(s.build().serialize(t));
 		expected = ""
 			+"</rdf:Description>>"
 			+"\n<<rdf:Description rdf:about='/f0/x0'>"
@@ -360,10 +359,10 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = stripAndSort(s.serialize(t));
+		s.absolutePathUriBase("http://foo");
+		r = stripAndSort(s.build().serialize(t));
 		expected = ""
 			+"</rdf:Description>>"
 			+"\n<<rdf:Description rdf:about='f0/x0'>"
@@ -384,12 +383,12 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = stripAndSort(s.serialize(t));
+		s.absolutePathUriBase("http://foo/");
+		r = stripAndSort(s.build().serialize(t));
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = stripAndSort(s.serialize(t));
+		s.absolutePathUriBase("");  // Same as null.
+		r = stripAndSort(s.build().serialize(t));
 		expected = ""
 			+"</rdf:Description>>"
 			+"\n<<rdf:Description rdf:about='f0/x0'>"
@@ -420,27 +419,11 @@ public class CommonTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		RdfSerializer s = getBasicSerializer().lock();
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		WriterSerializer s = new RdfSerializer.XmlAbbrev().setQuoteChar('\'');
+		RdfSerializerBuilder s = new RdfSerializerBuilder().xmlabbrev().sq();
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -451,7 +434,7 @@ public class CommonTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -459,9 +442,9 @@ public class CommonTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -471,8 +454,8 @@ public class CommonTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.jena.CommonTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		String r = s.serialize(r1).replace("\r", "");
+		s.ignoreRecursions(true);
+		String r = s.build().serialize(r1).replace("\r", "");
 		// Note...the order of the namespaces is not always the same depending on the JVM.
 		// The Jena libraries appear to use a hashmap for these.
 		assertTrue(r.contains(

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
index bb5c8f0..00ccbb7 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonXmlTest.java
@@ -25,13 +25,13 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class CommonXmlTest {
 
-	private RdfSerializer getBasicSerializer() {
-		return new RdfSerializer()
-			.setQuoteChar('\'')
-			.setUseWhitespace(false)
-			.setProperty(RDF_rdfxml_allowBadUris, true)
-			.setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
-			.setProperty(RDF_rdfxml_showXmlDeclaration, false);
+	private RdfSerializerBuilder getBasicSerializer() {
+		return new RdfSerializerBuilder()
+			.sq()
+			.useWhitespace(false)
+			.property(RDF_rdfxml_allowBadUris, true)
+			.property(RDF_rdfxml_showDoctypeDeclaration, false)
+			.property(RDF_rdfxml_showXmlDeclaration, false);
 	}
 
 	private String strip(String s) {
@@ -43,12 +43,12 @@ public class CommonXmlTest {
 	//====================================================================================================
 	@Test
 	public void testBeanUriAnnotation() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		A t1 = A.create(), t2;
 		String r;
 
-		r = s.serialize(t1);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description rdf:about='http://foo'><jp:name>bar</jp:name></rdf:Description>", strip(r));
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -71,12 +71,12 @@ public class CommonXmlTest {
 	//====================================================================================================
 	@Test
 	public void testBeanUriAnnotationOnlyUriProperty() throws Exception {
-		RdfSerializer s = getBasicSerializer();
+		RdfSerializerBuilder s = getBasicSerializer();
 		RdfParser p = RdfParser.DEFAULT_XML;
 		B t1 = B.create(), t2;
 		String r;
 
-		r = s.serialize(t1);
+		r = s.build().serialize(t1);
 		assertEquals("<rdf:Description rdf:about='http://foo'><jp:url2 rdf:resource='http://foo/2'/></rdf:Description>", strip(r));
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
index 8bd50c7..ef4bca6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfParserTest.java
@@ -45,10 +45,11 @@ public class RdfParserTest {
 		A a = new A().init();
 
 		// Create a new serializer with readable output.
-		RdfSerializer s = new RdfSerializer.XmlAbbrev()
-		   .setProperty(RDF_rdfxml_tab, 3)
-		   .setQuoteChar('\'')
-		   .setAddRootProperty(true);
+		RdfSerializer s = new RdfSerializerBuilder().xmlabbrev()
+		   .property(RDF_rdfxml_tab, 3)
+		   .sq()
+		   .addRootProperty(true)
+		   .build();
 
 		String expected =
 			 "<rdf:RDF a='http://ns/' a1='http://ns2/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
index 678520f..c8bfebb 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/RdfTest.java
@@ -15,7 +15,7 @@ package org.apache.juneau.jena;
 import static org.apache.juneau.TestUtils.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
 
-import java.net.URI;
+import java.net.*;
 import java.util.*;
 
 import org.apache.juneau.jena.annotation.*;
@@ -32,11 +32,11 @@ public class RdfTest {
 		String rdfXml;
 		String expected;
 
-		RdfSerializer s = new RdfSerializer.XmlAbbrev()
-		   .setProperty(RDF_rdfxml_tab, 3)
-		   .setQuoteChar('\'')
-		   .setAddRootProperty(true);
-		RdfParser p = RdfParser.DEFAULT_XML.clone();
+		RdfSerializerBuilder s = new RdfSerializerBuilder().xmlabbrev()
+		   .property(RDF_rdfxml_tab, 3)
+		   .sq()
+		   .addRootProperty(true);
+		RdfParser p = new RdfParserBuilder().xml().build();
 
 		//--------------------------------------------------------------------------------
 		// Normal format - Sequence
@@ -59,7 +59,7 @@ public class RdfTest {
 			+ "\n      <j:root>true</j:root>"
 			+ "\n   </rdf:Description>"
 			+ "\n</rdf:RDF>";
-		rdfXml = s.serialize(a);
+		rdfXml = s.build().serialize(a);
 		assertXmlEquals(expected, rdfXml);
 
 		a2 = p.parse(rdfXml, A.class);
@@ -68,7 +68,7 @@ public class RdfTest {
 		//--------------------------------------------------------------------------------
 		// Explicit sequence
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.SEQ);
+		s.collectionFormat(RdfCollectionFormat.SEQ);
 		expected =
 			"<rdf:RDF a='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			+ "\n   <rdf:Description about='http://test/a'>"
@@ -87,7 +87,7 @@ public class RdfTest {
 			+ "\n      <j:root>true</j:root>"
 			+ "\n   </rdf:Description>"
 			+ "\n</rdf:RDF>";
-		rdfXml = s.serialize(a);
+		rdfXml = s.build().serialize(a);
 		assertXmlEquals(expected, rdfXml);
 
 		a2 = p.parse(rdfXml, A.class);
@@ -96,7 +96,7 @@ public class RdfTest {
 		//--------------------------------------------------------------------------------
 		// Bag
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.BAG);
+		s.collectionFormat(RdfCollectionFormat.BAG);
 		expected =
 			"<rdf:RDF a='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			+ "\n   <rdf:Description about='http://test/a'>"
@@ -115,7 +115,7 @@ public class RdfTest {
 			+ "\n      <j:root>true</j:root>"
 			+ "\n   </rdf:Description>"
 			+ "\n</rdf:RDF>";
-		rdfXml = s.serialize(a);
+		rdfXml = s.build().serialize(a);
 		assertXmlEquals(expected, rdfXml);
 
 		a2 = p.parse(rdfXml, A.class);
@@ -124,7 +124,7 @@ public class RdfTest {
 		//--------------------------------------------------------------------------------
 		// List
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.LIST);
+		s.collectionFormat(RdfCollectionFormat.LIST);
 		expected =
 			   "<rdf:RDF a='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			 + "\n   <rdf:Description about='http://test/a'>"
@@ -145,7 +145,7 @@ public class RdfTest {
 			 + "\n      <j:root>true</j:root>"
 			 + "\n   </rdf:Description>"
 			 + "\n</rdf:RDF>";
-		rdfXml = s.serialize(a);
+		rdfXml = s.build().serialize(a);
 		assertXmlEquals(expected, rdfXml);
 
 		a2 = p.parse(rdfXml, A.class);
@@ -154,7 +154,7 @@ public class RdfTest {
 		//--------------------------------------------------------------------------------
 		// Multi-properties
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.MULTI_VALUED);
+		s.collectionFormat(RdfCollectionFormat.MULTI_VALUED);
 		expected =
 			"<rdf:RDF a='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			+ "\n   <rdf:Description about='http://test/a'>"
@@ -165,11 +165,11 @@ public class RdfTest {
 			 + "\n      <j:root>true</j:root>"
 			 + "\n   </rdf:Description>"
 			+ "\n</rdf:RDF>";
-		rdfXml = s.serialize(a);
+		rdfXml = s.build().serialize(a);
 		assertXmlEquals(expected, rdfXml);
 
 		// Note - Must specify collection format on parser for it to be able to understand this layout.
-		p.setCollectionFormat(RdfCollectionFormat.MULTI_VALUED);
+		p = new RdfParserBuilder().xml().collectionFormat(RdfCollectionFormat.MULTI_VALUED).build();
 		a2 = p.parse(rdfXml, A.class);
 		assertEqualObjects(a, a2);
 	}
@@ -192,11 +192,11 @@ public class RdfTest {
 	public void testCollectionFormatAnnotations() throws Exception {
 		B b = new B().init(), b2;
 		String rdfXml, expected;
-		RdfSerializer s = new RdfSerializer.XmlAbbrev()
-		   .setProperty(RDF_rdfxml_tab, 3)
-		   .setQuoteChar('\'')
-		   .setAddRootProperty(true);
-		RdfParser p = RdfParser.DEFAULT_XML.clone();
+		RdfSerializerBuilder s = new RdfSerializerBuilder().xmlabbrev()
+		   .property(RDF_rdfxml_tab, 3)
+		   .sq()
+		   .addRootProperty(true);
+		RdfParser p = RdfParser.DEFAULT_XML;
 
 		//--------------------------------------------------------------------------------
 		// Normal format - Sequence
@@ -262,7 +262,7 @@ public class RdfTest {
 			 + "\n      <j:root>true</j:root>"
 			 + "\n   </rdf:Description>"
 			 + "\n</rdf:RDF>";
-		rdfXml = s.serialize(b);
+		rdfXml = s.build().serialize(b);
 		assertXmlEquals(expected, rdfXml);
 
 		b2 = p.parse(rdfXml, B.class);
@@ -271,7 +271,7 @@ public class RdfTest {
 		//--------------------------------------------------------------------------------
 		// Default is Bag - Should only affect DEFAULT properties.
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.BAG);
+		s.collectionFormat(RdfCollectionFormat.BAG);
 		expected =
 			 "<rdf:RDF b='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			 + "\n   <rdf:Description about='http://test/b'>"
@@ -333,7 +333,7 @@ public class RdfTest {
 			 + "\n   </rdf:Description>"
 			 + "\n</rdf:RDF>";
 
-		rdfXml = s.serialize(b);
+		rdfXml = s.build().serialize(b);
 		assertXmlEquals(expected, rdfXml);
 
 		b2 = p.parse(rdfXml, B.class);
@@ -425,16 +425,16 @@ public class RdfTest {
 	public void testCollectionFormatAnnotationOnClass() throws Exception {
 		C c = new C().init(), c2;
 		String rdfXml, expected;
-		RdfSerializer s = new RdfSerializer.XmlAbbrev()
-		   .setProperty(RDF_rdfxml_tab, 3)
-		   .setQuoteChar('\'')
-		   .setAddRootProperty(true);
-		RdfParser p = RdfParser.DEFAULT_XML.clone();
+		RdfSerializerBuilder s = new RdfSerializerBuilder().xmlabbrev()
+		   .property(RDF_rdfxml_tab, 3)
+		   .sq()
+		   .addRootProperty(true);
+		RdfParser p = RdfParser.DEFAULT_XML;
 
 		//--------------------------------------------------------------------------------
 		// Default on class is Bag - Should only affect DEFAULT properties.
 		//--------------------------------------------------------------------------------
-		s.setCollectionFormat(RdfCollectionFormat.BAG);
+		s.collectionFormat(RdfCollectionFormat.BAG);
 		expected =
 			 "<rdf:RDF b='http://ns/' j='http://www.apache.org/juneau/' jp='http://www.apache.org/juneaubp/' rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'>"
 			 + "\n   <rdf:Description about='http://test/b'>"
@@ -496,7 +496,7 @@ public class RdfTest {
 			 + "\n   </rdf:Description>"
 			 + "\n</rdf:RDF>";
 
-		rdfXml = s.serialize(c);
+		rdfXml = s.build().serialize(c);
 		assertXmlEquals(expected, rdfXml);
 
 		c2 = p.parse(rdfXml, C.class);
@@ -524,8 +524,8 @@ public class RdfTest {
 
 	@Test
 	public void testLooseCollectionsOfBeans() throws Exception {
-		WriterSerializer s = new RdfSerializer.XmlAbbrev().setLooseCollections(true);
-		ReaderParser p = new RdfParser.Xml().setLooseCollections(true);
+		WriterSerializer s = new RdfSerializerBuilder().xmlabbrev().looseCollections(true).build();
+		ReaderParser p = new RdfParserBuilder().xml().looseCollections(true).build();
 		String rdfXml, expected;
 
 		List<D> l = new LinkedList<D>();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
index 04d067d..c3e4688 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonParserTest.java
@@ -29,7 +29,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testFromSerializer() throws Exception {
-		ReaderParser p = JsonParser.DEFAULT.clone().addToBeanDictionary(A1.class);
+		ReaderParser p = new JsonParserBuilder().beanDictionary(A1.class).build();
 
 		Map m = null;
 		m = (Map)p.parse("{a:1}", Object.class);
@@ -83,7 +83,7 @@ public class CommonParserTest {
 		tl.add(new A3("name0","value0"));
 		tl.add(new A3("name1","value1"));
 		b.list = tl;
-		String json = new JsonSerializer().setAddBeanTypeProperties(true).addToBeanDictionary(A1.class).serialize(b);
+		String json = new JsonSerializerBuilder().addBeanTypeProperties(true).beanDictionary(A1.class).build().serialize(b);
 		b = (A1)p.parse(json, Object.class);
 		assertEquals("value1", b.list.get(1).value);
 
@@ -114,7 +114,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new JsonParser().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new JsonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		B b;
 
 		String in =  "{a:1,unknown:3,b:2}";
@@ -123,7 +123,7 @@ public class CommonParserTest {
 		assertEquals(b.b, 2);
 
 		try {
-			p = new JsonParser();
+			p = JsonParser.DEFAULT;
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -162,7 +162,7 @@ public class CommonParserTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		JsonParser p = new JsonParser().setIgnoreUnknownBeanProperties(true);
+		JsonParser p = new JsonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
index 460ec61..316f96e 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/CommonTest.java
@@ -21,7 +21,6 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.testbeans.*;
 import org.junit.*;
 
@@ -33,18 +32,18 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 		JsonParser p = JsonParser.DEFAULT;
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("{s1:null,s2:'s2'}", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("{s2:'s2'}", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -65,19 +64,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 		JsonParser p = JsonParser.DEFAULT;
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("{f1:{},f2:{f2a:null,f2b:{s2:'s2'}}}", r);
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("{f2:{f2a:null,f2b:{s2:'s2'}}}", r);
 		t2 = p.parse(r, B.class);
 		assertNull(t2.f1);
@@ -99,19 +98,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 		JsonParser p = JsonParser.DEFAULT;
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
 		t2 = p.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("{f2:[null,{s2:'s2'}]}", r);
 		t2 = p.parse(r, C.class);
 		assertNull(t2.f1);
@@ -133,19 +132,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 		JsonParser p = JsonParser.DEFAULT;
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("{f1:[],f2:[null,{s2:'s2'}]}", r);
 		t2 = p.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("{f2:[null,{s2:'s2'}]}", r);
 		t2 = p.parse(r, D.class);
 		assertNull(t2.f1);
@@ -247,13 +246,13 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 		TestURI t = new TestURI();
 		String r;
 		String expected = "";
 
-		s.setRelativeUriBase(null);
-		r = s.serialize(t);
+		s.relativeUriBase(null);
+		r = s.build().serialize(t);
 		expected = "{"
 			+"f0:'f0/x0',"
 			+"f1:'f1/x1',"
@@ -273,12 +272,12 @@ public class CommonTest {
 			+"}";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.relativeUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = s.serialize(t);
+		s.relativeUriBase("/cr");
+		r = s.build().serialize(t);
 		expected = "{"
 			+"f0:'/cr/f0/x0',"
 			+"f1:'/cr/f1/x1',"
@@ -298,12 +297,12 @@ public class CommonTest {
 			+"}";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = s.serialize(t);
+		s.relativeUriBase("/cr/");  // Same as above
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = s.serialize(t);
+		s.relativeUriBase("/");
+		r = s.build().serialize(t);
 		expected = "{"
 			+"f0:'/f0/x0',"
 			+"f1:'/f1/x1',"
@@ -323,10 +322,10 @@ public class CommonTest {
 			+"}";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo");
+		r = s.build().serialize(t);
 		expected = "{"
 			+"f0:'f0/x0',"
 			+"f1:'f1/x1',"
@@ -346,12 +345,12 @@ public class CommonTest {
 			+"}";
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo/");
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.absolutePathUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		expected = "{"
 			+"f0:'f0/x0',"
 			+"f1:'f1/x1',"
@@ -373,31 +372,11 @@ public class CommonTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		JsonSerializer s = new JsonSerializer().lock();
-		try {
-			s.setSimpleMode(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple();
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -408,7 +387,7 @@ public class CommonTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -416,9 +395,9 @@ public class CommonTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -428,11 +407,11 @@ public class CommonTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.json.CommonTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		assertEquals("{name:'foo',r2:{name:'bar',r3:{name:'baz'}}}", s.serialize(r1));
+		s.ignoreRecursions(true);
+		assertEquals("{name:'foo',r2:{name:'bar',r3:{name:'baz'}}}", s.build().serialize(r1));
 
 		// Make sure this doesn't blow up.
-		s.getSchemaSerializer().serialize(r1);
+		s.build().getSchemaSerializer().serialize(r1);
 	}
 
 	public static class R1 {
@@ -453,7 +432,7 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testBasicBean() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple().setTrimNullProperties(false).setSortProperties(true);
+		JsonSerializer s = new JsonSerializerBuilder().simple().trimNullProperties(false).sortProperties(true).build();
 
 		J a = new J();
 		a.setF1("J");

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
index 9068ed5..0f6316f 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonParserEdgeCasesTest.java
@@ -366,11 +366,11 @@ public class JsonParserEdgeCasesTest {
 
 	@Test
 	public void testStrict() throws Exception {
-		Parser p = JsonParser.DEFAULT_STRICT;
+		JsonParser p = JsonParser.DEFAULT_STRICT;
 		if (name.contains("utf16LE"))
-			p = p.clone().setInputStreamCharset("UTF-16LE");
+			p = p.builder().inputStreamCharset("UTF-16LE").build();
 		else if (name.contains("utf16BE"))
-			p = p.clone().setInputStreamCharset("UTF-16BE");
+			p = p.builder().inputStreamCharset("UTF-16BE").build();
 
 		// 'y' tests should always succeed.
 		if (expected == 'y') {
@@ -405,11 +405,11 @@ public class JsonParserEdgeCasesTest {
 
 	@Test
 	public void testLax() throws Exception {
-		Parser p = JsonParser.DEFAULT;
+		JsonParser p = JsonParser.DEFAULT;
 		if (name.contains("utf16LE"))
-			p = p.clone().setInputStreamCharset("UTF-16LE");
+			p = p.builder().inputStreamCharset("UTF-16LE").build();
 		else if (name.contains("utf16BE"))
-			p = p.clone().setInputStreamCharset("UTF-16BE");
+			p = p.builder().inputStreamCharset("UTF-16BE").build();
 
 		// 'y' tests should always succeed.
 		if (expected == 'y') {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/json/JsonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonTest.java
index ecbcae7..120cde4 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/json/JsonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/json/JsonTest.java
@@ -33,8 +33,8 @@ public class JsonTest {
 		Map<String,Object> m = new LinkedHashMap<String,Object>();
 		List<Object> l = new LinkedList<Object>();
 
-		WriterSerializer s1 = new JsonSerializer.Simple().setTrimNullProperties(false);
-		WriterSerializer s2 = new JsonSerializer.Simple().setTrimNullProperties(false).setQuoteChar('"');
+		WriterSerializer s1 = new JsonSerializerBuilder().simple().trimNullProperties(false).build();
+		WriterSerializer s2 = new JsonSerializerBuilder().simple().trimNullProperties(false).quoteChar('"').build();
 		String r;
 
 		// Null keys and values
@@ -109,7 +109,7 @@ public class JsonTest {
 	//====================================================================================================
 	@Test
 	public void testBackslashesInStrings() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple().setTrimNullProperties(false).setQuoteChar('"');
+		JsonSerializer s = new JsonSerializerBuilder().simple().trimNullProperties(false).quoteChar('"').build();
 		String r, r2;
 
 		// [\\]
@@ -275,7 +275,7 @@ public class JsonTest {
 	//====================================================================================================
 	@Test
 	public void testSubclassedList() throws Exception {
-		JsonSerializer s = new JsonSerializer();
+		JsonSerializer s = JsonSerializer.DEFAULT;
 		Map<String,Object> o = new HashMap<String,Object>();
 		o.put("c", new C());
 		assertEquals("{\"c\":[]}", s.serialize(o));
@@ -289,13 +289,13 @@ public class JsonTest {
 	//====================================================================================================
 	@Test
 	public void testEscapeSolidus() throws Exception {
-		JsonSerializer s = new JsonSerializer().setEscapeSolidus(false);
+		JsonSerializer s = new JsonSerializerBuilder().escapeSolidus(false).build();
 		String r = s.serialize("foo/bar");
 		assertEquals("\"foo/bar\"", r);
 		r = JsonParser.DEFAULT.parse(r, String.class);
 		assertEquals("foo/bar", r);
 
-		s = new JsonSerializer().setEscapeSolidus(true);
+		s = new JsonSerializerBuilder().escapeSolidus(true).build();
 		r = s.serialize("foo/bar");
 		assertEquals("\"foo\\/bar\"", r);
 		r = JsonParser.DEFAULT.parse(r, String.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/IfVarTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/IfVarTest.java b/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/IfVarTest.java
index 9acfb76..e81c826 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/IfVarTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/IfVarTest.java
@@ -14,7 +14,7 @@ package org.apache.juneau.svl.vars;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.svl.VarResolver;
+import org.apache.juneau.svl.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")
@@ -25,7 +25,7 @@ public class IfVarTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		VarResolver vr = new VarResolver().addVars(IfVar.class, SystemPropertiesVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(IfVar.class, SystemPropertiesVar.class).build();
 		
 		for (String test : new String[]{"","0","false","FALSE","f","F","foobar"}) {
 			System.setProperty("IfVarTest.test", test);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/SwitchVarTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/SwitchVarTest.java b/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/SwitchVarTest.java
index 75c004c..ab6d154 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/SwitchVarTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/svl/vars/SwitchVarTest.java
@@ -14,7 +14,7 @@ package org.apache.juneau.svl.vars;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.svl.VarResolver;
+import org.apache.juneau.svl.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")
@@ -25,7 +25,7 @@ public class SwitchVarTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		VarResolver vr = new VarResolver().addVars(SwitchVar.class, SystemPropertiesVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(SwitchVar.class, SystemPropertiesVar.class).build();
 		
 		System.setProperty("SwitchVarTest.test", "foobar");
 		

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanFilterTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanFilterTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanFilterTest.java
index a1d24df..e5fcc26 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanFilterTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanFilterTest.java
@@ -30,13 +30,13 @@ public class BeanFilterTest {
 		BeanSession session;
 		BeanMap<A3> bm;
 
-		session = ContextFactory.create().addBeanFilters(A1.class).getBeanContext().createSession();
+		session = PropertyStore.create().setBeanFilters(A1.class).getBeanContext().createSession();
 		bm = session.newBeanMap(A3.class);
 		assertEquals("f1", bm.get("f1"));
 		assertNull(bm.get("f2"));
 		assertNull(bm.get("f3"));
 
-		session = ContextFactory.create().addBeanFilters(A2.class).getBeanContext().createSession();
+		session = PropertyStore.create().setBeanFilters(A2.class).getBeanContext().createSession();
 		bm = session.newBeanMap(A3.class);
 		assertEquals("f1", bm.get("f1"));
 		assertEquals("f2", bm.get("f2"));
@@ -73,13 +73,13 @@ public class BeanFilterTest {
 		BeanSession session;
 		BeanMap<Test2> bm;
 
-		session = ContextFactory.create().addBeanFilters(B1.class).getBeanContext().createSession();
+		session = PropertyStore.create().setBeanFilters(B1.class).getBeanContext().createSession();
 		bm = session.newBeanMap(Test2.class);
 		assertEquals("f1", bm.get("f1"));
 		assertNull(bm.get("f2"));
 		assertNull(bm.get("f3"));
 
-		session = ContextFactory.create().addBeanFilters(B2.class).getBeanContext().createSession();
+		session = PropertyStore.create().setBeanFilters(B2.class).getBeanContext().createSession();
 		bm = session.newBeanMap(Test2.class);
 		assertEquals("f1", bm.get("f1"));
 		assertEquals("f2", bm.get("f2"));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanMapTest.java
index 0f44984..1e5d375 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/BeanMapTest.java
@@ -26,7 +26,7 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testFilteredEntry() throws Exception {
-		BeanSession session = ContextFactory.create().addPojoSwaps(ByteArrayBase64Swap.class).getBeanContext().createSession();
+		BeanSession session = PropertyStore.create().setPojoSwaps(ByteArrayBase64Swap.class).getBeanContext().createSession();
 		BeanMap<A> m = session.toBeanMap(new A());
 
 		assertEquals("AQID", m.get("f1"));
@@ -48,12 +48,12 @@ public class BeanMapTest {
 	//====================================================================================================
 	@Test
 	public void testFilteredEntryWithMultipleMatchingFilters() throws Exception {
-		BeanSession session = ContextFactory.create().addPojoSwaps(B2Swap.class,B1Swap.class).getBeanContext().createSession();
+		BeanSession session = PropertyStore.create().setPojoSwaps(B2Swap.class,B1Swap.class).getBeanContext().createSession();
 		BeanMap<B> bm = session.toBeanMap(B.create());
 		ObjectMap om = (ObjectMap)bm.get("b1");
 		assertEquals("b2", om.getString("type"));
 
-		session = ContextFactory.create().addPojoSwaps(B1Swap.class,B2Swap.class).getBeanContext().createSession();
+		session = PropertyStore.create().setPojoSwaps(B1Swap.class,B2Swap.class).getBeanContext().createSession();
 		bm = session.toBeanMap(B.create());
 		om = (ObjectMap)bm.get("b1");
 		assertEquals("b1", om.getString("type"));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/ByteArrayBase64SwapComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/ByteArrayBase64SwapComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/ByteArrayBase64SwapComboTest.java
index adc310e..b9ac9c3 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/ByteArrayBase64SwapComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/ByteArrayBase64SwapComboTest.java
@@ -12,18 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.transforms;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
-import org.apache.juneau.ComboTest;
-import org.apache.juneau.parser.Parser;
-import org.apache.juneau.serializer.Serializer;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
 
 /**
  * Exhaustive serialization tests for the CalendarSwap class.
@@ -348,16 +343,12 @@ public class ByteArrayBase64SwapComboTest extends ComboTest {
 	
 	@Override
 	protected Serializer applySettings(Serializer s) throws Exception {
-		if (s.isLocked())
-			 s = s.clone();
-		return s.addPojoSwaps(ByteArrayBase64Swap.class).setTrimNullProperties(false);
+		return s.builder().pojoSwaps(ByteArrayBase64Swap.class).trimNullProperties(false).build();
 	}
 	
 	@Override
 	protected Parser applySettings(Parser p) throws Exception {
-		if (p.isLocked())
-			p = p.clone();
-		return p.addPojoSwaps(ByteArrayBase64Swap.class);
+		return p.builder().pojoSwaps(ByteArrayBase64Swap.class).build();
 	}
 		
 	public static class BeanWithByteArrayField {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
index 0da8c2a..c3453b3 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapComboTest.java
@@ -12,22 +12,14 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.transforms;
 
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.GregorianCalendar;
-import java.util.Locale;
-import java.util.TimeZone;
+import java.util.*;
 
-import org.apache.juneau.ComboTest;
-import org.apache.juneau.ObjectMap;
-import org.apache.juneau.TestUtils;
-import org.apache.juneau.parser.Parser;
-import org.apache.juneau.serializer.Serializer;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
 
 /**
  * Exhaustive serialization tests for the CalendarSwap class.
@@ -563,15 +555,11 @@ public class CalendarSwapComboTest extends ComboTest {
 	
 	@Override
 	protected Serializer applySettings(Serializer s) throws Exception {
-		if (s.isLocked())
-			 s = s.clone();
-		return s.addPojoSwaps(swapClass);
+		return s.builder().pojoSwaps(swapClass).build();
 	}
 	
 	@Override
 	protected Parser applySettings(Parser p) throws Exception {
-		if (p.isLocked())
-			p = p.clone();
-		return p.addPojoSwaps(swapClass);
+		return p.builder().pojoSwaps(swapClass).build();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapTest.java
index d173c95..7ea6697 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/CalendarSwapTest.java
@@ -27,6 +27,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
@@ -51,12 +52,13 @@ public class CalendarSwapTest {
 	}
 
 	private RdfSerializer getRdfSerializer() {
-		return new RdfSerializer()
-			.setQuoteChar('\'')
-			.setUseWhitespace(false)
-			.setProperty(RdfCommonContext.RDF_rdfxml_allowBadUris, true)
-			.setProperty(RdfCommonContext.RDF_rdfxml_showDoctypeDeclaration, false)
-			.setProperty(RdfCommonContext.RDF_rdfxml_showXmlDeclaration, false);
+		return new RdfSerializerBuilder()
+			.sq()
+			.useWhitespace(false)
+			.property(RdfCommonContext.RDF_rdfxml_allowBadUris, true)
+			.property(RdfCommonContext.RDF_rdfxml_showDoctypeDeclaration, false)
+			.property(RdfCommonContext.RDF_rdfxml_showXmlDeclaration, false)
+			.build();
 	}
 
 	private String stripRdf(String s) {
@@ -184,7 +186,7 @@ public class CalendarSwapTest {
 	//====================================================================================================
 	@Test
 	public void testBeanProperyFilterHtml() throws Exception {
-		WriterSerializer s = HtmlSerializer.DEFAULT_SQ.clone().setAddKeyValueTableHeaders(true);
+		WriterSerializer s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true).build();
 		ReaderParser p = HtmlParser.DEFAULT;
 
 		Calendar c = testDate;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
index 6d641bd..5965e94 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapComboTest.java
@@ -12,20 +12,14 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.transforms;
 
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Locale;
+import java.util.*;
 
-import org.apache.juneau.ComboTest;
-import org.apache.juneau.ObjectMap;
-import org.apache.juneau.TestUtils;
-import org.apache.juneau.parser.Parser;
-import org.apache.juneau.serializer.Serializer;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
 
 /**
  * Exhaustive serialization tests for the DateSwap class.
@@ -557,15 +551,11 @@ public class DateSwapComboTest extends ComboTest {
 	
 	@Override
 	protected Serializer applySettings(Serializer s) throws Exception {
-		if (s.isLocked())
-			 s = s.clone();
-		return s.addPojoSwaps(swapClass);
+		return s.builder().pojoSwaps(swapClass).build();
 	}
 	
 	@Override
 	protected Parser applySettings(Parser p) throws Exception {
-		if (p.isLocked())
-			p = p.clone();
-		return p.addPojoSwaps(swapClass);
+		return p.builder().pojoSwaps(swapClass).build();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
index b0b57f0..40225ec 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/DateSwapTest.java
@@ -37,10 +37,14 @@ public class DateSwapTest {
 	public void testBeanWithDate() throws Exception {
 		A testBeanA = new A().init();
 
-		final String jsonData = new JsonSerializer().addPojoSwaps(
-			DateSwap.ISO8601DT.class).serialize(testBeanA);
-		final ObjectMap data = new JsonParser().addPojoSwaps(
-			DateSwap.ISO8601DT.class).parse(jsonData, ObjectMap.class);
+		final String jsonData = new JsonSerializerBuilder()
+			.pojoSwaps(DateSwap.ISO8601DT.class)
+			.build()
+			.serialize(testBeanA);
+		final ObjectMap data = new JsonParserBuilder()
+			.pojoSwaps(DateSwap.ISO8601DT.class)
+			.build()
+			.parse(jsonData, ObjectMap.class);
 
 		final DateSwap.ISO8601DT dateSwap = new DateSwap.ISO8601DT();
 		// this works

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/EnumerationSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/EnumerationSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/EnumerationSwapTest.java
index 5d96b15..207c5f1 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/EnumerationSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/EnumerationSwapTest.java
@@ -28,7 +28,7 @@ public class EnumerationSwapTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(EnumerationSwap.class);
+		WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(EnumerationSwap.class).build();
 		Vector<String> v = new Vector<String>(Arrays.asList(new String[]{"foo","bar","baz"}));
 		Enumeration<String> e = v.elements();
 		assertEquals("['foo','bar','baz']", s.serialize(e));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/IteratorSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/IteratorSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/IteratorSwapTest.java
index 3d72f5a..68db0b6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/IteratorSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/IteratorSwapTest.java
@@ -28,7 +28,7 @@ public class IteratorSwapTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(IteratorSwap.class);
+		WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(IteratorSwap.class).build();
 
 		// Iterators
 		List<String> l = new ArrayList<String>(Arrays.asList(new String[]{"foo","bar","baz"}));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/LocalizedDatesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/LocalizedDatesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/LocalizedDatesTest.java
index 25fe320..9aaca66 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/LocalizedDatesTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/LocalizedDatesTest.java
@@ -606,7 +606,7 @@ public class LocalizedDatesTest {
 	@SuppressWarnings("unused")
 	private String label, expected;
 	private Object calendar;
-	private ContextFactory cf;
+	private PropertyStore ps;
 	private Locale sessionLocale;
 	private TimeZone sessionTimeZone;
 
@@ -616,16 +616,16 @@ public class LocalizedDatesTest {
 		this.calendar = calendar;
 		this.sessionLocale = sessionLocale;
 		this.sessionTimeZone = sessionTimeZone;
-		cf = ContextFactory.create().addPojoSwaps(swap);
+		ps = PropertyStore.create().setPojoSwaps(swap);
 		if (contextLocale != null)
-			cf.setProperty(BEAN_locale, contextLocale);
+			ps.setProperty(BEAN_locale, contextLocale);
 		if (contextTimeZone != null)
-			cf.setProperty(BEAN_timeZone, contextTimeZone);
+			ps.setProperty(BEAN_timeZone, contextTimeZone);
 	}
 
 	@Test
 	public void test() {
-		BeanSession session = cf.getBeanContext().createSession(null, sessionLocale, sessionTimeZone, null);
+		BeanSession session = ps.getBeanContext().createSession(null, sessionLocale, sessionTimeZone, null);
 		String actual = session.convertToType(calendar, String.class);
 		assertEquals(expected, actual);
 		Object c2 = session.convertToType(actual, calendar.getClass());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderFilterTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderFilterTest.java b/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderFilterTest.java
index 0398568..3e0999d 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderFilterTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/transforms/ReaderFilterTest.java
@@ -18,7 +18,6 @@ import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")
@@ -29,7 +28,7 @@ public class ReaderFilterTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(ReaderSwap.Json.class);
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple().pojoSwaps(ReaderSwap.Json.class);
 
 		Reader r;
 		Map<String,Object> m;
@@ -37,12 +36,12 @@ public class ReaderFilterTest {
 		r = new StringReader("{foo:'bar',baz:'quz'}");
 		m = new HashMap<String,Object>();
 		m.put("X", r);
-		assertEquals("{X:{foo:'bar',baz:'quz'}}", s.serialize(m));
+		assertEquals("{X:{foo:'bar',baz:'quz'}}", s.build().serialize(m));
 
-		s.addPojoSwaps(ReaderSwap.Xml.class);
+		s.pojoSwaps(ReaderSwap.Xml.class);
 		r = new StringReader("<object><foo _type='string'>bar</foo><baz _type='string'>quz</baz></object>");
 		m = new HashMap<String,Object>();
 		m.put("X", r);
-		assertEquals("{X:{foo:'bar',baz:'quz'}}", s.serialize(m));
+		assertEquals("{X:{foo:'bar',baz:'quz'}}", s.build().serialize(m));
 	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
index 37f2376..62a5d9d 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UonTest.java
@@ -19,13 +19,14 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.parser.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings({"rawtypes","serial","javadoc"})
 public class CommonParser_UonTest {
 
-	ReaderParser p = UonParser.DEFAULT.clone().addToBeanDictionary(A1.class);
-	ReaderParser pe = UonParser.DEFAULT_DECODING.clone();
+	ReaderParser p = new UonParserBuilder().beanDictionary(A1.class).build();
+	ReaderParser pe = UonParser.DEFAULT_DECODING;
 
 	//====================================================================================================
 	// testFromSerializer
@@ -69,7 +70,7 @@ public class CommonParser_UonTest {
 		tl.add(new A3("name1","value1"));
 		b.list = tl;
 
-		in = new UonSerializer().setAddBeanTypeProperties(true).serialize(b);
+		in = new UonSerializerBuilder().addBeanTypeProperties(true).build().serialize(b);
 		b = (A1)p.parse(in, Object.class);
 		assertEquals("value1", b.list.get(1).value);
 
@@ -100,7 +101,7 @@ public class CommonParser_UonTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new UonParser().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new UonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		B t;
 
 		String in =  "(a=1,unknown=3,b=2)";
@@ -109,7 +110,7 @@ public class CommonParser_UonTest {
 		assertEquals(t.b, 2);
 
 		try {
-			p = new UonParser();
+			p = UonParser.DEFAULT;
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -150,7 +151,7 @@ public class CommonParser_UonTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		UonParser p = new UonParser().setIgnoreUnknownBeanProperties(true);
+		UonParser p = new UonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
index e026be1..d480a1b 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/CommonParser_UrlEncodingTest.java
@@ -21,12 +21,13 @@ import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings({"rawtypes","serial","javadoc"})
 public class CommonParser_UrlEncodingTest {
 
-	ReaderParser p = UrlEncodingParser.DEFAULT.clone().addToBeanDictionary(A1.class);
+	ReaderParser p = new UrlEncodingParserBuilder().beanDictionary(A1.class).build();
 
 	//====================================================================================================
 	// testFromSerializer
@@ -71,7 +72,7 @@ public class CommonParser_UrlEncodingTest {
 		tl.add(new A3("name1","value1"));
 		b.list = tl;
 
-		in = new UrlEncodingSerializer().setAddBeanTypeProperties(true).serialize(b);
+		in = new UrlEncodingSerializerBuilder().addBeanTypeProperties(true).build().serialize(b);
 		b = (A1)p.parse(in, Object.class);
 		assertEquals("value1", b.list.get(1).value);
 
@@ -102,7 +103,7 @@ public class CommonParser_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new UrlEncodingParser().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new UrlEncodingParserBuilder().ignoreUnknownBeanProperties(true).build();
 		B t;
 
 		String in =  "a=1&unknown=3&b=2";
@@ -111,7 +112,7 @@ public class CommonParser_UrlEncodingTest {
 		assertEquals(t.b, 2);
 
 		try {
-			p = new UrlEncodingParser();
+			p = UrlEncodingParser.DEFAULT;
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -152,7 +153,7 @@ public class CommonParser_UrlEncodingTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		UonParser p = new UrlEncodingParser().setIgnoreUnknownBeanProperties(true);
+		UonParser p = new UrlEncodingParserBuilder().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */
@@ -170,8 +171,8 @@ public class CommonParser_UrlEncodingTest {
 
 	@Test
 	public void testCollections() throws Exception {
-		WriterSerializer s = new UrlEncodingSerializer();
-		ReaderParser p = new UrlEncodingParser();
+		WriterSerializer s = UrlEncodingSerializer.DEFAULT;
+		ReaderParser p = UrlEncodingParser.DEFAULT;
 
 		List l = new ObjectList("foo","bar");
 		assertEquals("0=foo&1=bar", s.serialize(l));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UonTest.java
index 00643d0..187e120 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UonTest.java
@@ -21,8 +21,8 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.testbeans.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings({"serial","javadoc"})
@@ -35,17 +35,17 @@ public class Common_UonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		UonSerializer s = new UonSerializer.Encoding();
+		UonSerializerBuilder s = new UonSerializerBuilder().encoding();
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("(s1=null,s2=s2)", r);
 		t2 = pe.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("(s2=s2)", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -66,18 +66,18 @@ public class Common_UonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		UonSerializer s = UonSerializer.DEFAULT_ENCODING.clone();
+		UonSerializerBuilder s = new UonSerializerBuilder().encoding();
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("(f1=(),f2=(f2a=null,f2b=(s2=s2)))", r);
 		t2 = pe.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("(f2=(f2a=null,f2b=(s2=s2)))", r);
 		t2 = pe.parse(r, B.class);
 		assertNull(t2.f1);
@@ -99,18 +99,18 @@ public class Common_UonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		UonSerializer s = new UonSerializer.Encoding();
+		UonSerializerBuilder s = new UonSerializerBuilder().encoding();
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
 		t2 = pe.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("(f2=@(null,(s2=s2)))", r);
 		t2 = pe.parse(r, C.class);
 		assertNull(t2.f1);
@@ -132,18 +132,18 @@ public class Common_UonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		UonSerializer s = new UonSerializer.Encoding();
+		UonSerializerBuilder s = new UonSerializerBuilder().encoding();
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("(f1=@(),f2=@(null,(s2=s2)))", r);
 		t2 = pe.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("(f2=@(null,(s2=s2)))", r);
 		t2 = pe.parse(r, D.class);
 		assertNull(t2.f1);
@@ -240,13 +240,13 @@ public class Common_UonTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		WriterSerializer s = new UonSerializer();
+		UonSerializerBuilder s = new UonSerializerBuilder();
 		TestURI t = new TestURI();
 		String r;
 		String expected;
 
-		s.setRelativeUriBase(null);
-		r = s.serialize(t);
+		s.relativeUriBase(null);
+		r = s.build().serialize(t);
 		expected = ""
 			+"("
 			+"f0=f0/x0,"
@@ -267,12 +267,12 @@ public class Common_UonTest {
 			+")";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.relativeUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = s.serialize(t);
+		s.relativeUriBase("/cr");
+		r = s.build().serialize(t);
 		expected = ""
 			+"("
 			+"f0=/cr/f0/x0,"
@@ -293,12 +293,12 @@ public class Common_UonTest {
 			+")";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = s.serialize(t);
+		s.relativeUriBase("/cr/");  // Same as above
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = s.serialize(t);
+		s.relativeUriBase("/");
+		r = s.build().serialize(t);
 		expected = ""
 			+"("
 			+"f0=/f0/x0,"
@@ -319,10 +319,10 @@ public class Common_UonTest {
 			+")";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo");
+		r = s.build().serialize(t);
 		expected = ""
 			+"("
 			+"f0=f0/x0,"
@@ -343,12 +343,12 @@ public class Common_UonTest {
 			+")";
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo/");
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.absolutePathUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		expected = ""
 			+"("
 			+"f0=f0/x0,"
@@ -371,31 +371,11 @@ public class Common_UonTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		UonSerializer s = new UonSerializer().lock();
-		try {
-			s.setUseWhitespace(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		WriterSerializer s = new UonSerializer();
+		UonSerializerBuilder s = new UonSerializerBuilder();
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -406,7 +386,7 @@ public class Common_UonTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -414,9 +394,9 @@ public class Common_UonTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -426,8 +406,8 @@ public class Common_UonTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.urlencoding.Common_UonTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		assertEquals("(name=foo,r2=(name=bar,r3=(name=baz)))", s.serialize(r1));
+		s.ignoreRecursions(true);
+		assertEquals("(name=foo,r2=(name=bar,r3=(name=baz)))", s.build().serialize(r1));
 	}
 
 	public static class R1 {


[25/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
new file mode 100644
index 0000000..2f01917
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/CoreObjectBuilder.java
@@ -0,0 +1,1429 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import static org.apache.juneau.BeanContext.*;
+
+import java.beans.*;
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Builder class for building instances of serializers and parsers.
+ */
+public abstract class CoreObjectBuilder {
+
+	/** Contains all the modifiable settings for the implementation class. */
+	protected final PropertyStore propertyStore;
+
+	/**
+	 * Constructor.
+	 * Default settings.
+	 */
+	public CoreObjectBuilder() {
+		this.propertyStore = PropertyStore.create();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public CoreObjectBuilder(PropertyStore propertyStore) {
+		this.propertyStore = PropertyStore.create(propertyStore);
+	}
+
+	/**
+	 * Build the object.
+	 *
+	 * @return The built object.
+	 * Subsequent calls to this method will create new instances.
+	 */
+	public abstract CoreObject build();
+
+	/**
+	 * Copies the settings from the specified property store into this builder.
+	 *
+	 * @param copyFrom The factory whose settings are being copied.
+	 * @return This object (for method chaining).
+	 */
+	public CoreObjectBuilder apply(PropertyStore copyFrom) {
+		this.propertyStore.copyFrom(propertyStore);
+		return this;
+	}
+
+	/**
+	 * Build a new instance of the specified object.
+	 *
+	 * @param c The subclass of {@link CoreObject} to instantiate.
+	 * @return A new object using the settings defined in this builder.
+	 */
+	public <T extends CoreObject> T build(Class<T> c) {
+		try {
+			return c.getConstructor(PropertyStore.class).newInstance(propertyStore);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Sets a configuration property on this object.
+	 *
+	 * @param name The property name.
+	 * @param value The property value.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 */
+	public CoreObjectBuilder property(String name, Object value) {
+		propertyStore.setProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Adds multiple configuration properties on this object.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling {@link PropertyStore#addProperties(Map)}.
+	 * 	<li>Any previous properties are kept if they're not overwritten.
+	 * </ul>
+	 *
+	 * @param properties The properties to set on this class.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#addProperties(java.util.Map)
+	 */
+	public CoreObjectBuilder properties(Map<String,Object> properties) {
+		propertyStore.addProperties(properties);
+		return this;
+	}
+
+	/**
+	 * Sets multiple configuration properties on this object.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling {@link PropertyStore#setProperties(Map)}.
+	 * 	<li>Any previous properties are discarded.
+	 * </ul>
+	 *
+	 * @param properties The properties to set on this class.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperties(java.util.Map)
+	 */
+	public CoreObjectBuilder setProperties(Map<String,Object> properties) {
+		propertyStore.setProperties(properties);
+		return this;
+	}
+
+	/**
+	 * Adds a value to a SET property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>PropertyStore.addToProperty(name, value);</code>.
+	 * </ul>
+	 *
+	 * @param name The property name.
+	 * @param value The new value to add to the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public CoreObjectBuilder addToProperty(String name, Object value) {
+		propertyStore.addToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>PropertyStore.putToProperty(name, key, value);</code>.
+	 * </ul>
+	 *
+	 * @param name The property name.
+	 * @param key The property value map key.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public CoreObjectBuilder putToProperty(String name, Object key, Object value) {
+		propertyStore.putToProperty(name, key, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>PropertyStore.putToProperty(name, value);</code>.
+	 * </ul>
+	 *
+	 * @param name The property value.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public CoreObjectBuilder putToProperty(String name, Object value) {
+		propertyStore.putToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Removes a value from a SET property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>PropertyStore.removeFromProperty(name, value);</code>.
+	 * </ul>
+	 *
+	 * @param name The property name.
+	 * @param value The property value in the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public CoreObjectBuilder removeFromProperty(String name, Object value) {
+		propertyStore.removeFromProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Beans require no-arg constructors.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireDefaultConstructor"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, a Java class must implement a default no-arg constructor to be considered a bean.
+	 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method.
+	 * <p>
+	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beansRequireDefaultConstructor</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
+	 */
+	public CoreObjectBuilder beansRequireDefaultConstructor(boolean value) {
+		return property(BEAN_beansRequireDefaultConstructor, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Beans require {@link Serializable} interface.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSerializable"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, a Java class must implement the {@link Serializable} interface to be considered a bean.
+	 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method.
+	 * <p>
+	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beansRequireSerializable</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSerializable
+	 */
+	public CoreObjectBuilder beansRequireSerializable(boolean value) {
+		return property(BEAN_beansRequireSerializable, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Beans require setters for getters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSettersForGetters"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, only getters that have equivalent setters will be considered as properties on a bean.
+	 * Otherwise, they will be ignored.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beansRequireSettersForGetters</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSettersForGetters
+	 */
+	public CoreObjectBuilder beansRequireSettersForGetters(boolean value) {
+		return property(BEAN_beansRequireSettersForGetters, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Beans require at least one property.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSomeProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, then a Java class must contain at least 1 property to be considered a bean.
+	 * Otherwise, the bean will be serialized as a string using the {@link Object#toString()} method.
+	 * <p>
+	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beansRequireSomeProperties</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSomeProperties
+	 */
+	public CoreObjectBuilder beansRequireSomeProperties(boolean value) {
+		return property(BEAN_beansRequireSomeProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  {@link BeanMap#put(String,Object) BeanMap.put()} method will return old property value.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanMapPutReturnsOldValue"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, then the {@link BeanMap#put(String,Object) BeanMap.put()} method will return old property values.
+	 * Otherwise, it returns <jk>null</jk>.
+	 * <p>
+	 * Disabled by default because it introduces a slight performance penalty.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanMapPutReturnsOldValue</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
+	 */
+	public CoreObjectBuilder beanMapPutReturnsOldValue(boolean value) {
+		return property(BEAN_beanMapPutReturnsOldValue, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for bean constructors with the specified minimum visibility.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanConstructorVisibility"</js>
+	 * 	<li><b>Data type:</b> {@link Visibility}
+	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Constructors not meeting this minimum visibility will be ignored.
+	 * For example, if the visibility is <code>PUBLIC</code> and the constructor is <jk>protected</jk>, then
+	 * 	the constructor will be ignored.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanConstructorVisibility</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanConstructorVisibility
+	 */
+	public CoreObjectBuilder beanConstructorVisibility(Visibility value) {
+		return property(BEAN_beanConstructorVisibility, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for bean classes with the specified minimum visibility.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanClassVisibility"</js>
+	 * 	<li><b>Data type:</b> {@link Visibility}
+	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Classes are not considered beans unless they meet the minimum visibility requirements.
+	 * For example, if the visibility is <code>PUBLIC</code> and the bean class is <jk>protected</jk>, then
+	 * 	the class will not be interpreted as a bean class.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanClassVisibility</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanClassVisibility
+	 */
+	public CoreObjectBuilder beanClassVisibility(Visibility value) {
+		return property(BEAN_beanClassVisibility, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for bean fields with the specified minimum visibility.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanFieldVisibility"</js>
+	 * 	<li><b>Data type:</b> {@link Visibility}
+	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Fields are not considered bean properties unless they meet the minimum visibility requirements.
+	 * For example, if the visibility is <code>PUBLIC</code> and the bean field is <jk>protected</jk>, then
+	 * 	the field will not be interpreted as a bean property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanFieldVisibility</jsf>, value)</code>.
+	 * 	<li>Use {@link Visibility#NONE} to prevent bean fields from being interpreted as bean properties altogether.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFieldVisibility
+	 */
+	public CoreObjectBuilder beanFieldVisibility(Visibility value) {
+		return property(BEAN_beanFieldVisibility, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for bean methods with the specified minimum visibility.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.methodVisibility"</js>
+	 * 	<li><b>Data type:</b> {@link Visibility}
+	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Methods are not considered bean getters/setters unless they meet the minimum visibility requirements.
+	 * For example, if the visibility is <code>PUBLIC</code> and the bean method is <jk>protected</jk>, then
+	 * 	the method will not be interpreted as a bean getter or setter.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_methodVisibility</jsf>, value)</code>.
+	 * 	<li>Use {@link Visibility#NONE} to prevent bean methods from being interpreted as bean properties altogether.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_methodVisibility
+	 */
+	public CoreObjectBuilder methodVisibility(Visibility value) {
+		return property(BEAN_methodVisibility, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Use Java {@link Introspector} for determining bean properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.useJavaBeanIntrospector"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Using the built-in Java bean introspector will not pick up fields or non-standard getters/setters.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_useJavaBeanIntrospector</jsf>, value)</code>.
+	 * 	<li>Most {@link Bean @Bean} annotations will be ignored if you enable this setting.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useJavaBeanIntrospector
+	 */
+	public CoreObjectBuilder useJavaBeanIntrospector(boolean value) {
+		return property(BEAN_useJavaBeanIntrospector, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Use interface proxies.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.useInterfaceProxies"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, then interfaces will be instantiated as proxy classes through the use of an {@link InvocationHandler}
+	 * if there is no other way of instantiating them.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_useInterfaceProxies</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useInterfaceProxies
+	 */
+	public CoreObjectBuilder useInterfaceProxies(boolean value) {
+		return property(BEAN_useInterfaceProxies, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore unknown properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreUnknownBeanProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, trying to set a value on a non-existent bean property will silently be ignored.
+	 * Otherwise, a {@code BeanRuntimeException} is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_ignoreUnknownBeanProperties</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
+	 */
+	public CoreObjectBuilder ignoreUnknownBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownBeanProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore unknown properties with null values.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreUnknownNullBeanProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, trying to set a <jk>null</jk> value on a non-existent bean property will silently be ignored.
+	 * Otherwise, a {@code BeanRuntimeException} is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_ignoreUnknownNullBeanProperties</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
+	 */
+	public CoreObjectBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownNullBeanProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore properties without setters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.ignorePropertiesWithoutSetters"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, trying to set a value on a bean property without a setter will silently be ignored.
+	 * Otherwise, a {@code BeanRuntimeException} is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_ignorePropertiesWithoutSetters</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
+	 */
+	public CoreObjectBuilder ignorePropertiesWithoutSetters(boolean value) {
+		return property(BEAN_ignorePropertiesWithoutSetters, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore invocation errors on getters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreInvocationExceptionsOnGetters"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, errors thrown when calling bean getter methods will silently be ignored.
+	 * Otherwise, a {@code BeanRuntimeException} is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_ignoreInvocationExceptionsOnGetters</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
+	 */
+	public CoreObjectBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnGetters, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore invocation errors on setters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreInvocationExceptionsOnSetters"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, errors thrown when calling bean setter methods will silently be ignored.
+	 * Otherwise, a {@code BeanRuntimeException} is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_ignoreInvocationExceptionsOnSetters</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
+	 */
+	public CoreObjectBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnSetters, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Sort bean properties in alphabetical order.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.sortProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * When <jk>true</jk>, all bean properties will be serialized and access in alphabetical order.
+	 * Otherwise, the natural order of the bean properties is used which is dependent on the
+	 * 	JVM vendor.
+	 * On IBM JVMs, the bean properties are ordered based on their ordering in the Java file.
+	 * On Oracle JVMs, the bean properties are not ordered (which follows the offical JVM specs).
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_sortProperties</jsf>, value)</code>.
+	 * 	<li>This property is disabled by default so that IBM JVM users don't have to use {@link Bean @Bean} annotations
+	 * 		to force bean properties to be in a particular order and can just alter the order of the fields/methods
+	 * 		in the Java file.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_sortProperties
+	 */
+	public CoreObjectBuilder sortProperties(boolean value) {
+		return property(BEAN_sortProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Packages whose classes should not be considered beans.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.notBeanPackages.set"</js>
+	 * 	<li><b>Data type:</b> <code>Set&lt;String&gt;</code>
+	 * 	<li><b>Default:</b>
+	 * 	<ul>
+	 * 		<li><code>java.lang</code>
+	 * 		<li><code>java.lang.annotation</code>
+	 * 		<li><code>java.lang.ref</code>
+	 * 		<li><code>java.lang.reflect</code>
+	 * 		<li><code>java.io</code>
+	 * 		<li><code>java.net</code>
+	 * 		<li><code>java.nio.*</code>
+	 * 		<li><code>java.util.*</code>
+	 * 	</ul>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * When specified, the current list of ignore packages are appended to.
+	 * <p>
+	 * Any classes within these packages will be serialized to strings using {@link Object#toString()}.
+	 * <p>
+	 * Note that you can specify prefix patterns to include all subpackages.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_notBeanPackages</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public CoreObjectBuilder setNotBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Packages whose classes should not be considered beans.
+	 * <p>
+	 * Same as {@link #setNotBeanPackages(String...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public CoreObjectBuilder setNotBeanPackages(Collection<String> values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to packages whose classes should not be considered beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_notBeanPackages</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_notBeanPackages_add</jsf>, s)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public CoreObjectBuilder notBeanPackages(String...values) {
+		return addToProperty(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to packages whose classes should not be considered beans.
+	 * <p>
+	 * Same as {@link #notBeanPackages(String...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public CoreObjectBuilder notBeanPackages(Collection<String> values) {
+		return addToProperty(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from packages whose classes should not be considered beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_notBeanPackages</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_notBeanPackages_remove</jsf>, s)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public CoreObjectBuilder removeNotBeanPackages(String...values) {
+		return removeFromProperty(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from packages whose classes should not be considered beans.
+	 * <p>
+	 * Same as {@link #removeNotBeanPackages(String...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public CoreObjectBuilder removeNotBeanPackages(Collection<String> values) {
+		return removeFromProperty(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Classes to be excluded from consideration as being beans.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.notBeanClasses.set"</js>
+	 * 	<li><b>Data type:</b> <code>Set&lt;Class&gt;</code>
+	 * 	<li><b>Default:</b> empty set
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Not-bean classes are typically converted to <code>Strings</code> during serialization even if they
+	 * appear to be bean-like.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_notBeanClasses</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public CoreObjectBuilder setNotBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Classes to be excluded from consideration as being beans.
+	 * <p>
+	 * Same as {@link #setNotBeanClasses(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public CoreObjectBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to classes that should not be considered beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_notBeanClasses</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_notBeanClasses_add</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 * @see BeanContext#BEAN_notBeanClasses_add
+	 */
+	public CoreObjectBuilder notBeanClasses(Class<?>...values) {
+		return addToProperty(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to classes that should not be considered beans.
+	 * <p>
+	 * Same as {@link #notBeanClasses(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 * @see BeanContext#BEAN_notBeanClasses_add
+	 */
+	public CoreObjectBuilder notBeanClasses(Collection<Class<?>> values) {
+		return addToProperty(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from classes that should not be considered beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_notBeanClasses</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_notBeanClasses_remove</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public CoreObjectBuilder removeNotBeanClasses(Class<?>...values) {
+		return removeFromProperty(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from classes that should not be considered beans.
+	 * <p>
+	 * Same as {@link #removeNotBeanClasses(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public CoreObjectBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		return removeFromProperty(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Bean filters to apply to beans.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanFilters.list"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * This is a programmatic equivalent to the {@link Bean @Bean} annotation.
+	 * It's useful when you want to use the Bean annotation functionality, but you don't have the ability
+	 * 	to alter the bean classes.
+	 * <p>
+	 * There are two category of classes that can be passed in through this method:
+	 * <ul class='spaced-list'>
+	 * 	<li>Subclasses of {@link BeanFilterBuilder}.
+	 * 		These must have a public no-arg constructor.
+	 * 	<li>Bean interface classes.
+	 * 		A shortcut for defining a {@link InterfaceBeanFilterBuilder}.
+	 * 		Any subclasses of an interface class will only have properties defined on the interface.
+	 * 		All other bean properties will be ignored.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanFilters</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public CoreObjectBuilder setBeanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Bean filters to apply to beans.
+	 * <p>
+	 * Same as {@link #setBeanFilters(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public CoreObjectBuilder setBeanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to bean filters.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_beanFilters</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_beanFilters_add</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public CoreObjectBuilder beanFilters(Class<?>...values) {
+		return addToProperty(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to bean filters.
+	 * <p>
+	 * Same as {@link #beanFilters(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public CoreObjectBuilder beanFilters(Collection<Class<?>> values) {
+		return addToProperty(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from bean filters.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_beanFilters</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_beanFilters_remove</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public CoreObjectBuilder removeBeanFilters(Class<?>...values) {
+		return removeFromProperty(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from bean filters.
+	 * <p>
+	 * Same as {@link #removeBeanFilters(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public CoreObjectBuilder removeBeanFilters(Collection<Class<?>> values) {
+		return removeFromProperty(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  POJO swaps to apply to Java objects.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.pojoSwaps.list"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * There are two category of classes that can be passed in through this method:
+	 * <ul>
+	 * 	<li>Subclasses of {@link PojoSwap}.
+	 * 	<li>Surrogate classes.  A shortcut for defining a {@link SurrogateSwap}.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_pojoSwaps</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public CoreObjectBuilder setPojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  POJO swaps to apply to Java objects.
+	 * <p>
+	 * Same as {@link #setPojoSwaps(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public CoreObjectBuilder setPojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to POJO swaps.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_pojoSwaps</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_pojoSwaps_add</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public CoreObjectBuilder pojoSwaps(Class<?>...values) {
+		return addToProperty(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to POJO swaps.
+	 * <p>
+	 * Same as {@link #pojoSwaps(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public CoreObjectBuilder pojoSwaps(Collection<Class<?>> values) {
+		return addToProperty(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from POJO swaps.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_pojoSwaps</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_pojoSwaps_remove</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public CoreObjectBuilder removePojoSwaps(Class<?>...values) {
+		return removeFromProperty(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from POJO swaps.
+	 * <p>
+	 * Same as {@link #removePojoSwaps(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public CoreObjectBuilder removePojoSwaps(Collection<Class<?>> values) {
+		return removeFromProperty(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Implementation classes for interfaces and abstract classes.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.implClasses.map"</js>
+	 * 	<li><b>Data type:</b> <code>Map&lt;Class,Class&gt;</code>
+	 * 	<li><b>Default:</b> empty map
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * For interfaces and abstract classes this method can be used to specify an implementation
+	 * 	class for the interface/abstract class so that instances of the implementation
+	 * 	class are used when instantiated (e.g. during a parse).
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_implClasses</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 */
+	public CoreObjectBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		return property(BEAN_implClasses, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Implementation classes for interfaces and abstract classes.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_implClasses</jsf>, interfaceClass, implClass)</code>
+	 * 		or <code>property(<jsf>BEAN_implClasses_put</jsf>, interfaceClass, implClass)</code>.
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface class.
+	 * @param implClass The implementation class.
+	 * @param <I> The class type of the interface.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 * @see BeanContext#BEAN_implClasses_put
+	 */
+	public <I> CoreObjectBuilder implClass(Class<I> interfaceClass, Class<? extends I> implClass) {
+		return putToProperty(BEAN_implClasses, interfaceClass, implClass);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Bean lookup dictionary.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanDictionary.list"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * This list can consist of the following class types:
+	 * <ul>
+	 * 	<li>Any bean class that specifies a value for {@link Bean#typeName() @Bean.typeName()}.
+	 * 	<li>Any subclass of {@link BeanDictionaryList} containing a collection of bean classes with type name annotations.
+	 * 	<li>Any subclass of {@link BeanDictionaryMap} containing a mapping of type names to classes without type name annotations.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanDictionary</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public CoreObjectBuilder setBeanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Bean lookup dictionary.
+	 * <p>
+	 * Same as {@link #setBeanDictionary(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public CoreObjectBuilder setBeanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to bean dictionary.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_beanDictionary</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_beanDictionary_add</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public CoreObjectBuilder beanDictionary(Class<?>...values) {
+		return addToProperty(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add to bean dictionary.
+	 * <p>
+	 * Same as {@link #beanDictionary(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public CoreObjectBuilder beanDictionary(Collection<Class<?>> values) {
+		return addToProperty(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from bean dictionary.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_beanDictionary</jsf>, values)</code>
+	 * 		or <code>property(<jsf>BEAN_beanDictionary_remove</jsf>, values)</code>.
+	 * </ul>
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public CoreObjectBuilder removeFromBeanDictionary(Class<?>...values) {
+		return removeFromProperty(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Remove from bean dictionary.
+	 * <p>
+	 * Same as {@link #removeFromBeanDictionary(Class...)} but using a <code>Collection</code>.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public CoreObjectBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		return removeFromProperty(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Name to use for the bean type properties used to represent a bean type.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.beanTypePropertyName"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"_type"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_beanTypePropertyName</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanTypePropertyName
+	 */
+	public CoreObjectBuilder beanTypePropertyName(String value) {
+		return property(BEAN_beanTypePropertyName, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default parser to use when converting <code>Strings</code> to POJOs.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.defaultParser"</js>
+	 * 	<li><b>Data type:</b> <code>Class</code>
+	 * 	<li><b>Default:</b> {@link JsonSerializer}
+	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * Used in the in the {@link BeanSession#convertToType(Object, Class)} method.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_defaultParser</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_defaultParser
+	 */
+	public CoreObjectBuilder defaultParser(Class<?> value) {
+		return property(BEAN_defaultParser, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Locale.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.locale"</js>
+	 * 	<li><b>Data type:</b> <code>Locale</code>
+	 * 	<li><b>Default:</b> <code>Locale.getDefault()</code>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_locale</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_locale
+	 */
+	public CoreObjectBuilder locale(Locale value) {
+		return property(BEAN_locale, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  TimeZone.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.timeZone"</js>
+	 * 	<li><b>Data type:</b> <code>TimeZone</code>
+	 * 	<li><b>Default:</b> <jk>null</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_timeZone</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_timeZone
+	 */
+	public CoreObjectBuilder timeZone(TimeZone value) {
+		return property(BEAN_timeZone, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Media type.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.mediaType"</js>
+	 * 	<li><b>Data type:</b> <code>MediaType</code>
+	 * 	<li><b>Default:</b> <jk>null</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specifies a default media type value for serializer and parser sessions.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_mediaType</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_mediaType
+	 */
+	public CoreObjectBuilder mediaType(MediaType value) {
+		return property(BEAN_mediaType, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Debug mode.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"BeanContext.debug"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Enables the following additional information during serialization:
+	 * <ul class='spaced-list'>
+	 * 	<li>When bean getters throws exceptions, the exception includes the object stack information
+	 * 		in order to determine how that method was invoked.
+	 * 	<li>Enables {@link SerializerContext#SERIALIZER_detectRecursions}.
+	 * </ul>
+	 * <p>
+	 * Enables the following additional information during parsing:
+	 * <ul class='spaced-list'>
+	 * 	<li>When bean setters throws exceptions, the exception includes the object stack information
+	 * 		in order to determine how that method was invoked.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>BEAN_debug</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_debug
+	 */
+	public CoreObjectBuilder debug(boolean value) {
+		return property(BEAN_debug, value);
+	}
+
+	/**
+	 * Sets the classloader used for created classes from class strings.
+	 *
+	 * @param classLoader The new classloader.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setClassLoader(ClassLoader)
+	 */
+	public CoreObjectBuilder classLoader(ClassLoader classLoader) {
+		propertyStore.setClassLoader(classLoader);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/Lockable.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/Lockable.java b/juneau-core/src/main/java/org/apache/juneau/Lockable.java
deleted file mode 100644
index 4dc1b21..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/Lockable.java
+++ /dev/null
@@ -1,86 +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;
-
-/**
- * Superclass of all classes that have a locked state.
- * <p>
- * Used to mark bean contexts, serializers, and parsers as read-only so that
- * 	settings can no longer be modified.
- * <p>
- * Also keeps track of when the object has been cloned and allows for lazy cloning through
- * 	the {@link #onUnclone()} method.  The idea behind this is that certain expensive fields don't
- * 	need to be cloned unless the object is actually being modified.
- * <p>
- * Calling {@link #lock()} on the object causes it to be put into a read-only state.
- * Once called, subsequent calls to {@link #checkLock()} will cause {@link LockedException LockedExceptions}
- * 	to be thrown.
- * <p>
- * As a rule, cloned objects are unlocked by default.
- */
-public abstract class Lockable implements Cloneable {
-
-	private boolean isLocked = false;
-	private boolean isCloned = false;
-
-	/**
-	 * Locks this object so that settings on it cannot be modified.
-	 *
-	 * @return This object (for method chaining).
-	 */
-	public Lockable lock() {
-		isLocked = true;
-		return this;
-	}
-
-	/**
-	 * @return <code><jk>true</jk></code> if this object has been locked.
-	 */
-	public boolean isLocked() {
-		return isLocked;
-	}
-
-	/**
-	 * Causes a {@link LockedException} to be thrown if this object has been locked.
-	 * <p>
-	 * Also calls {@link #onUnclone()} if this is the first time this method has been called since cloning.
-	 *
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	protected void checkLock() throws LockedException {
-		if (isLocked)
-			throw new LockedException();
-		if (isCloned)
-			onUnclone();
-		isCloned = false;
-	}
-
-	/**
-	 * Subclass can override this method to handle lazy-cloning on the first time {@link #checkLock()} is called after
-	 * the object has been cloned.
-	 */
-	public void onUnclone() {}
-
-	/**
-	 * Creates an unlocked clone of this object.
-	 *
-	 * @throws CloneNotSupportedException If class cannot be cloned.
-	 */
-	@Override /* Object */
-	public Lockable clone() throws CloneNotSupportedException {
-		Lockable c = (Lockable)super.clone();
-		c.isLocked = false;
-		c.isCloned = true;
-		return c;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/LockedException.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/LockedException.java b/juneau-core/src/main/java/org/apache/juneau/LockedException.java
deleted file mode 100644
index 4ad8303..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/LockedException.java
+++ /dev/null
@@ -1,30 +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;
-
-/**
- * Exception that gets thrown when trying to modify settings on a locked {@link Lockable} object.
- * <p>
- * A locked exception indicates a programming error.
- * Certain objects that are meant for reuse, such as serializers and parsers, provide
- * the ability to lock the current settings so that they cannot be later changed.
- * This exception indicates that a setting change was attempted on a previously locked object.
- */
-public final class LockedException extends RuntimeException {
-
-	private static final long serialVersionUID = 1L;
-
-	LockedException() {
-		super("Object is locked and object settings cannot be modified.  Try cloning the object.");
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/MediaRange.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/MediaRange.java b/juneau-core/src/main/java/org/apache/juneau/MediaRange.java
index c9295f0..5a21882 100644
--- a/juneau-core/src/main/java/org/apache/juneau/MediaRange.java
+++ b/juneau-core/src/main/java/org/apache/juneau/MediaRange.java
@@ -13,7 +13,6 @@
 package org.apache.juneau;
 
 import java.util.*;
-import java.util.Map;
 import java.util.Map.*;
 
 import org.apache.juneau.annotation.*;


[13/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
new file mode 100644
index 0000000..ef4c95c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParser.java
@@ -0,0 +1,800 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.uon.UonParserContext.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Parses UON (a notation for URL-encoded query parameter values) text into POJO models.
+ *
+ * <h5 class='section'>Media types:</h5>
+ * <p>
+ * Handles <code>Content-Type</code> types: <code>text/uon</code>
+ *
+ * <h5 class='section'>Description:</h5>
+ * <p>
+ * This parser uses a state machine, which makes it very fast and efficient.
+ *
+ * <h5 class='section'>Configurable properties:</h5>
+ * <p>
+ * This class has the following properties associated with it:
+ * <ul>
+ * 	<li>{@link UonParserContext}
+ * 	<li>{@link ParserContext}
+ * 	<li>{@link BeanContext}
+ * </ul>
+ */
+@SuppressWarnings({ "rawtypes", "unchecked" })
+@Consumes("text/uon")
+public class UonParser extends ReaderParser {
+
+	/** Reusable instance of {@link UonParser}, all default settings. */
+	public static final UonParser DEFAULT = new UonParser(PropertyStore.create());
+
+	/** Reusable instance of {@link UonParser} with decodeChars set to true. */
+	public static final UonParser DEFAULT_DECODING = new UonParser.Decoding(PropertyStore.create());
+
+	// Characters that need to be preceeded with an escape character.
+	private static final AsciiSet escapedChars = new AsciiSet("~'\u0001\u0002");
+
+	private static final char AMP='\u0001', EQ='\u0002';  // Flags set in reader to denote & and = characters.
+
+
+	/** Default parser, decoding. */
+	public static class Decoding extends UonParser {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Decoding(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(UON_decodeChars, true);
+		}
+	}
+
+
+	private final UonParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public UonParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(UonParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public UonParserBuilder builder() {
+		return new UonParserBuilder(propertyStore);
+	}
+
+	/**
+	 * Workhorse method.
+	 *
+	 * @param session The parser context for this parse.
+	 * @param eType The class type being parsed, or <jk>null</jk> if unknown.
+	 * @param r The reader being parsed.
+	 * @param outer The outer object (for constructing nested inner classes).
+	 * @param isUrlParamValue If <jk>true</jk>, then we're parsing a top-level URL-encoded value which is treated a bit different than the default case.
+	 * @param pMeta The current bean property being parsed.
+	 * @return The parsed object.
+	 * @throws Exception
+	 */
+	protected <T> T parseAnything(UonParserSession session, ClassMeta<T> eType, ParserReader r, Object outer, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws Exception {
+
+		if (eType == null)
+			eType = (ClassMeta<T>)object();
+		PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
+		ClassMeta<?> sType = eType.getSerializedClassMeta();
+
+		Object o = null;
+
+		int c = r.peekSkipWs();
+
+		if (c == -1 || c == AMP) {
+			// If parameter is blank and it's an array or collection, return an empty list.
+			if (sType.isCollectionOrArray())
+				o = sType.newInstance();
+			else if (sType.isString() || sType.isObject())
+				o = "";
+			else if (sType.isPrimitive())
+				o = sType.getPrimitiveDefault();
+			// Otherwise, leave null.
+		} else if (sType.isObject()) {
+			if (c == '(') {
+				ObjectMap m = new ObjectMap(session);
+				parseIntoMap(session, r, m, string(), object(), pMeta);
+				o = session.cast(m, pMeta, eType);
+			} else if (c == '@') {
+				Collection l = new ObjectList(session);
+				o = parseIntoCollection(session, r, l, sType.getElementType(), isUrlParamValue, pMeta);
+			} else {
+				String s = parseString(session, r, isUrlParamValue);
+				if (c != '\'') {
+					if ("true".equals(s) || "false".equals(s))
+						o = Boolean.valueOf(s);
+					else if (StringUtils.isNumeric(s))
+						o = StringUtils.parseNumber(s, Number.class);
+					else
+						o = s;
+				} else {
+					o = s;
+				}
+			}
+		} else if (sType.isBoolean()) {
+			o = parseBoolean(session, r);
+		} else if (sType.isCharSequence()) {
+			o = parseString(session, r, isUrlParamValue);
+		} else if (sType.isChar()) {
+			String s = parseString(session, r, isUrlParamValue);
+			o = s == null ? null : s.charAt(0);
+		} else if (sType.isNumber()) {
+			o = parseNumber(session, r, (Class<? extends Number>)sType.getInnerClass());
+		} else if (sType.isMap()) {
+			Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(session));
+			o = parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
+		} else if (sType.isCollection()) {
+			if (c == '(') {
+				ObjectMap m = new ObjectMap(session);
+				parseIntoMap(session, r, m, string(), object(), pMeta);
+				// Handle case where it's a collection, but serialized as a map with a _type or _value key.
+				if (m.containsKey(session.getBeanTypePropertyName()))
+					o = session.cast(m, pMeta, eType);
+				// Handle case where it's a collection, but only a single value was specified.
+				else {
+					Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance(outer) : new ObjectList(session));
+					l.add(m.cast(sType.getElementType()));
+					o = l;
+				}
+			} else {
+				Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance(outer) : new ObjectList(session));
+				o = parseIntoCollection(session, r, l, sType.getElementType(), isUrlParamValue, pMeta);
+			}
+		} else if (sType.canCreateNewBean(outer)) {
+			BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
+			m = parseIntoBeanMap(session, r, m);
+			o = m == null ? null : m.getBean();
+		} else if (sType.canCreateNewInstanceFromString(outer)) {
+			String s = parseString(session, r, isUrlParamValue);
+			if (s != null)
+				o = sType.newInstanceFromString(outer, s);
+		} else if (sType.canCreateNewInstanceFromNumber(outer)) {
+			o = sType.newInstanceFromNumber(session, outer, parseNumber(session, r, sType.getNewInstanceFromNumberClass()));
+		} else if (sType.isArray()) {
+			if (c == '(') {
+				ObjectMap m = new ObjectMap(session);
+				parseIntoMap(session, r, m, string(), object(), pMeta);
+				// Handle case where it's an array, but serialized as a map with a _type or _value key.
+				if (m.containsKey(session.getBeanTypePropertyName()))
+					o = session.cast(m, pMeta, eType);
+				// Handle case where it's an array, but only a single value was specified.
+				else {
+					ArrayList l = new ArrayList(1);
+					l.add(m.cast(sType.getElementType()));
+					o = session.toArray(sType, l);
+				}
+			} else {
+				ArrayList l = (ArrayList)parseIntoCollection(session, r, new ArrayList(), sType.getElementType(), isUrlParamValue, pMeta);
+				o = session.toArray(sType, l);
+			}
+		} else if (c == '(') {
+			// It could be a non-bean with _type attribute.
+			ObjectMap m = new ObjectMap(session);
+			parseIntoMap(session, r, m, string(), object(), pMeta);
+			if (m.containsKey(session.getBeanTypePropertyName()))
+				o = session.cast(m, pMeta, eType);
+			else
+				throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
+		} else {
+			throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
+		}
+
+		if (transform != null && o != null)
+			o = transform.unswap(session, o, eType);
+
+		if (outer != null)
+			setParent(eType, o, outer);
+
+		return (T)o;
+	}
+
+	private <K,V> Map<K,V> parseIntoMap(UonParserSession session, ParserReader r, Map<K,V> m, ClassMeta<K> keyType, ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception {
+
+		if (keyType == null)
+			keyType = (ClassMeta<K>)string();
+
+		int c = r.read();
+		if (c == -1 || c == AMP)
+			return null;
+		if (c == 'n')
+			return (Map<K,V>)parseNull(session, r);
+		if (c != '(')
+			throw new ParseException(session, "Expected '(' at beginning of object.");
+
+		final int S1=1; // Looking for attrName start.
+		final int S2=2; // Found attrName end, looking for =.
+		final int S3=3; // Found =, looking for valStart.
+		final int S4=4; // Looking for , or )
+		boolean isInEscape = false;
+
+		int state = S1;
+		K currAttr = null;
+		while (c != -1 && c != AMP) {
+			c = r.read();
+			if (! isInEscape) {
+				if (state == S1) {
+					if (c == ')')
+						return m;
+					if (Character.isWhitespace(c))
+						skipSpace(r);
+					else {
+						r.unread();
+						Object attr = parseAttr(session, r, session.isDecodeChars());
+						currAttr = attr == null ? null : convertAttrToType(session, m, session.trim(attr.toString()), keyType);
+						state = S2;
+						c = 0; // Avoid isInEscape if c was '\'
+					}
+				} else if (state == S2) {
+					if (c == EQ || c == '=')
+						state = S3;
+					else if (c == -1 || c == ',' || c == ')' || c == AMP) {
+						if (currAttr == null) {
+							// Value was '%00'
+							r.unread();
+							return null;
+						}
+						m.put(currAttr, null);
+						if (c == ')' || c == -1 || c == AMP)
+							return m;
+						state = S1;
+					}
+				} else if (state == S3) {
+					if (c == -1 || c == ',' || c == ')' || c == AMP) {
+						V value = convertAttrToType(session, m, "", valueType);
+						m.put(currAttr, value);
+						if (c == -1 || c == ')' || c == AMP)
+							return m;
+						state = S1;
+					} else  {
+						V value = parseAnything(session, valueType, r.unread(), m, false, pMeta);
+						setName(valueType, value, currAttr);
+						m.put(currAttr, value);
+						state = S4;
+						c = 0; // Avoid isInEscape if c was '\'
+					}
+				} else if (state == S4) {
+					if (c == ',')
+						state = S1;
+					else if (c == ')' || c == -1 || c == AMP) {
+						return m;
+					}
+				}
+			}
+			isInEscape = isInEscape(c, r, isInEscape);
+		}
+		if (state == S1)
+			throw new ParseException(session, "Could not find attribute name on object.");
+		if (state == S2)
+			throw new ParseException(session, "Could not find '=' following attribute name on object.");
+		if (state == S3)
+			throw new ParseException(session, "Dangling '=' found in object entry");
+		if (state == S4)
+			throw new ParseException(session, "Could not find ')' marking end of object.");
+
+		return null; // Unreachable.
+	}
+
+	private <E> Collection<E> parseIntoCollection(UonParserSession session, ParserReader r, Collection<E> l, ClassMeta<E> elementType, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws Exception {
+
+		int c = r.readSkipWs();
+		if (c == -1 || c == AMP)
+			return null;
+		if (c == 'n')
+			return (Collection<E>)parseNull(session, r);
+
+		// If we're parsing a top-level parameter, we're allowed to have comma-delimited lists outside parenthesis (e.g. "&foo=1,2,3&bar=a,b,c")
+		// This is not allowed at lower levels since we use comma's as end delimiters.
+		boolean isInParens = (c == '@');
+		if (! isInParens) {
+			if (isUrlParamValue)
+				r.unread();
+			else
+				throw new ParseException(session, "Could not find '(' marking beginning of collection.");
+		} else {
+			r.read();
+		}
+
+		if (isInParens) {
+			final int S1=1; // Looking for starting of first entry.
+			final int S2=2; // Looking for starting of subsequent entries.
+			final int S3=3; // Looking for , or ) after first entry.
+
+			int state = S1;
+			while (c != -1 && c != AMP) {
+				c = r.read();
+				if (state == S1 || state == S2) {
+					if (c == ')') {
+						if (state == S2) {
+							l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
+							r.read();
+						}
+						return l;
+					} else if (Character.isWhitespace(c)) {
+						skipSpace(r);
+					} else {
+						l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
+						state = S3;
+					}
+				} else if (state == S3) {
+					if (c == ',') {
+						state = S2;
+					} else if (c == ')') {
+						return l;
+					}
+				}
+			}
+			if (state == S1 || state == S2)
+				throw new ParseException(session, "Could not find start of entry in array.");
+			if (state == S3)
+				throw new ParseException(session, "Could not find end of entry in array.");
+
+		} else {
+			final int S1=1; // Looking for starting of entry.
+			final int S2=2; // Looking for , or & or END after first entry.
+
+			int state = S1;
+			while (c != -1 && c != AMP) {
+				c = r.read();
+				if (state == S1) {
+					if (Character.isWhitespace(c)) {
+						skipSpace(r);
+					} else {
+						l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
+						state = S2;
+					}
+				} else if (state == S2) {
+					if (c == ',') {
+						state = S1;
+					} else if (Character.isWhitespace(c)) {
+						skipSpace(r);
+					} else if (c == AMP || c == -1) {
+						r.unread();
+						return l;
+					}
+				}
+			}
+		}
+
+		return null;  // Unreachable.
+	}
+
+	private <T> BeanMap<T> parseIntoBeanMap(UonParserSession session, ParserReader r, BeanMap<T> m) throws Exception {
+
+		int c = r.readSkipWs();
+		if (c == -1 || c == AMP)
+			return null;
+		if (c == 'n')
+			return (BeanMap<T>)parseNull(session, r);
+		if (c != '(')
+			throw new ParseException(session, "Expected '(' at beginning of object.");
+
+		final int S1=1; // Looking for attrName start.
+		final int S2=2; // Found attrName end, looking for =.
+		final int S3=3; // Found =, looking for valStart.
+		final int S4=4; // Looking for , or }
+		boolean isInEscape = false;
+
+		int state = S1;
+		String currAttr = "";
+		int currAttrLine = -1, currAttrCol = -1;
+		while (c != -1 && c != AMP) {
+			c = r.read();
+			if (! isInEscape) {
+				if (state == S1) {
+					if (c == ')' || c == -1 || c == AMP) {
+						return m;
+					}
+					if (Character.isWhitespace(c))
+						skipSpace(r);
+					else {
+						r.unread();
+						currAttrLine= r.getLine();
+						currAttrCol = r.getColumn();
+						currAttr = parseAttrName(session, r, session.isDecodeChars());
+						if (currAttr == null)  // Value was '%00'
+							return null;
+						state = S2;
+					}
+				} else if (state == S2) {
+					if (c == EQ || c == '=')
+						state = S3;
+					else if (c == -1 || c == ',' || c == ')' || c == AMP) {
+						m.put(currAttr, null);
+						if (c == ')' || c == -1 || c == AMP)
+							return m;
+						state = S1;
+					}
+				} else if (state == S3) {
+					if (c == -1 || c == ',' || c == ')' || c == AMP) {
+						if (! currAttr.equals(session.getBeanTypePropertyName())) {
+							BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
+							if (pMeta == null) {
+								onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+							} else {
+								Object value = session.convertToType("", pMeta.getClassMeta());
+								pMeta.set(m, value);
+							}
+						}
+						if (c == -1 || c == ')' || c == AMP)
+							return m;
+						state = S1;
+					} else {
+						if (! currAttr.equals(session.getBeanTypePropertyName())) {
+							BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
+							if (pMeta == null) {
+								onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
+								parseAnything(session, object(), r.unread(), m.getBean(false), false, null); // Read content anyway to ignore it
+							} else {
+								session.setCurrentProperty(pMeta);
+								ClassMeta<?> cm = pMeta.getClassMeta();
+								Object value = parseAnything(session, cm, r.unread(), m.getBean(false), false, pMeta);
+								setName(cm, value, currAttr);
+								pMeta.set(m, value);
+								session.setCurrentProperty(null);
+							}
+						}
+						state = S4;
+					}
+				} else if (state == S4) {
+					if (c == ',')
+						state = S1;
+					else if (c == ')' || c == -1 || c == AMP) {
+						return m;
+					}
+				}
+			}
+			isInEscape = isInEscape(c, r, isInEscape);
+		}
+		if (state == S1)
+			throw new ParseException(session, "Could not find attribute name on object.");
+		if (state == S2)
+			throw new ParseException(session, "Could not find '=' following attribute name on object.");
+		if (state == S3)
+			throw new ParseException(session, "Could not find value following '=' on object.");
+		if (state == S4)
+			throw new ParseException(session, "Could not find ')' marking end of object.");
+
+		return null; // Unreachable.
+	}
+
+	private Object parseNull(UonParserSession session, ParserReader r) throws Exception {
+		String s = parseString(session, r, false);
+		if ("ull".equals(s))
+			return null;
+		throw new ParseException(session, "Unexpected character sequence: ''{0}''", s);
+	}
+
+	/**
+	 * Convenience method for parsing an attribute from the specified parser.
+	 *
+	 * @param session
+	 * @param r
+	 * @param encoded
+	 * @return The parsed object
+	 * @throws Exception
+	 */
+	protected final Object parseAttr(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
+		Object attr;
+		attr = parseAttrName(session, r, encoded);
+		return attr;
+	}
+
+	/**
+	 * Parses an attribute name from the specified reader.
+	 *
+	 * @param session
+	 * @param r
+	 * @param encoded
+	 * @return The parsed attribute name.
+	 * @throws Exception
+	 */
+	protected final String parseAttrName(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
+
+		// If string is of form 'xxx', we're looking for ' at the end.
+		// Otherwise, we're looking for '&' or '=' or WS or -1 denoting the end of this string.
+
+		int c = r.peekSkipWs();
+		if (c == '\'')
+			return parsePString(session, r);
+
+		r.mark();
+		boolean isInEscape = false;
+		if (encoded) {
+			while (c != -1) {
+				c = r.read();
+				if (! isInEscape) {
+					if (c == AMP || c == EQ || c == -1 || Character.isWhitespace(c)) {
+						if (c != -1)
+							r.unread();
+						String s = r.getMarked();
+						return ("null".equals(s) ? null : s);
+					}
+				}
+				else if (c == AMP)
+					r.replace('&');
+				else if (c == EQ)
+					r.replace('=');
+				isInEscape = isInEscape(c, r, isInEscape);
+			}
+		} else {
+			while (c != -1) {
+				c = r.read();
+				if (! isInEscape) {
+					if (c == '=' || c == -1 || Character.isWhitespace(c)) {
+						if (c != -1)
+							r.unread();
+						String s = r.getMarked();
+						return ("null".equals(s) ? null : session.trim(s));
+					}
+				}
+				isInEscape = isInEscape(c, r, isInEscape);
+			}
+		}
+
+		// We should never get here.
+		throw new ParseException(session, "Unexpected condition.");
+	}
+
+
+	/**
+	 * Returns true if the next character in the stream is preceeded by an escape '~' character.
+	 * @param c The current character.
+	 * @param r The reader.
+	 * @param prevIsInEscape What the flag was last time.
+	 */
+	private static final boolean isInEscape(int c, ParserReader r, boolean prevIsInEscape) throws Exception {
+		if (c == '~' && ! prevIsInEscape) {
+			c = r.peek();
+			if (escapedChars.contains(c)) {
+				r.delete();
+				return true;
+			}
+		}
+		return false;
+	}
+
+	/**
+	 * Parses a string value from the specified reader.
+	 *
+	 * @param session
+	 * @param r
+	 * @param isUrlParamValue
+	 * @return The parsed string.
+	 * @throws Exception
+	 */
+	protected final String parseString(UonParserSession session, ParserReader r, boolean isUrlParamValue) throws Exception {
+
+		// If string is of form 'xxx', we're looking for ' at the end.
+		// Otherwise, we're looking for ',' or ')' or -1 denoting the end of this string.
+
+		int c = r.peekSkipWs();
+		if (c == '\'')
+			return parsePString(session, r);
+
+		r.mark();
+		boolean isInEscape = false;
+		String s = null;
+		AsciiSet endChars = (isUrlParamValue ? endCharsParam : endCharsNormal);
+		while (c != -1) {
+			c = r.read();
+			if (! isInEscape) {
+				// If this is a URL parameter value, we're looking for:  &
+				// If not, we're looking for:  &,)
+				if (endChars.contains(c)) {
+					r.unread();
+					c = -1;
+				}
+			}
+			if (c == -1)
+				s = r.getMarked();
+			else if (c == EQ)
+				r.replace('=');
+			else if (Character.isWhitespace(c) && ! isUrlParamValue) {
+				s = r.getMarked(0, -1);
+				skipSpace(r);
+				c = -1;
+			}
+			isInEscape = isInEscape(c, r, isInEscape);
+		}
+
+		if (isUrlParamValue)
+			s = StringUtils.trim(s);
+
+		return ("null".equals(s) ? null : session.trim(s));
+	}
+
+	private static final AsciiSet endCharsParam = new AsciiSet(""+AMP), endCharsNormal = new AsciiSet(",)"+AMP);
+
+
+	/**
+	 * Parses a string of the form "'foo'"
+	 * All whitespace within parenthesis are preserved.
+	 */
+	static String parsePString(UonParserSession session, ParserReader r) throws Exception {
+
+		r.read(); // Skip first quote.
+		r.mark();
+		int c = 0;
+
+		boolean isInEscape = false;
+		while (c != -1) {
+			c = r.read();
+			if (! isInEscape) {
+				if (c == '\'')
+					return session.trim(r.getMarked(0, -1));
+			}
+			if (c == EQ)
+				r.replace('=');
+			isInEscape = isInEscape(c, r, isInEscape);
+		}
+		throw new ParseException(session, "Unmatched parenthesis");
+	}
+
+	private Boolean parseBoolean(UonParserSession session, ParserReader r) throws Exception {
+		String s = parseString(session, r, false);
+		if (s == null || s.equals("null"))
+			return null;
+		if (s.equals("true"))
+			return true;
+		if (s.equals("false"))
+			return false;
+		throw new ParseException(session, "Unrecognized syntax for boolean.  ''{0}''.", s);
+	}
+
+	private Number parseNumber(UonParserSession session, ParserReader r, Class<? extends Number> c) throws Exception {
+		String s = parseString(session, r, false);
+		if (s == null)
+			return null;
+		return StringUtils.parseNumber(s, c);
+	}
+
+	/*
+	 * Call this method after you've finished a parsing a string to make sure that if there's any
+	 * remainder in the input, that it consists only of whitespace and comments.
+	 */
+	private void validateEnd(UonParserSession session, ParserReader r) throws Exception {
+		while (true) {
+			int c = r.read();
+			if (c == -1)
+				return;
+			if (! Character.isWhitespace(c))
+				throw new ParseException(session, "Remainder after parse: ''{0}''.", (char)c);
+		}
+	}
+
+	private Object[] parseArgs(UonParserSession session, ParserReader r, ClassMeta<?>[] argTypes) throws Exception {
+
+		final int S1=1; // Looking for start of entry
+		final int S2=2; // Looking for , or )
+
+		Object[] o = new Object[argTypes.length];
+		int i = 0;
+
+		int c = r.readSkipWs();
+		if (c == -1 || c == AMP)
+			return null;
+		if (c != '@')
+			throw new ParseException(session, "Expected '@' at beginning of args array.");
+		c = r.read();
+
+		int state = S1;
+		while (c != -1 && c != AMP) {
+			c = r.read();
+			if (state == S1) {
+				if (c == ')')
+					return o;
+				o[i] = parseAnything(session, argTypes[i], r.unread(), session.getOuter(), false, null);
+				i++;
+				state = S2;
+			} else if (state == S2) {
+				if (c == ',') {
+					state = S1;
+				} else if (c == ')') {
+					return o;
+				}
+			}
+		}
+
+		throw new ParseException(session, "Did not find ')' at the end of args array.");
+	}
+
+	private static void skipSpace(ParserReader r) throws Exception {
+		int c = 0;
+		while ((c = r.read()) != -1) {
+			if (c <= 2 || ! Character.isWhitespace(c)) {
+				r.unread();
+				return;
+			}
+		}
+	}
+
+	/**
+	 * Create a UON parser session for parsing parameter values.
+	 *
+	 * @param input
+	 * @return A new parser session.
+	 */
+	protected final UonParserSession createParameterSession(Object input) {
+		return new UonParserSession(ctx, input);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Entry point methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Parser */
+	public UonParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		return new UonParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
+	}
+
+	@Override /* Parser */
+	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
+		UonParserSession s = (UonParserSession)session;
+		UonReader r = s.getReader();
+		T o = parseAnything(s, type, r, s.getOuter(), true, null);
+		validateEnd(s, r);
+		return o;
+	}
+
+	@Override /* ReaderParser */
+	protected <K,V> Map<K,V> doParseIntoMap(ParserSession session, Map<K,V> m, Type keyType, Type valueType) throws Exception {
+		UonParserSession s = (UonParserSession)session;
+		UonReader r = s.getReader();
+		m = parseIntoMap(s, r, m, (ClassMeta<K>)session.getClassMeta(keyType), (ClassMeta<V>)session.getClassMeta(valueType), null);
+		validateEnd(s, r);
+		return m;
+	}
+
+	@Override /* ReaderParser */
+	protected <E> Collection<E> doParseIntoCollection(ParserSession session, Collection<E> c, Type elementType) throws Exception {
+		UonParserSession s = (UonParserSession)session;
+		UonReader r = s.getReader();
+		c = parseIntoCollection(s, r, c, (ClassMeta<E>)session.getClassMeta(elementType), false, null);
+		validateEnd(s, r);
+		return c;
+	}
+
+	@Override /* ReaderParser */
+	protected Object[] doParseArgs(ParserSession session, ClassMeta<?>[] argTypes) throws Exception {
+		UonParserSession s = (UonParserSession)session;
+		UonReader r = s.getReader();
+		Object[] a = parseArgs(s, r, argTypes);
+		return a;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
new file mode 100644
index 0000000..694a97e
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserBuilder.java
@@ -0,0 +1,495 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.uon.UonParserContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Builder class for building instances of UON parsers.
+ */
+public class UonParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public UonParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public UonParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParser build() {
+		return new UonParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b> Decode <js>"%xx"</js> sequences.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UonParser.decodeChars"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonParser}, <jk>true</jk> for {@link UrlEncodingParser}
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specify <jk>true</jk> if URI encoded characters should be decoded, <jk>false</jk>
+	 * 	if they've already been decoded before being passed to this parser.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>UON_decodeChars</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see UonParserContext#UON_decodeChars
+	 */
+	public UonParserBuilder decodeChars(boolean value) {
+		return property(UON_decodeChars, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>decodeChars(<jk>true</jk>)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public UonParserBuilder decoding() {
+		return decodeChars(true);
+	}
+
+	@Override /* ParserBuilder */
+	public UonParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UonParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UonParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UonParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UonParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> UonParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParserContext.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserContext.java
new file mode 100644
index 0000000..7217f9d
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserContext.java
@@ -0,0 +1,74 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Configurable properties on the {@link UonParser} class.
+ * <p>
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
+ * <p>
+ * See {@link PropertyStore} for more information about context properties.
+ *
+ * <h5 class='section'>Inherited configurable properties:</h5>
+ * <ul class='javahierarchy'>
+ * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
+ * 	<ul>
+ * 		<li class='c'><a class="doclink" href="../parser/ParserContext.html#ConfigProperties">ParserContext</a> - Configurable properties common to all parsers.
+ * 	</ul>
+ * </ul>
+ */
+public class UonParserContext extends ParserContext {
+
+	/**
+	 * <b>Configuration property:</b> Decode <js>"%xx"</js> sequences.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UonParser.decodeChars"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonParser}, <jk>true</jk> for {@link UrlEncodingParser}
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specify <jk>true</jk> if URI encoded characters should be decoded, <jk>false</jk>
+	 * 	if they've already been decoded before being passed to this parser.
+	 */
+	public static final String UON_decodeChars = "UonParser.decodeChars";
+
+	final boolean
+		decodeChars;
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
+	 *
+	 * @param ps The property store that created this context.
+	 */
+	public UonParserContext(PropertyStore ps) {
+		super(ps);
+		this.decodeChars = ps.getProperty(UON_decodeChars, boolean.class, false);
+	}
+
+	@Override /* Context */
+	public ObjectMap asMap() {
+		return super.asMap()
+			.append("UonParserContext", new ObjectMap()
+				.append("decodeChars", decodeChars)
+			);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonParserSession.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserSession.java
new file mode 100644
index 0000000..bf2334b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonParserSession.java
@@ -0,0 +1,118 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.uon.UonParserContext.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link UonParser}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ */
+public class UonParserSession extends ParserSession {
+
+	private final boolean decodeChars;
+	private UonReader reader;
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * 	he context contains all the configuration settings for this object.
+	 * @param input The input.  Can be any of the following types:
+	 * <ul>
+	 * 	<li><jk>null</jk>
+	 * 	<li>{@link Reader}
+	 * 	<li>{@link CharSequence}
+	 * 	<li>{@link InputStream} containing UTF-8 encoded text.
+	 * 	<li>{@link File} containing system encoded text.
+	 * </ul>
+	 * @param op The override properties.
+	 * These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param outer The outer object for instantiating top-level non-static inner classes.
+	 * @param locale The session locale.
+	 * If <jk>null</jk>, then the locale defined on the context is used.
+	 * @param timeZone The session timezone.
+	 * If <jk>null</jk>, then the timezone defined on the context is used.
+	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
+	 */
+	public UonParserSession(UonParserContext ctx, ObjectMap op, Object input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
+		if (op == null || op.isEmpty()) {
+			decodeChars = ctx.decodeChars;
+		} else {
+			decodeChars = op.getBoolean(UON_decodeChars, ctx.decodeChars);
+		}
+	}
+
+	/**
+	 * Create a specialized parser session for parsing URL parameters.
+	 * <p>
+	 * The main difference is that characters are never decoded, and the {@link UonParserContext#UON_decodeChars} property is always ignored.
+	 *
+	 * @param ctx The context to copy setting from.
+	 * @param input The input.  Can be any of the following types:
+	 * 	<ul>
+	 * 		<li><jk>null</jk>
+	 * 		<li>{@link Reader}
+	 * 		<li>{@link CharSequence} (e.g. {@link String})
+	 * 		<li>{@link InputStream} - Read as UTF-8 encoded character stream.
+	 * 		<li>{@link File} - Read as system-default encoded stream.
+	 * 	</ul>
+	 */
+	public UonParserSession(UonParserContext ctx, Object input) {
+		super(ctx, null, input, null, null, null, null, null);
+		decodeChars = false;
+	}
+
+	/**
+	 * Returns the {@link UonParserContext#UON_decodeChars} setting value for this session.
+	 *
+	 * @return The {@link UonParserContext#UON_decodeChars} setting value for this session.
+	 */
+	public final boolean isDecodeChars() {
+		return decodeChars;
+	}
+
+	@Override /* ParserSession */
+	public UonReader getReader() throws Exception {
+		if (reader == null) {
+			Object input = getInput();
+			if (input instanceof UonReader)
+				reader = (UonReader)input;
+			else if (input instanceof CharSequence)
+				reader = new UonReader((CharSequence)input, decodeChars);
+			else
+				reader = new UonReader(super.getReader(), decodeChars);
+		}
+		return reader;
+	}
+
+	@Override /* ParserSession */
+	public Map<String,Object> getLastLocation() {
+		Map<String,Object> m = super.getLastLocation();
+		if (reader != null) {
+			m.put("line", reader.getLine());
+			m.put("column", reader.getColumn());
+		}
+		return m;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonReader.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonReader.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonReader.java
new file mode 100644
index 0000000..eba2df4
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonReader.java
@@ -0,0 +1,195 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import java.io.*;
+
+import org.apache.juneau.parser.*;
+
+/**
+ * Same functionality as {@link ParserReader} except automatically decoded <code>%xx</code> escape sequences.
+ * <p>
+ * Escape sequences are assumed to be encoded UTF-8.  Extended Unicode (&gt;\u10000) is supported.
+ * <p>
+ * If decoding is enabled, the following character replacements occur so that boundaries are not lost:
+ * <ul>
+ * 	<li><js>'&amp;'</js> -&gt; <js>'\u0001'</js>
+ * 	<li><js>'='</js> -&gt; <js>'\u0002'</js>
+ * </ul>
+ */
+public final class UonReader extends ParserReader {
+
+	private final boolean decodeChars;
+	private final char[] buff;
+	private int iCurrent, iEnd;
+
+	/**
+	 * Constructor for input from a {@link CharSequence}.
+	 *
+	 * @param in The character sequence being read from.
+	 * @param decodeChars If <jk>true</jk>, decode <code>%xx</code> escape sequences.
+	 */
+	public UonReader(CharSequence in, boolean decodeChars) {
+		super(in);
+		this.decodeChars = decodeChars;
+		if (in == null || ! decodeChars)
+			this.buff = new char[0];
+		else
+			this.buff = new char[in.length() < 1024 ? in.length() : 1024];
+	}
+
+	/**
+	 * Constructor for input from a {@link Reader}).
+	 *
+	 * @param r The Reader being wrapped.
+	 * @param decodeChars If <jk>true</jk>, decode <code>%xx</code> escape sequences.
+	 */
+	public UonReader(Reader r, boolean decodeChars) {
+		super(r);
+		this.decodeChars = decodeChars;
+		this.buff = new char[1024];
+	}
+
+	@Override /* Reader */
+	public final int read(char[] cbuf, int off, int len) throws IOException {
+
+		if (! decodeChars)
+			return super.read(cbuf, off, len);
+
+		// Copy any remainder to the beginning of the buffer.
+		int remainder = iEnd - iCurrent;
+		if (remainder > 0)
+			System.arraycopy(buff, iCurrent, buff, 0, remainder);
+		iCurrent = 0;
+
+		int expected = buff.length - remainder;
+
+		int x = super.read(buff, remainder, expected);
+		if (x == -1 && remainder == 0)
+			return -1;
+
+		iEnd = remainder + (x == -1 ? 0 : x);
+
+		int i = 0;
+		while (i < len) {
+			if (iCurrent >= iEnd)
+				return i;
+			char c = buff[iCurrent++];
+			if (c == '+') {
+				cbuf[off + i++] = ' ';
+			} else if (c == '&') {
+				cbuf[off + i++] = '\u0001';
+			} else if (c == '=') {
+				cbuf[off + i++] = '\u0002';
+			} else if (c != '%') {
+				cbuf[off + i++] = c;
+			} else {
+				int iMark = iCurrent-1;  // Keep track of current position.
+
+				// Stop if there aren't at least two more characters following '%' in the buffer,
+				// or there aren't at least two more positions open in cbuf to handle double-char chars.
+				if (iMark+2 >= iEnd || i+2 > len) {
+					iCurrent--;
+					return i;
+				}
+
+				int b0 = readEncodedByte();
+				int cx;
+
+				// 0xxxxxxx
+				if (b0 < 128) {
+					cx = b0;
+
+				// 10xxxxxx
+				} else if (b0 < 192) {
+					throw new IOException("Invalid hex value for first escape pattern in UTF-8 sequence:  " + b0);
+
+				// 110xxxxx	10xxxxxx
+				// 11000000(192) - 11011111(223)
+				} else if (b0 < 224) {
+					cx = readUTF8(b0-192, 1);
+					if (cx == -1) {
+						iCurrent = iMark;
+						return i;
+					}
+
+				// 1110xxxx	10xxxxxx	10xxxxxx
+				// 11100000(224) - 11101111(239)
+				} else if (b0 < 240) {
+					cx = readUTF8(b0-224, 2);
+					if (cx == -1) {
+						iCurrent = iMark;
+						return i;
+					}
+
+				// 11110xxx	10xxxxxx	10xxxxxx	10xxxxxx
+				// 11110000(240) - 11110111(247)
+				} else if (b0 < 248) {
+					cx = readUTF8(b0-240, 3);
+					if (cx == -1) {
+						iCurrent = iMark;
+						return i;
+					}
+
+				} else
+					throw new IOException("Invalid hex value for first escape pattern in UTF-8 sequence:  " + b0);
+
+				if (cx < 0x10000)
+					cbuf[off + i++] = (char)cx;
+				else {
+					cx -= 0x10000;
+					cbuf[off + i++] = (char)(0xd800 + (cx >> 10));
+					cbuf[off + i++] = (char)(0xdc00 + (cx & 0x3ff));
+				}
+			}
+		}
+		return i;
+	}
+
+	private final int readUTF8(int n, final int numBytes) throws IOException {
+		if (iCurrent + numBytes*3 > iEnd)
+			return -1;
+		for (int i = 0; i < numBytes; i++) {
+			n <<= 6;
+			n += readHex()-128;
+		}
+		return n;
+	}
+
+	private final int readHex() throws IOException {
+		int c = buff[iCurrent++];
+		if (c != '%')
+			throw new IOException("Did not find expected '%' character in UTF-8 sequence.");
+		return readEncodedByte();
+	}
+
+	private final int readEncodedByte() throws IOException {
+		if (iEnd <= iCurrent + 1)
+			throw new IOException("Incomplete trailing escape pattern");
+		int h = buff[iCurrent++];
+		int l = buff[iCurrent++];
+		h = fromHexChar(h);
+		l = fromHexChar(l);
+		return (h << 4) + l;
+	}
+
+	private final int fromHexChar(int c) throws IOException {
+		if (c >= '0' && c <= '9')
+			return c - '0';
+		if (c >= 'a' && c <= 'f')
+			return 10 + c - 'a';
+		if (c >= 'A' && c <= 'F')
+			return 10 + c - 'A';
+		throw new IOException("Invalid hex character '"+c+"' found in escape pattern.");
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
new file mode 100644
index 0000000..6ecb85d
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializer.java
@@ -0,0 +1,386 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.apache.juneau.uon.UonSerializerContext.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Serializes POJO models to UON (a notation for URL-encoded query parameter values).
+ *
+ * <h5 class='section'>Media types:</h5>
+ * <p>
+ * Handles <code>Accept</code> types: <code>text/uon</code>
+ * <p>
+ * Produces <code>Content-Type</code> types: <code>text/uon</code>
+ *
+ * <h5 class='section'>Description:</h5>
+ * <p>
+ * This serializer provides several serialization options.  Typically, one of the predefined DEFAULT serializers will be sufficient.
+ * However, custom serializers can be constructed to fine-tune behavior.
+ *
+ * <h5 class='section'>Configurable properties:</h5>
+ * <p>
+ * This class has the following properties associated with it:
+ * <ul>
+ * 	<li>{@link UonSerializerContext}
+ * 	<li>{@link BeanContext}
+ * </ul>
+ * <p>
+ * The following shows a sample object defined in Javascript:
+ * </p>
+ * <p class='bcode'>
+ * 	{
+ * 		id: 1,
+ * 		name: <js>'John Smith'</js>,
+ * 		uri: <js>'http://sample/addressBook/person/1'</js>,
+ * 		addressBookUri: <js>'http://sample/addressBook'</js>,
+ * 		birthDate: <js>'1946-08-12T00:00:00Z'</js>,
+ * 		otherIds: <jk>null</jk>,
+ * 		addresses: [
+ * 			{
+ * 				uri: <js>'http://sample/addressBook/address/1'</js>,
+ * 				personUri: <js>'http://sample/addressBook/person/1'</js>,
+ * 				id: 1,
+ * 				street: <js>'100 Main Street'</js>,
+ * 				city: <js>'Anywhereville'</js>,
+ * 				state: <js>'NY'</js>,
+ * 				zip: 12345,
+ * 				isCurrent: <jk>true</jk>,
+ * 			}
+ * 		]
+ * 	}
+ * </p>
+ * <p>
+ * Using the "strict" syntax defined in this document, the equivalent
+ * 	UON notation would be as follows:
+ * </p>
+ * <p class='bcode'>
+ * 	(
+ * 		<ua>id</ua>=<un>1</un>,
+ * 		<ua>name</ua>=<us>'John+Smith'</us>,
+ * 		<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * 		<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+ * 		<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+ * 		<ua>otherIds</ua>=<uk>null</uk>,
+ * 		<ua>addresses</ua>=@(
+ * 			(
+ * 				<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>,
+ * 				<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>,
+ * 				<ua>id</ua>=<un>1</un>,
+ * 				<ua>street</ua>=<us>'100+Main+Street'</us>,
+ * 				<ua>city</ua>=<us>Anywhereville</us>,
+ * 				<ua>state</ua>=<us>NY</us>,
+ * 				<ua>zip</ua>=<un>12345</un>,
+ * 				<ua>isCurrent</ua>=<uk>true</uk>
+ * 			)
+ * 		)
+ * 	)
+ * </p>
+ *
+ * <h5 class='section'>Example:</h5>
+ * <p class='bcode'>
+ * 	<jc>// Serialize a Map</jc>
+ * 	Map m = <jk>new</jk> ObjectMap(<js>"{a:'b',c:1,d:false,e:['f',1,false],g:{h:'i'}}"</js>);
+ *
+ * 	<jc>// Serialize to value equivalent to JSON.</jc>
+ * 	<jc>// Produces "(a=b,c=1,d=false,e=@(f,1,false),g=(h=i))"</jc>
+ * 	String s = UonSerializer.<jsf>DEFAULT</jsf>.serialize(s);
+ *
+ * 	<jc>// Serialize a bean</jc>
+ * 	<jk>public class</jk> Person {
+ * 		<jk>public</jk> Person(String s);
+ * 		<jk>public</jk> String getName();
+ * 		<jk>public int</jk> getAge();
+ * 		<jk>public</jk> Address getAddress();
+ * 		<jk>public boolean</jk> deceased;
+ * 	}
+ *
+ * 	<jk>public class</jk> Address {
+ * 		<jk>public</jk> String getStreet();
+ * 		<jk>public</jk> String getCity();
+ * 		<jk>public</jk> String getState();
+ * 		<jk>public int</jk> getZip();
+ * 	}
+ *
+ * 	Person p = <jk>new</jk> Person(<js>"John Doe"</js>, 23, <js>"123 Main St"</js>, <js>"Anywhere"</js>, <js>"NY"</js>, 12345, <jk>false</jk>);
+ *
+ * 	<jc>// Produces "(name='John Doe',age=23,address=(street='123 Main St',city=Anywhere,state=NY,zip=12345),deceased=false)"</jc>
+ * 	String s = UonSerializer.<jsf>DEFAULT</jsf>.serialize(s);
+ * </p>
+ */
+@Produces("text/uon")
+public class UonSerializer extends WriterSerializer {
+
+	/** Reusable instance of {@link UonSerializer}, all default settings. */
+	public static final UonSerializer DEFAULT = new UonSerializer(PropertyStore.create());
+
+	/** Reusable instance of {@link UonSerializer.Readable}. */
+	public static final UonSerializer DEFAULT_READABLE = new Readable(PropertyStore.create());
+
+	/** Reusable instance of {@link UonSerializer.Encoding}. */
+	public static final UonSerializer DEFAULT_ENCODING = new Encoding(PropertyStore.create());
+
+	/**
+	 * Equivalent to <code><jk>new</jk> UonSerializerBuilder().ws().build();</code>.
+	 */
+	public static class Readable extends UonSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Readable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_useWhitespace, true);
+		}
+	}
+
+	/**
+	 * Equivalent to <code><jk>new</jk> UonSerializerBuilder().encoding().build();</code>.
+	 */
+	public static class Encoding extends UonSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Encoding(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(UON_encodeChars, true);
+		}
+	}
+
+
+	private final UonSerializerContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public UonSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(UonSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public UonSerializerBuilder builder() {
+		return new UonSerializerBuilder(propertyStore);
+	}
+
+	/**
+	 * Workhorse method. Determines the type of object, and then calls the
+	 * appropriate type-specific serialization method.
+	 * @param session The context that exist for the duration of a serialize.
+	 * @param out The writer to serialize to.
+	 * @param o The object being serialized.
+	 * @param eType The expected type of the object if this is a bean property.
+	 * @param attrName The bean property name if this is a bean property.  <jk>null</jk> if this isn't a bean property being serialized.
+	 * @param pMeta The bean property metadata.
+	 *
+	 * @return The same writer passed in.
+	 * @throws Exception
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	protected SerializerWriter serializeAnything(UonSerializerSession session, UonWriter out, Object o, ClassMeta<?> eType,
+			String attrName, BeanPropertyMeta pMeta) throws Exception {
+
+		if (o == null) {
+			out.appendObject(null, false);
+			return out;
+		}
+
+		if (eType == null)
+			eType = object();
+
+		ClassMeta<?> aType;			// The actual type
+		ClassMeta<?> sType;			// The serialized type
+
+		aType = session.push(attrName, o, eType);
+		boolean isRecursion = aType == null;
+
+		// Handle recursion
+		if (aType == null) {
+			o = null;
+			aType = object();
+		}
+
+		sType = aType.getSerializedClassMeta();
+		String typeName = session.getBeanTypeName(eType, aType, pMeta);
+
+		// Swap if necessary
+		PojoSwap swap = aType.getPojoSwap();
+		if (swap != null) {
+			o = swap.swap(session, o);
+
+			// If the getSwapClass() method returns Object, we need to figure out
+			// the actual type now.
+			if (sType.isObject())
+				sType = session.getClassMetaForObject(o);
+		}
+
+		// '\0' characters are considered null.
+		if (o == null || (sType.isChar() && ((Character)o).charValue() == 0))
+			out.appendObject(null, false);
+		else if (sType.isBoolean())
+			out.appendBoolean(o);
+		else if (sType.isNumber())
+			out.appendNumber(o);
+		else if (sType.isBean())
+			serializeBeanMap(session, out, session.toBeanMap(o), typeName);
+		else if (sType.isUri() || (pMeta != null && pMeta.isUri()))
+			out.appendUri(o);
+		else if (sType.isMap()) {
+			if (o instanceof BeanMap)
+				serializeBeanMap(session, out, (BeanMap)o, typeName);
+			else
+				serializeMap(session, out, (Map)o, eType);
+		}
+		else if (sType.isCollection()) {
+			serializeCollection(session, out, (Collection) o, eType);
+		}
+		else if (sType.isArray()) {
+			serializeCollection(session, out, toList(sType.getInnerClass(), o), eType);
+		}
+		else {
+			out.appendObject(o, false);
+		}
+
+		if (! isRecursion)
+			session.pop();
+		return out;
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private SerializerWriter serializeMap(UonSerializerSession session, UonWriter out, Map m, ClassMeta<?> type) throws Exception {
+
+		m = session.sort(m);
+
+		ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
+
+		int depth = session.getIndent();
+		out.append('(');
+
+		Iterator mapEntries = m.entrySet().iterator();
+
+		while (mapEntries.hasNext()) {
+			Map.Entry e = (Map.Entry) mapEntries.next();
+			Object value = e.getValue();
+			Object key = session.generalize(e.getKey(), keyType);
+			out.cr(depth).appendObject(key, false).append('=');
+			serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null);
+			if (mapEntries.hasNext())
+				out.append(',');
+		}
+
+		if (m.size() > 0)
+			out.cr(depth-1);
+		out.append(')');
+
+		return out;
+	}
+
+	private SerializerWriter serializeBeanMap(UonSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
+		int depth = session.getIndent();
+
+		out.append('(');
+
+		boolean addComma = false;
+
+		for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null)) {
+			BeanPropertyMeta pMeta = p.getMeta();
+			ClassMeta<?> cMeta = p.getClassMeta();
+
+			String key = p.getName();
+			Object value = p.getValue();
+			Throwable t = p.getThrown();
+			if (t != null)
+				session.addBeanGetterWarning(pMeta, t);
+
+			if (session.canIgnoreValue(cMeta, key, value))
+				continue;
+
+			if (addComma)
+				out.append(',');
+
+			out.cr(depth).appendObject(key, false).append('=');
+
+			serializeAnything(session, out, value, cMeta, key, pMeta);
+
+			addComma = true;
+		}
+
+		if (m.size() > 0)
+			out.cr(depth-1);
+		out.append(')');
+
+		return out;
+	}
+
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private SerializerWriter serializeCollection(UonSerializerSession session, UonWriter out, Collection c, ClassMeta<?> type) throws Exception {
+
+		ClassMeta<?> elementType = type.getElementType();
+
+		c = session.sort(c);
+
+		out.append('@').append('(');
+
+		int depth = session.getIndent();
+
+		for (Iterator i = c.iterator(); i.hasNext();) {
+			out.cr(depth);
+			serializeAnything(session, out, i.next(), elementType, "<iterator>", null);
+			if (i.hasNext())
+				out.append(',');
+		}
+
+		if (c.size() > 0)
+			out.cr(depth-1);
+		out.append(')');
+
+		return out;
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Entry point methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Serializer */
+	public UonSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		return new UonSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
+	}
+
+	@Override /* Serializer */
+	protected void doSerialize(SerializerSession session, Object o) throws Exception {
+		UonSerializerSession s = (UonSerializerSession)session;
+		serializeAnything(s, s.getWriter(), o, null, "root", null);
+	}
+}


[02/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/InheritanceTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/InheritanceTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/InheritanceTest.java
index 25acda5..a716cc8 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/InheritanceTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/InheritanceTest.java
@@ -14,23 +14,13 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
 public class InheritanceTest extends RestTestcase {
 
-	private static RestClient client;
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
-	@BeforeClass
-	public static void beforeClass() {
-		client = new TestRestClient();
-	}
-
-	@AfterClass
-	public static void afterClass() {
-		client.closeQuietly();
-	}
 
 	//====================================================================================================
 	// Test serializer inheritance.
@@ -81,7 +71,7 @@ public class InheritanceTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testTransforms() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.class, JsonParser.class).setAccept("text/json+simple");
+		RestClient client = TestMicroservice.client().accept("text/json+simple").build();
 		String r;
 		String url = "/testInheritanceTransforms";
 
@@ -108,7 +98,7 @@ public class InheritanceTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testProperties() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.class, JsonParser.class).setAccept("text/json+simple");
+		RestClient client = TestMicroservice.client().accept("text/json+simple").build();
 		String r;
 		String url = "/testInheritanceProperties";
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/LargePojosTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/LargePojosTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/LargePojosTest.java
index dc5c944..f2db303 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/LargePojosTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/LargePojosTest.java
@@ -13,9 +13,8 @@
 package org.apache.juneau.rest.test;
 
 import org.apache.juneau.html.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
-import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
 
@@ -35,7 +34,7 @@ public class LargePojosTest extends RestTestcase {
 		RestClient c;
 
 		System.err.println("\n---Testing JSON---");
-		c = new TestRestClient(JsonSerializer.class, JsonParser.class);
+		c = TestMicroservice.DEFAULT_CLIENT;
 		for (int i = 1; i <= 3; i++) {
 			t = System.currentTimeMillis();
 			p = c.doGet(URL).getResponse(LargePojo.class);
@@ -46,7 +45,7 @@ public class LargePojosTest extends RestTestcase {
 		}
 
 		System.err.println("\n---Testing XML---");
-		c = new TestRestClient(XmlSerializer.class, XmlParser.class);
+		c = TestMicroservice.client(XmlSerializer.class, XmlParser.class).build();
 		for (int i = 1; i <= 3; i++) {
 			t = System.currentTimeMillis();
 			p = c.doGet(URL).getResponse(LargePojo.class);
@@ -57,7 +56,7 @@ public class LargePojosTest extends RestTestcase {
 		}
 
 		System.err.println("\n---Testing HTML---");
-		c = new TestRestClient(HtmlSerializer.class, HtmlParser.class).setAccept("text/html+stripped");
+		c = TestMicroservice.client(HtmlSerializer.class, HtmlParser.class).accept("text/html+stripped").build();
 		for (int i = 1; i <= 3; i++) {
 			t = System.currentTimeMillis();
 			p = c.doGet(URL).getResponse(LargePojo.class);
@@ -67,8 +66,10 @@ public class LargePojosTest extends RestTestcase {
 			System.err.println("Upload: ["+(System.currentTimeMillis() - t)+"] ms");
 		}
 
+		c.closeQuietly();
+
 		System.err.println("\n---Testing UrlEncoding---");
-		c = new TestRestClient(UonSerializer.class, UonParser.class);
+		c = TestMicroservice.client(UonSerializer.class, UonParser.class).build();
 		for (int i = 1; i <= 3; i++) {
 			t = System.currentTimeMillis();
 			p = c.doGet(URL).getResponse(LargePojo.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/MessagesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/MessagesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/MessagesTest.java
index e833de7..5cb4b82 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/MessagesTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/MessagesTest.java
@@ -16,7 +16,6 @@ import static org.apache.juneau.rest.test.TestUtils.*;
 
 import java.util.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -31,7 +30,7 @@ public class MessagesTest extends RestTestcase {
 	@SuppressWarnings("rawtypes")
 	@Test
 	public void test() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.class,JsonParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
 		// Parent resource should just pick up values from its bundle.
 		TreeMap r = client.doGet("/testMessages/test").getResponse(TreeMap.class);
@@ -41,7 +40,5 @@ public class MessagesTest extends RestTestcase {
 		// ordered child before parent.
 		r = client.doGet("/testMessages2/test").getResponse(TreeMap.class);
 		assertObjectEquals("{key1:'value1a',key2:'value2b',key3:'value3b'}", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsPropertyTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsPropertyTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsPropertyTest.java
index ddd9c5d..55b0272 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsPropertyTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsPropertyTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,11 +26,9 @@ public class NlsPropertyTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testInheritedFromClass() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String r = client.doGet(URL + "/testInheritedFromClass").getResponseAsString();
 		assertEquals("value1", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -39,10 +36,8 @@ public class NlsPropertyTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testInheritedFromMethod() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String r = client.doGet(URL + "/testInheritedFromMethod").getResponseAsString();
 		assertEquals("value2", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsTest.java
index 6869df8..1cb00c6 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NlsTest.java
@@ -15,27 +15,24 @@ package org.apache.juneau.rest.test;
 import static org.apache.juneau.rest.test.TestUtils.*;
 
 import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
 public class NlsTest extends RestTestcase {
 
 	private static String URL = "/testNls";
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
 	// ====================================================================================================
 	// test1 - Pull labels from annotations only.
 	// ====================================================================================================
 	@Test
 	public void test1() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test1").getResponse(Swagger.class);
 		assertObjectEquals("{title:'Test1.a',description:'Test1.b'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'Test1.f'},{'in':'header',name:'D',type:'string',description:'Test1.g'},{'in':'header',name:'D2',type:'string',description:'Test1.j'},{'in':'header',name:'g'},{'in':'path',name:'a',type:'string',description:'Test1.d',required:true},{'in':'path',name:'a2',type:'string',description:'Test1.h',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',type:'string',description:'Test1.e'},{'in':'query',name:'b2',type:'string',description:'Test1.i'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'OK'},'201':{description:'Test1.l',headers:{bar:{description:'Test1.m',type:'string'}}}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 
 	// ====================================================================================================
@@ -43,14 +40,11 @@ public class NlsTest extends RestTestcase {
 	// ====================================================================================================
 	@Test
 	public void test2() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test2").getResponse(Swagger.class);
 		assertObjectEquals("{title:'Test2.a',description:'Test2.b'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'Test2.f'},{'in':'header',name:'D',description:'Test2.g'},{'in':'header',name:'D2',description:'Test2.j'},{'in':'header',name:'g'},{'in':'path',name:'a',description:'Test2.d',required:true},{'in':'path',name:'a2',description:'Test2.h',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',description:'Test2.e'},{'in':'query',name:'b2',description:'Test2.i'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'OK2'},'201':{description:'Test2.l'}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 
 	// ====================================================================================================
@@ -58,14 +52,11 @@ public class NlsTest extends RestTestcase {
 	// ====================================================================================================
 	@Test
 	public void test3() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test3").getResponse(Swagger.class);
 		assertObjectEquals("{title:'Test3.a',description:'Test3.b'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'Test3.f'},{'in':'header',name:'D',description:'Test3.g'},{'in':'header',name:'D2',description:'Test3.j'},{'in':'header',name:'g'},{'in':'path',name:'a',description:'Test3.d',required:true},{'in':'path',name:'a2',description:'Test3.h',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',description:'Test3.e'},{'in':'query',name:'b2',description:'Test3.i'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'OK3'},'201':{description:'Test3.l'}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 
 	// ====================================================================================================
@@ -73,14 +64,11 @@ public class NlsTest extends RestTestcase {
 	// ====================================================================================================
 	@Test
 	public void test4() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test4").getResponse(Swagger.class);
 		assertObjectEquals("{title:'baz',description:'baz'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'baz'},{'in':'header',name:'D',description:'baz'},{'in':'header',name:'D2',description:'baz'},{'in':'header',name:'g'},{'in':'path',name:'a',description:'baz',required:true},{'in':'path',name:'a2',description:'baz',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',description:'baz'},{'in':'query',name:'b2',description:'baz'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'foobazfoobazfoo'},'201':{description:'baz'}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 
 	// ====================================================================================================
@@ -88,14 +76,11 @@ public class NlsTest extends RestTestcase {
 	// ====================================================================================================
 	@Test
 	public void test5() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test5").getResponse(Swagger.class);
 		assertObjectEquals("{title:'baz2',description:'baz2'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'baz2'},{'in':'header',name:'D',description:'baz2'},{'in':'header',name:'D2',description:'baz2'},{'in':'header',name:'g'},{'in':'path',name:'a',description:'baz2',required:true},{'in':'path',name:'a2',description:'baz2',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',description:'baz2'},{'in':'query',name:'b2',description:'baz2'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'foobaz2foobaz2foo'},'201':{description:'baz2'}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 
 	// ====================================================================================================
@@ -103,13 +88,10 @@ public class NlsTest extends RestTestcase {
 	// ====================================================================================================
 	@Test
 	public void test6() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 
 		Swagger s = client.doOptions(URL + "/test6").getResponse(Swagger.class);
 		assertObjectEquals("{title:'baz',description:'baz'}", s.getInfo());
 		assertObjectEquals("[{'in':'body',description:'baz'},{'in':'header',name:'D',type:'string',description:'baz'},{'in':'header',name:'D2',type:'string',description:'baz'},{'in':'header',name:'g'},{'in':'path',name:'a',type:'string',description:'baz',required:true},{'in':'path',name:'a2',type:'string',description:'baz',required:true},{'in':'path',name:'e',required:true},{'in':'query',name:'b',type:'string',description:'baz'},{'in':'query',name:'b2',type:'string',description:'baz'},{'in':'query',name:'f'}]", s.getPaths().get("/{a}").get("post").getParameters());
 		assertObjectEquals("{'200':{description:'OK'},'201':{description:'baz',headers:{bar:{description:'baz',type:'string'}}}}", s.getPaths().get("/{a}").get("post").getResponses());
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NoParserInputTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NoParserInputTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NoParserInputTest.java
index b63d14a..0c9b2a3 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NoParserInputTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/NoParserInputTest.java
@@ -16,7 +16,6 @@ import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
-import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -24,17 +23,15 @@ public class NoParserInputTest extends RestTestcase {
 
 	private static String URL = "/testNoParserInput";
 	private static boolean debug = false;
+	RestClient plainTextClient = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 
 	//====================================================================================================
 	// @Body annotated InputStream.
 	//====================================================================================================
 	@Test
 	public void testInputStream() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
-		String r = client.doPut(URL + "/testInputStream", "foo").getResponseAsString();
+		String r = plainTextClient.doPut(URL + "/testInputStream", "foo").getResponseAsString();
 		assertEquals("foo", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -42,11 +39,8 @@ public class NoParserInputTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testReader() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
-		String r = client.doPut(URL + "/testReader", "foo").getResponseAsString();
+		String r = plainTextClient.doPut(URL + "/testReader", "foo").getResponseAsString();
 		assertEquals("foo", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -55,16 +49,13 @@ public class NoParserInputTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPushbackReader() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
 		try {
-			client.doPut(URL + "/testPushbackReader?noTrace=true", "foo").getResponseAsString();
+			plainTextClient.doPut(URL + "/testPushbackReader?noTrace=true", "foo").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_BAD_REQUEST,
 				"Invalid argument type passed to the following method:",
 				"'public java.lang.String org.apache.juneau.rest.test.NoParserInputResource.testPushbackReader(java.io.PushbackReader) throws java.lang.Exception'");
 		}
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPostCallTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPostCallTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPostCallTest.java
index aa52ca6..e7786b9 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPostCallTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPostCallTest.java
@@ -28,7 +28,7 @@ public class OnPostCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverridenByAnnotation() throws Exception {
-		RestClient client = new TestRestClient().setAccept("text/s1");
+		RestClient client = TestMicroservice.client().accept("text/s1").build();
 		String url = URL + "/testPropertiesOverridenByAnnotation";
 		String r;
 		RestCall rc;
@@ -36,10 +36,10 @@ public class OnPostCallTest extends RestTestcase {
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Accept", "text/s2").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Accept", "text/s2").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 
-		rc = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/s3").connect();
+		rc = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/s3").connect();
 		r = rc.getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s1", r);
 		assertTrue(rc.getResponse().getFirstHeader("Content-Type").getValue().startsWith("text/s3"));
@@ -52,7 +52,7 @@ public class OnPostCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverridenByAnnotationDefaultAccept() throws Exception {
-		RestClient client = new TestRestClient().setAccept("");
+		RestClient client = TestMicroservice.client().accept("").build();
 		String url = URL + "/testPropertiesOverridenByAnnotation";
 		String r;
 		RestCall rc;
@@ -60,10 +60,10 @@ public class OnPostCallTest extends RestTestcase {
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Accept", "text/s3").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Accept", "text/s3").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s3", r);
 
-		rc = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/s3").connect();
+		rc = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/s3").connect();
 		r = rc.getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 		assertTrue(rc.getResponse().getFirstHeader("Content-Type").getValue().startsWith("text/s3"));
@@ -76,7 +76,7 @@ public class OnPostCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverriddenProgramatically() throws Exception {
-		RestClient client = new TestRestClient().setAccept("text/s1");
+		RestClient client = TestMicroservice.client().accept("text/s1").build();
 		String url = URL + "/testPropertiesOverriddenProgramatically";
 		String r;
 		RestCall rc;
@@ -84,10 +84,10 @@ public class OnPostCallTest extends RestTestcase {
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Accept", "text/s2").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Accept", "text/s2").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 
-		rc = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/s3").connect();
+		rc = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/s3").connect();
 		r = rc.getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s1", r);
 		assertTrue(rc.getResponse().getFirstHeader("Content-Type").getValue().startsWith("text/s3"));
@@ -100,7 +100,7 @@ public class OnPostCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverriddenProgramaticallyDefaultAccept() throws Exception {
-		RestClient client = new TestRestClient().setAccept("");
+		RestClient client = TestMicroservice.client().accept("").build();
 		String url = URL + "/testPropertiesOverriddenProgramatically";
 		String r;
 		RestCall rc;
@@ -108,10 +108,10 @@ public class OnPostCallTest extends RestTestcase {
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Accept", "text/s3").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Accept", "text/s3").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s3", r);
 
-		rc = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/s3").connect();
+		rc = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/s3").connect();
 		r = rc.getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=xp4,p5=xp5,contentType=text/s2", r);
 		assertTrue(rc.getResponse().getFirstHeader("Content-Type").getValue().startsWith("text/s3"));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPreCallTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPreCallTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPreCallTest.java
index 8159dad..12a4201 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPreCallTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OnPreCallTest.java
@@ -28,14 +28,14 @@ public class OnPreCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverriddenByAnnotation() throws Exception {
-		RestClient client = new TestRestClient().setContentType("text/a1").setAccept("text/plain");
+		RestClient client = TestMicroservice.client().contentType("text/a1").accept("text/plain").build();
 		String url = URL + "/testPropertiesOverriddenByAnnotation";
 		String r;
 
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a1", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/a2").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/a2").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=mp3,p4=xp4,p5=xp5,contentType=text/a2", r);
 
 		client.closeQuietly();
@@ -46,14 +46,14 @@ public class OnPreCallTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesOverriddenProgrammatically() throws Exception {
-		RestClient client = new TestRestClient().setContentType("text/a1").setAccept("text/plain");
+		RestClient client = TestMicroservice.client().contentType("text/a1").accept("text/plain").build();
 		String url = URL + "/testPropertiesOverriddenProgrammatically";
 		String r;
 
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a1", r);
 
-		r = client.doPut(url, new StringReader("")).setHeader("Override-Content-Type", "text/a2").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).header("Override-Content-Type", "text/a2").getResponseAsString();
 		assertEquals("p1=sp1,p2=xp2,p3=pp3,p4=pp4,p5=xp5,contentType=text/a2", r);
 
 		client.closeQuietly();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OptionsWithoutNlsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OptionsWithoutNlsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OptionsWithoutNlsTest.java
index 36529af..ce34166 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OptionsWithoutNlsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OptionsWithoutNlsTest.java
@@ -15,25 +15,22 @@ package org.apache.juneau.rest.test;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.dto.swagger.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
 public class OptionsWithoutNlsTest extends RestTestcase {
 
 	private static String URL = "/testOptionsWithoutNls";
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
 	//====================================================================================================
 	// Should get to the options page without errors
 	//====================================================================================================
 	@Test
 	public void testOptions() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 		RestCall r = client.doOptions(URL + "/testOptions");
 		Swagger o = r.getResponse(Swagger.class);
 		assertNotNull(o.getInfo());
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -41,11 +38,8 @@ public class OptionsWithoutNlsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testMissingResourceBundle() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
 		RestCall r = client.doGet(URL + "/testMissingResourceBundle");
 		String o = r.getResponse(String.class);
 		assertEquals("{!!bad}", o);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OverlappingMethodsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OverlappingMethodsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OverlappingMethodsTest.java
index 4b4cb43..6822566 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OverlappingMethodsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/OverlappingMethodsTest.java
@@ -29,7 +29,7 @@ public class OverlappingMethodsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOverlappingGuards1() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testOverlappingGuards1";
 
@@ -51,7 +51,7 @@ public class OverlappingMethodsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOverlappingGuards2() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testOverlappingGuards2";
 		try {
@@ -86,7 +86,7 @@ public class OverlappingMethodsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOverlappingMatchers1() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testOverlappingMatchers1";
 
@@ -107,7 +107,7 @@ public class OverlappingMethodsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOverlappingMatchers2() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testOverlappingMatchers2";
 
@@ -131,7 +131,7 @@ public class OverlappingMethodsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOverlappingUrlPatterns() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testOverlappingUrlPatterns";
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
index 9e14c52..77bc2c0 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParamsTest.java
@@ -23,7 +23,6 @@ import org.apache.http.client.entity.*;
 import org.apache.http.entity.*;
 import org.apache.http.message.*;
 import org.apache.juneau.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -37,7 +36,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testBasic() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		RestCall r;
 
 		//		@Override
@@ -168,8 +167,6 @@ public class ParamsTest extends RestTestcase {
 		UUID uuid = UUID.randomUUID();
 		r = client.doPut(URL + "/uuid/"+uuid, "");
 		assertEquals("PUT /uuid/"+uuid, r.getResponse(String.class));
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -177,7 +174,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testParamGet";
 
@@ -214,7 +211,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPlainParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testPlainParamGet";
 
@@ -232,7 +229,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParamPost() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testParamPost";
 
@@ -268,7 +265,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPlainParamPost() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testPlainParamPost";
 
@@ -294,7 +291,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testQParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testQParamGet";
 
@@ -331,7 +328,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPlainQParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testPlainQParamGet";
 
@@ -349,7 +346,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testQParamPost() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testQParamPost";
 
@@ -385,7 +382,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testHasParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testHasParamGet";
 
@@ -422,7 +419,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testHasParamPost() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testHasParamPost";
 
@@ -458,7 +455,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testHasQParamGet() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testHasQParamGet";
 
@@ -495,7 +492,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testHasQParamPost() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testHasQParamPost";
 
@@ -531,7 +528,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testFormPostAsContent() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testFormPostAsContent";
 
@@ -555,7 +552,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testMultiPartParams() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testMultiPartParams";
 
@@ -597,7 +594,7 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testMultiPartParamsSingleValues() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.client().accept("text/plain").build();
 		String r;
 		String url = URL + "/testMultiPartParams";
 
@@ -641,9 +638,10 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testFormPostsWithMultiParamsUsingProperty() throws Exception {
-		RestClient client = new TestRestClient()
-			.setHeader("Content-Type", "application/x-www-form-urlencoded")
-			.setHeader("Accept", "application/x-www-form-urlencoded");
+		RestClient client = TestMicroservice.client()
+			.contentType("application/x-www-form-urlencoded")
+			.accept("application/x-www-form-urlencoded")
+			.build();
 		String r;
 		String url = URL + "/testFormPostsWithMultiParamsUsingProperty";
 
@@ -681,9 +679,10 @@ public class ParamsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testFormPostsWithMultiParamsUsingAnnotation() throws Exception {
-		RestClient client = new TestRestClient()
-			.setHeader("Content-Type", "application/x-www-form-urlencoded")
-			.setHeader("Accept", "application/x-www-form-urlencoded");
+		RestClient client = TestMicroservice.client()
+			.contentType("application/x-www-form-urlencoded")
+			.accept("application/x-www-form-urlencoded")
+			.build();
 		String r;
 		String url = URL + "/testFormPostsWithMultiParamsUsingAnnotation";
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParsersTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParsersTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParsersTest.java
index 48f86ce..21e07a1 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParsersTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ParsersTest.java
@@ -16,7 +16,6 @@ import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
-import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -30,16 +29,14 @@ public class ParsersTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParserOnClass() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/testParserOnClass";
 
-		client.setContentType("text/a");
-		String r = client.doPut(url, "test1").getResponseAsString();
+		String r = client.doPut(url, "test1").contentType("text/a").getResponseAsString();
 		assertEquals("text/a - test1", r);
 
 		try {
-			client.setContentType("text/b");
-			client.doPut(url + "?noTrace=true", "test1").getResponseAsString();
+			client.doPut(url + "?noTrace=true", "test1").contentType("text/b").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -48,11 +45,8 @@ public class ParsersTest extends RestTestcase {
 			);
 		}
 
-		client.setContentType("text/json").setAccept("text/json");
-		r = client.doPut(url, "'test1'").getResponseAsString();
+		r = client.doPut(url, "'test1'").contentType("text/json").accept("text/json").getResponseAsString();
 		assertEquals("\"test1\"", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -60,16 +54,14 @@ public class ParsersTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParserOnMethod() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/testParserOnMethod";
 
-		client.setContentType("text/b");
-		String r = client.doPut(url, "test2").getResponseAsString();
+		String r = client.doPut(url, "test2").contentType("text/b").getResponseAsString();
 		assertEquals("text/b - test2", r);
 
 		try {
-			client.setContentType("text/a");
-			client.doPut(url + "?noTrace=true", "test2").getResponseAsString();
+			client.doPut(url + "?noTrace=true", "test2").contentType("text/a").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -79,8 +71,7 @@ public class ParsersTest extends RestTestcase {
 		}
 
 		try {
-			client.setContentType("text/json");
-			r = client.doPut(url + "?noTrace=true", "'test2'").getResponseAsString();
+			r = client.doPut(url + "?noTrace=true", "'test2'").contentType("text/json").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -88,8 +79,6 @@ public class ParsersTest extends RestTestcase {
 				"Supported media-types: [text/b]"
 			);
 		}
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -97,22 +86,17 @@ public class ParsersTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParserOverriddenOnMethod() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/testParserOverriddenOnMethod";
 
-		client.setContentType("text/a");
-		String r = client.doPut(url, "test3").getResponseAsString();
+		String r = client.doPut(url, "test3").contentType("text/a").getResponseAsString();
 		assertEquals("text/a - test3", r);
 
-		client.setContentType("text/b");
-		r = client.doPut(url, "test3").getResponseAsString();
+		r = client.doPut(url, "test3").contentType("text/b").getResponseAsString();
 		assertEquals("text/b - test3", r);
 
-		client.setContentType("text/json");
-		r = client.doPut(url, "'test3'").getResponseAsString();
+		r = client.doPut(url, "'test3'").contentType("text/json").getResponseAsString();
 		assertEquals("test3", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -120,22 +104,17 @@ public class ParsersTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testParserWithDifferentMediaTypes() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/testParserWithDifferentMediaTypes";
 
-		client.setContentType("text/a");
-		String r = client.doPut(url, "test4").getResponseAsString();
+		String r = client.doPut(url, "test4").contentType("text/a").getResponseAsString();
 		assertEquals("text/d - test4", r);
 
-		client.setContentType("text/d");
-		r = client.doPut(url, "test4").getResponseAsString();
+		r = client.doPut(url, "test4").contentType("text/d").getResponseAsString();
 		assertEquals("text/d - test4", r);
 
-		client.setContentType("text/json");
-		r = client.doPut(url, "'test4'").getResponseAsString();
+		r = client.doPut(url, "'test4'").contentType("text/json").getResponseAsString();
 		assertEquals("test4", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -143,12 +122,11 @@ public class ParsersTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testValidErrorResponse() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/testValidErrorResponse";
 
 		try {
-			client.setContentType("text/bad");
-			client.doPut(url + "?noTrace=true", "test1").getResponseAsString();
+			client.doPut(url + "?noTrace=true", "test1").contentType("text/bad").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -156,7 +134,5 @@ public class ParsersTest extends RestTestcase {
 				"Supported media-types: [text/a"
 			);
 		}
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
index 733a685..a4c9db5 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,7 +26,7 @@ public class PathTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testBasic() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r = null;
 
 		r = client.doGet(URL).getResponse(String.class);
@@ -38,7 +37,5 @@ public class PathTest extends RestTestcase {
 
 		r = client.doGet(URL + "/testPath2/testPath3").getResponse(String.class);
 		assertEquals("/testPath/testPath2/testPath3", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathsTest.java
index 4282a80..6aa8517 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PathsTest.java
@@ -15,7 +15,6 @@ package org.apache.juneau.rest.test;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -28,7 +27,7 @@ public class PathsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testBasic() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		ObjectMap r;
 		String url;
 
@@ -1362,7 +1361,5 @@ public class PathsTest extends RestTestcase {
 		assertTrue(r.getString("servletParentURI").endsWith("/testPaths"));
 		assertTrue(r.getString("relativeServletURI").endsWith("/testPaths/a"));
 		assertEquals(4, (int)r.getInt("method"));
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
index 67b827a..f52a564 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/PropertiesTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,11 +26,9 @@ public class PropertiesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testPropertiesDefinedOnMethod() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r = client.doGet(URL + "/testPropertiesDefinedOnMethod").getResponseAsString();
 		assertTrue(r.matches("A1=a1,A2=c,B1=b1,B2=c,C=c,R1a=.*/testProperties/testPropertiesDefinedOnMethod,R1b=.*/testProperties,R2=bar,R3=baz,R4=a1,R5=c,R6=c"));
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -39,10 +36,8 @@ public class PropertiesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testProperties() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
-		String r = client.doGet(URL + "/testProperties/a1?P=p1").setHeader("H", "h1").getResponseAsString();
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
+		String r = client.doGet(URL + "/testProperties/a1?P=p1").header("H", "h1").getResponseAsString();
 		assertEquals("A=a1,P=p1,H=h1", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestClientTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestClientTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestClientTest.java
index 7902f5b..2250489 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestClientTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/RestClientTest.java
@@ -19,7 +19,6 @@ import java.util.*;
 import java.util.regex.*;
 
 import org.apache.http.entity.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -32,7 +31,7 @@ public class RestClientTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testSuccessPattern() throws Exception {
-		RestClient c = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient c = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 		int rc;
 
@@ -47,8 +46,6 @@ public class RestClientTest extends RestTestcase {
 		} catch (RestCallException e) {
 			assertEquals("Success pattern not detected.", e.getLocalizedMessage());
 		}
-
-		c.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -56,7 +53,7 @@ public class RestClientTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testFailurePattern() throws Exception {
-		RestClient c = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient c = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 		int rc;
 
@@ -78,8 +75,6 @@ public class RestClientTest extends RestTestcase {
 		} catch (RestCallException e) {
 			assertEquals("Failure pattern detected.", e.getLocalizedMessage());
 		}
-
-		c.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -87,7 +82,7 @@ public class RestClientTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testCaptureResponse() throws Exception {
-		RestClient c = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient c = TestMicroservice.DEFAULT_CLIENT;
 		RestCall rc = c.doPost(URL, new StringEntity("xxx")).captureResponse();
 
 		try {
@@ -111,8 +106,6 @@ public class RestClientTest extends RestTestcase {
 		} catch (IllegalStateException e) {
 			assertEquals("Method cannot be called.  Response has already been consumed.", e.getLocalizedMessage());
 		}
-
-		c.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -120,7 +113,7 @@ public class RestClientTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testAddResponsePattern() throws Exception {
-		RestClient c = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient c = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		final List<String> l = new ArrayList<String>();
@@ -135,18 +128,18 @@ public class RestClientTest extends RestTestcase {
 			}
 		};
 
-		r = c.doPost(URL, new StringEntity("x=1,y=2")).addResponsePattern(p).getResponseAsString();
+		r = c.doPost(URL, new StringEntity("x=1,y=2")).responsePattern(p).getResponseAsString();
 		assertEquals("x=1,y=2", r);
 		assertObjectEquals("['1/2']", l);
 
 		l.clear();
 
-		r = c.doPost(URL, new StringEntity("x=1,y=2\nx=3,y=4")).addResponsePattern(p).getResponseAsString();
+		r = c.doPost(URL, new StringEntity("x=1,y=2\nx=3,y=4")).responsePattern(p).getResponseAsString();
 		assertEquals("x=1,y=2\nx=3,y=4", r);
 		assertObjectEquals("['1/2','3/4']", l);
 
 		try {
-			c.doPost(URL, new StringEntity("x=1")).addResponsePattern(p).run();
+			c.doPost(URL, new StringEntity("x=1")).responsePattern(p).run();
 			fail();
 		} catch (RestCallException e) {
 			assertEquals("Pattern not found!", e.getLocalizedMessage());
@@ -176,24 +169,22 @@ public class RestClientTest extends RestTestcase {
 		};
 
 		l.clear();
-		r = c.doPost(URL, new StringEntity("x=1,y=2\nx=3,y=4")).addResponsePattern(p1).addResponsePattern(p2).getResponseAsString();
+		r = c.doPost(URL, new StringEntity("x=1,y=2\nx=3,y=4")).responsePattern(p1).responsePattern(p2).getResponseAsString();
 		assertEquals("x=1,y=2\nx=3,y=4", r);
 		assertObjectEquals("['x=1','x=3','y=2','y=4']", l);
 
 		try {
-			c.doPost(URL, new StringEntity("x=1\nx=3")).addResponsePattern(p1).addResponsePattern(p2).getResponseAsString();
+			c.doPost(URL, new StringEntity("x=1\nx=3")).responsePattern(p1).responsePattern(p2).getResponseAsString();
 		} catch (RestCallException e) {
 			assertEquals("Pattern y not found!", e.getLocalizedMessage());
 			assertEquals(0, e.getResponseCode());
 		}
 
 		try {
-			c.doPost(URL, new StringEntity("y=1\ny=3")).addResponsePattern(p1).addResponsePattern(p2).getResponseAsString();
+			c.doPost(URL, new StringEntity("y=1\ny=3")).responsePattern(p1).responsePattern(p2).getResponseAsString();
 		} catch (RestCallException e) {
 			assertEquals("Pattern x not found!", e.getLocalizedMessage());
 			assertEquals(0, e.getResponseCode());
 		}
-
-		c.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/SerializersTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/SerializersTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/SerializersTest.java
index ab0649c..b7947f0 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/SerializersTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/SerializersTest.java
@@ -16,7 +16,6 @@ import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -24,17 +23,8 @@ public class SerializersTest extends RestTestcase {
 
 	private static String URL = "/testSerializers";
 	private static boolean debug = false;
-	private static RestClient client;
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
-	@BeforeClass
-	public static void beforeClass() {
-		client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
-	}
-
-	@AfterClass
-	public static void afterClass() {
-		client.closeQuietly();
-	}
 
 	//====================================================================================================
 	// Serializer defined on class.
@@ -43,13 +33,11 @@ public class SerializersTest extends RestTestcase {
 	public void testSerializerOnClass() throws Exception {
 		String url = URL + "/testSerializerOnClass";
 
-		client.setAccept("text/a");
-		String r = client.doGet(url).getResponseAsString();
+		String r = client.doGet(url).accept("text/a").getResponseAsString();
 		assertEquals("text/a - test1", r);
 
 		try {
-			client.setAccept("text/b");
-			client.doGet(url + "?noTrace=true").getResponseAsString();
+			client.doGet(url + "?noTrace=true").accept("text/b").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -57,8 +45,7 @@ public class SerializersTest extends RestTestcase {
 				"Supported media-types: [text/a, ");
 		}
 
-		client.setAccept("text/json");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/json").getResponseAsString();
 		assertEquals("\"test1\"", r);
 	}
 
@@ -70,8 +57,7 @@ public class SerializersTest extends RestTestcase {
 		String url = URL + "/testSerializerOnMethod";
 
 		try {
-			client.setAccept("text/a");
-			client.doGet(url + "?noTrace=true").getResponseAsString();
+			client.doGet(url + "?noTrace=true").accept("text/a").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -81,8 +67,7 @@ public class SerializersTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/json");
-			client.doGet(url + "?noTrace=true").getResponseAsString();
+			client.doGet(url + "?noTrace=true").accept("text/json").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -99,16 +84,13 @@ public class SerializersTest extends RestTestcase {
 	public void testSerializerOverriddenOnMethod() throws Exception {
 		String url = URL + "/testSerializerOverriddenOnMethod";
 
-		client.setAccept("text/a");
-		String r = client.doGet(url).getResponseAsString();
+		String r = client.doGet(url).accept("text/a").getResponseAsString();
 		assertEquals("text/c - test3", r);
 
-		client.setAccept("text/b");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/b").getResponseAsString();
 		assertEquals("text/b - test3", r);
 
-		client.setAccept("text/json");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/json").getResponseAsString();
 		assertEquals("\"test3\"", r);
 	}
 
@@ -119,16 +101,13 @@ public class SerializersTest extends RestTestcase {
 	public void testSerializerWithDifferentMediaTypes() throws Exception {
 		String url = URL + "/testSerializerWithDifferentMediaTypes";
 
-		client.setAccept("text/a");
-		String r = client.doGet(url).getResponseAsString();
+		String r = client.doGet(url).accept("text/a").getResponseAsString();
 		assertEquals("text/d - test4", r);
 
-		client.setAccept("text/d");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/d").getResponseAsString();
 		assertEquals("text/d - test4", r);
 
-		client.setAccept("text/json");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/json").getResponseAsString();
 		assertEquals("\"test4\"", r);
 	}
 
@@ -140,8 +119,7 @@ public class SerializersTest extends RestTestcase {
 		String url = URL + "/test406";
 
 		try {
-			client.setAccept("text/bad");
-			client.doGet(url + "?noTrace=true").getResponseAsString();
+			client.doGet(url + "?noTrace=true").accept("text/bad").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/StaticFilesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/StaticFilesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/StaticFilesTest.java
index 96e31f8..42c4c9b 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/StaticFilesTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/StaticFilesTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,7 +26,7 @@ public class StaticFilesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testXdocs() throws Exception {
-		RestClient client = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String r;
 		String url = URL + "/xdocs";
 
@@ -50,7 +49,5 @@ public class StaticFilesTest extends RestTestcase {
 		} catch (RestCallException e) {
 			assertEquals(404, e.getResponseCode());
 		}
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
index 84df9ec..25a740d 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
@@ -13,18 +13,32 @@
 package org.apache.juneau.rest.test;
 
 import java.net.*;
+import java.security.*;
 import java.util.*;
 
+import javax.net.ssl.*;
+
+import org.apache.http.conn.ssl.*;
+import org.apache.http.impl.client.*;
 import org.apache.juneau.microservice.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.plaintext.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.serializer.*;
 
 /**
  * Utility class for starting up the tests microservice.
  * @author james.bognar
  */
 public class TestMicroservice {
+
 	static RestMicroservice microservice;
 	static URI microserviceURI;
 
+	// Reusable HTTP clients that get created and shut down with the microservice.
+	public static RestClient DEFAULT_CLIENT;
+	public static RestClient DEFAULT_CLIENT_PLAINTEXT;
+
 	/**
 	 * Starts the microservice.
 	 * @return <jk>true</jk> if the service started, <jk>false</jk> if it's already started.
@@ -41,6 +55,8 @@ public class TestMicroservice {
 					"Test-Entry: test-value"
 				);
 			microserviceURI = microservice.start().getURI();
+			DEFAULT_CLIENT = client().build();
+			DEFAULT_CLIENT_PLAINTEXT = client(PlainTextSerializer.class, PlainTextParser.class).build();
 			return true;
 		} catch (Throwable e) {
 			System.err.println(e); // NOT DEBUG
@@ -65,8 +81,55 @@ public class TestMicroservice {
 		try {
 			microservice.stop();
 			microservice = null;
+			DEFAULT_CLIENT.closeQuietly();
+			DEFAULT_CLIENT_PLAINTEXT.closeQuietly();
+
 		} catch (Exception e) {
 			System.err.println(e); // NOT DEBUG
 		}
 	}
+
+	/**
+	 * Create a new HTTP client.
+	 */
+	public static RestClientBuilder client() {
+		try {
+			return new RestClientBuilder()
+				.rootUrl(microserviceURI)
+			//	.httpClient(createHttpClient(), true)
+			;
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Create a new HTTP client using the specified serializer and parser.
+	 */
+	public static RestClientBuilder client(Serializer s, Parser p) {
+		return client().serializer(s).parser(p);
+	}
+
+	/**
+	 * Create a new HTTP client using the specified serializer and parser.
+	 */
+	public static RestClientBuilder client(Class<? extends Serializer> s, Class<? extends Parser> p) {
+		return client().serializer(s).parser(p);
+	}
+
+	// TODO - Why is this needed?
+	static SSLConnectionSocketFactory getSSLSocketFactory() throws Exception {
+		SSLContext sslContext = SSLContext.getInstance("SSL");
+		TrustManager tm = new SimpleX509TrustManager(true);
+		sslContext.init(null, new TrustManager[]{tm}, new SecureRandom());
+		return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
+	}
+
+	public static CloseableHttpClient createHttpClient() {
+		try {
+			return HttpClients.custom().setSSLSocketFactory(getSSLSocketFactory()).setRedirectStrategy(new LaxRedirectStrategy()).build();
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestRestClient.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestRestClient.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestRestClient.java
deleted file mode 100644
index 05c491c..0000000
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestRestClient.java
+++ /dev/null
@@ -1,69 +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.test;
-
-import java.security.*;
-
-import javax.net.ssl.*;
-
-import org.apache.http.conn.ssl.*;
-import org.apache.http.impl.client.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * REST client with lenient SSL support and lax redirection strategy.
- */
-class TestRestClient extends RestClient {
-
-	public TestRestClient(Class<? extends Serializer> s, Class<? extends Parser> p) throws InstantiationException {
-		super(s,p);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public TestRestClient(Serializer s, Parser p) {
-		super(s,p);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public TestRestClient() {
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public TestRestClient(CloseableHttpClient c) {
-		super(c);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public static SSLConnectionSocketFactory getSSLSocketFactory() throws Exception {
-		SSLContext sslContext = SSLContext.getInstance("SSL");
-		TrustManager tm = new SimpleX509TrustManager(true);
-		sslContext.init(null, new TrustManager[]{tm}, new SecureRandom());
-		return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
-	}
-
-	@Override /* RestClient */
-	protected CloseableHttpClient createHttpClient() throws Exception {
-		try {
-			return HttpClients.custom().setSSLSocketFactory(getSSLSocketFactory()).setRedirectStrategy(new LaxRedirectStrategy()).build();
-		} catch (KeyStoreException e) {
-			throw new RuntimeException(e);
-		} catch (NoSuchAlgorithmException e) {
-			throw new RuntimeException(e);
-		} catch (Throwable e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestUtils.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestUtils.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestUtils.java
index 164a04e..22d84e0 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestUtils.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TestUtils.java
@@ -24,8 +24,10 @@ import junit.framework.*;
 
 public class TestUtils {
 
-	private static JsonSerializer js2 = new JsonSerializer.Simple()
-		.addPojoSwaps(IteratorSwap.class, EnumerationSwap.class);
+	private static JsonSerializer js2 = new JsonSerializerBuilder()
+		.simple()
+		.pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+		.build();
 
 	/**
 	 * Assert that the object equals the specified string after running it through JsonSerializer.DEFAULT_LAX.toString().

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TransformsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TransformsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TransformsTest.java
index d758fd8..3d405c4 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TransformsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/TransformsTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -28,7 +27,7 @@ public class TransformsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testClassTransformOverridesParentClassTransform() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 		String url = URL + "/testClassTransformOverridesParentClassTransform";
 
@@ -40,8 +39,6 @@ public class TransformsTest extends RestTestcase {
 
 		r = client.doPut(url + "/A2-2", "").getResponse(String.class);
 		assertEquals("A2-2", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -50,7 +47,7 @@ public class TransformsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testMethodTransformOverridesClassTransform() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 		String url = URL + "/testMethodTransformOverridesClassTransform";
 
@@ -62,7 +59,5 @@ public class TransformsTest extends RestTestcase {
 
 		r = client.doPut(url + "/A3-2", "").getResponse(String.class);
 		assertEquals("A3-2", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrisTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrisTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrisTest.java
index 57b929c..9917e3c 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrisTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrisTest.java
@@ -15,7 +15,6 @@ package org.apache.juneau.rest.test;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -33,7 +32,7 @@ public class UrisTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testRoot() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		ObjectMap r;
 
 		//--------------------------------------------------------------------------------
@@ -304,8 +303,6 @@ public class UrisTest extends RestTestcase {
 		// Always the same
 		assertTrue(r.getString("testURL2").endsWith(port + "/testURL"));
 		assertEquals("http://testURL", r.getString("testURL3"));
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -313,7 +310,7 @@ public class UrisTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testChild() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		ObjectMap r;
 
 		//--------------------------------------------------------------------------------
@@ -603,8 +600,6 @@ public class UrisTest extends RestTestcase {
 		// Always the same
 		assertTrue(r.getString("testURL2").endsWith(port + "/testURL"));
 		assertEquals("http://testURL", r.getString("testURL3"));
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -612,7 +607,7 @@ public class UrisTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testGrandChild() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		ObjectMap r;
 
 		//--------------------------------------------------------------------------------
@@ -902,15 +897,5 @@ public class UrisTest extends RestTestcase {
 		// Always the same
 		assertTrue(r.getString("testURL2").endsWith(port + "/testURL"));
 		assertEquals("http://testURL", r.getString("testURL3"));
-
-		client.closeQuietly();
 	}
-//
-//	private static int getPort(String url) {
-//		Pattern p = Pattern.compile("\\:(\\d{2,5})");
-//		Matcher m = p.matcher(url);
-//		if (m.find())
-//			return Integer.parseInt(m.group(1));
-//		return -1;
-//	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlContentTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlContentTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlContentTest.java
index 4ecee25..0f03f94 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlContentTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlContentTest.java
@@ -20,17 +20,8 @@ import org.junit.*;
 public class UrlContentTest extends RestTestcase {
 
 	private static String URL = "/testUrlContent";
-	private static RestClient client;
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 
-	@BeforeClass
-	public static void beforeClass() {
-		client = new TestRestClient().setHeader("Accept", "text/plain");
-	}
-
-	@AfterClass
-	public static void afterClass() {
-		client.closeQuietly();
-	}
 
 	//====================================================================================================
 	// Test URL &Body parameter containing a String

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlPathPatternTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlPathPatternTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlPathPatternTest.java
index c05bc2e..5e19738 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlPathPatternTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/UrlPathPatternTest.java
@@ -20,7 +20,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.rest.*;
 import org.junit.*;
 
-public class UrlPathPatternTest extends RestTestcase {
+public class UrlPathPatternTest {
 	@Test
 	public void testComparison() throws Exception {
 		List<UrlPathPattern> l = new LinkedList<UrlPathPattern>();
@@ -35,6 +35,6 @@ public class UrlPathPatternTest extends RestTestcase {
 		l.add(new UrlPathPattern("/foo/{id}/bar/*"));
 
 		Collections.sort(l);
-		assertEquals("[{vars:[],patternString:'/foo/bar'},{vars:[],patternString:'/foo/bar/*'},{vars:['id'],patternString:'/foo/{id}/bar'},{vars:['id'],patternString:'/foo/{id}/bar/*'},{vars:['id'],patternString:'/foo/{id}'},{vars:['id'],patternString:'/foo/{id}/*'},{vars:[],patternString:'/foo'},{vars:[],patternString:'/foo/*'}]", JsonSerializer.DEFAULT_LAX.serialize(l));
+		assertEquals("[{patternString:'/foo/bar',vars:[]},{patternString:'/foo/bar/*',vars:[]},{patternString:'/foo/{id}/bar',vars:['id']},{patternString:'/foo/{id}/bar/*',vars:['id']},{patternString:'/foo/{id}',vars:['id']},{patternString:'/foo/{id}/*',vars:['id']},{patternString:'/foo',vars:[]},{patternString:'/foo/*',vars:[]}]", JsonSerializer.DEFAULT_LAX.builder().sortProperties(true).build().serialize(l));
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
----------------------------------------------------------------------
diff --git a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
index 113d9da..0e907c3 100644
--- a/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
+++ b/juneau-rest/src/main/java/org/apache/juneau/rest/RestRequest.java
@@ -36,6 +36,7 @@ import org.apache.juneau.parser.*;
 import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.svl.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.utils.*;
 
@@ -113,8 +114,11 @@ public final class RestRequest extends HttpServletRequestWrapper {
 
 			method = _method;
 
-			if (servlet.context.allowBodyParam)
+			if (servlet.context.allowBodyParam) {
 				body = getQueryParameter("body");
+				if (body != null)
+					setHeader("Content-Type", UonSerializer.DEFAULT.getResponseContentType());
+			}
 
 			defaultServletHeaders = servlet.getDefaultRequestHeaders();
 
@@ -192,10 +196,10 @@ public final class RestRequest extends HttpServletRequestWrapper {
 	 * @param name The header name.
 	 * @param value The header value.
 	 */
-	public void setHeader(String name, String value) {
+	public void setHeader(String name, Object value) {
 		if (overriddenHeaders == null)
 			overriddenHeaders = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
-		overriddenHeaders.put(name, value);
+		overriddenHeaders.put(name, StringUtils.toString(value));
 	}
 
 


[17/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
new file mode 100644
index 0000000..64f9253
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroupBuilder.java
@@ -0,0 +1,864 @@
+// ***************************************************************************************************************************
+// * 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.parser;
+
+import static org.apache.juneau.BeanContext.*;
+import static org.apache.juneau.parser.ParserContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Builder class for creating instances of {@link ParserGroup}.
+ */
+public class ParserGroupBuilder {
+
+	private final List<Object> parsers;
+	private final PropertyStore propertyStore;
+
+	/**
+	 * Create an empty parser group builder.
+	 */
+	public ParserGroupBuilder() {
+		this.parsers = new ArrayList<Object>();
+		this.propertyStore = PropertyStore.create();
+	}
+
+	/**
+	 * Clone an existing parser group builder.
+	 * @param copyFrom The parser group that we're copying settings and parsers from.
+	 */
+	public ParserGroupBuilder(ParserGroup copyFrom) {
+		this.parsers = new ArrayList<Object>(Arrays.asList(copyFrom.parsers));
+		this.propertyStore = copyFrom.createPropertyStore();
+	}
+
+	/**
+	 * Registers the specified parsers with this group.
+	 *
+	 * @param p The parsers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public ParserGroupBuilder append(Class<?>...p) {
+		parsers.addAll(Arrays.asList(p));
+		return this;
+	}
+
+	/**
+	 * Registers the specified parsers with this group.
+	 *
+	 * @param p The parsers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public ParserGroupBuilder append(Parser...p) {
+		parsers.addAll(Arrays.asList(p));
+		return this;
+	}
+
+	/**
+	 * Registers the specified parsers with this group.
+	 *
+	 * @param p The parsers to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public ParserGroupBuilder append(List<Parser> p) {
+		parsers.addAll(p);
+		return this;
+	}
+
+	/**
+	 * Creates a new {@link ParserGroup} object using a snapshot of the settings defined in this builder.
+	 * <p>
+	 * This method can be called multiple times to produce multiple parser groups.
+	 *
+	 * @return A new {@link ParserGroup} object.
+	 */
+	@SuppressWarnings("unchecked")
+	public ParserGroup build() {
+		List<Parser> l = new ArrayList<Parser>();
+		for (Object p : parsers) {
+			Class<? extends Parser> c = null;
+			PropertyStore ps = propertyStore;
+			if (p instanceof Class) {
+				c = (Class<? extends Parser>)p;
+			} else {
+				// Note that if we added a serializer instance, we want a new instance with this builder's properties
+				// on top of the previous serializer's properties.
+				Parser p2 = (Parser)p;
+				ps = p2.createPropertyStore().copyFrom(propertyStore);
+				c = p2.getClass();
+			}
+			try {
+				l.add(c.getConstructor(PropertyStore.class).newInstance(ps));
+			} catch (Exception e) {
+				throw new RuntimeException("Could not instantiate parser " + c.getName(), e);
+			}
+		}
+		return new ParserGroup(propertyStore, l.toArray(new Parser[l.size()]));
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Sets a property on all parsers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The property value.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 */
+	public ParserGroupBuilder property(String name, Object value) {
+		propertyStore.setProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Sets a set of properties on all parsers in this group.
+	 *
+	 * @param properties The properties to set on this class.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperties(java.util.Map)
+	 */
+	public ParserGroupBuilder properties(ObjectMap properties) {
+		propertyStore.setProperties(properties);
+		return this;
+	}
+
+	/**
+	 * Adds a value to a SET property on all parsers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The new value to add to the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public ParserGroupBuilder addToProperty(String name, Object value) {
+		propertyStore.addToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property on all parsers in this group.
+	 *
+	 * @param name The property name.
+	 * @param key The property value map key.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public ParserGroupBuilder putToProperty(String name, Object key, Object value) {
+		propertyStore.putToProperty(name, key, value);
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property on all parsers in this group.
+	 *
+	 * @param name The property value.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public ParserGroupBuilder putToProperty(String name, Object value) {
+		propertyStore.putToProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Removes a value from a SET property on all parsers in this group.
+	 *
+	 * @param name The property name.
+	 * @param value The property value in the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public ParserGroupBuilder removeFromProperty(String name, Object value) {
+		propertyStore.removeFromProperty(name, value);
+		return this;
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_trimStrings} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_trimStrings
+	 */
+	public ParserGroupBuilder trimStrings(boolean value) {
+		return property(PARSER_trimStrings, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_strict} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_strict
+	 */
+	public ParserGroupBuilder strict(boolean value) {
+		return property(PARSER_strict, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_inputStreamCharset} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_inputStreamCharset
+	 */
+	public ParserGroupBuilder inputStreamCharset(String value) {
+		return property(PARSER_inputStreamCharset, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_fileCharset} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_fileCharset
+	 */
+	public ParserGroupBuilder fileCharset(String value) {
+		return property(PARSER_fileCharset, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireDefaultConstructor} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
+	 */
+	public ParserGroupBuilder beansRequireDefaultConstructor(boolean value) {
+		return property(BEAN_beansRequireDefaultConstructor, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSerializable} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSerializable
+	 */
+	public ParserGroupBuilder beansRequireSerializable(boolean value) {
+		return property(BEAN_beansRequireSerializable, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSettersForGetters} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSettersForGetters
+	 */
+	public ParserGroupBuilder beansRequireSettersForGetters(boolean value) {
+		return property(BEAN_beansRequireSettersForGetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beansRequireSomeProperties} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beansRequireSomeProperties
+	 */
+	public ParserGroupBuilder beansRequireSomeProperties(boolean value) {
+		return property(BEAN_beansRequireSomeProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanMapPutReturnsOldValue} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
+	 */
+	public ParserGroupBuilder beanMapPutReturnsOldValue(boolean value) {
+		return property(BEAN_beanMapPutReturnsOldValue, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanConstructorVisibility} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanConstructorVisibility
+	 */
+	public ParserGroupBuilder beanConstructorVisibility(Visibility value) {
+		return property(BEAN_beanConstructorVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanClassVisibility} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanClassVisibility
+	 */
+	public ParserGroupBuilder beanClassVisibility(Visibility value) {
+		return property(BEAN_beanClassVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFieldVisibility} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFieldVisibility
+	 */
+	public ParserGroupBuilder beanFieldVisibility(Visibility value) {
+		return property(BEAN_beanFieldVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_methodVisibility} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_methodVisibility
+	 */
+	public ParserGroupBuilder methodVisibility(Visibility value) {
+		return property(BEAN_methodVisibility, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_useJavaBeanIntrospector} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useJavaBeanIntrospector
+	 */
+	public ParserGroupBuilder useJavaBeanIntrospector(boolean value) {
+		return property(BEAN_useJavaBeanIntrospector, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_useInterfaceProxies} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_useInterfaceProxies
+	 */
+	public ParserGroupBuilder useInterfaceProxies(boolean value) {
+		return property(BEAN_useInterfaceProxies, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreUnknownBeanProperties} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
+	 */
+	public ParserGroupBuilder ignoreUnknownBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownBeanProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreUnknownNullBeanProperties} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
+	 */
+	public ParserGroupBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		return property(BEAN_ignoreUnknownNullBeanProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignorePropertiesWithoutSetters} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
+	 */
+	public ParserGroupBuilder ignorePropertiesWithoutSetters(boolean value) {
+		return property(BEAN_ignorePropertiesWithoutSetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreInvocationExceptionsOnGetters} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
+	 */
+	public ParserGroupBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnGetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_ignoreInvocationExceptionsOnSetters} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
+	 */
+	public ParserGroupBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		return property(BEAN_ignoreInvocationExceptionsOnSetters, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_sortProperties} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_sortProperties
+	 */
+	public ParserGroupBuilder sortProperties(boolean value) {
+		return property(BEAN_sortProperties, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public ParserGroupBuilder notBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_add} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public ParserGroupBuilder notBeanPackages(Collection<String> value) {
+		return property(BEAN_notBeanPackages_add, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public ParserGroupBuilder setNotBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 */
+	public ParserGroupBuilder setNotBeanPackages(Collection<String> values) {
+		return property(BEAN_notBeanPackages, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public ParserGroupBuilder removeNotBeanPackages(String...values) {
+		return property(BEAN_notBeanPackages_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanPackages_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages
+	 * @see BeanContext#BEAN_notBeanPackages_remove
+	 */
+	public ParserGroupBuilder removeNotBeanPackages(Collection<String> values) {
+		return property(BEAN_notBeanPackages_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_add
+	 */
+	public ParserGroupBuilder notBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanPackages_add
+	 */
+	public ParserGroupBuilder notBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public ParserGroupBuilder setNotBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public ParserGroupBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public ParserGroupBuilder removeNotBeanClasses(Class<?>...values) {
+		return property(BEAN_notBeanClasses_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_notBeanClasses_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_notBeanClasses_remove
+	 */
+	public ParserGroupBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		return property(BEAN_notBeanClasses_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public ParserGroupBuilder beanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_add
+	 */
+	public ParserGroupBuilder beanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public ParserGroupBuilder setBeanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public ParserGroupBuilder setBeanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public ParserGroupBuilder removeBeanFilters(Class<?>...values) {
+		return property(BEAN_beanFilters_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanFilters_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanFilters_remove
+	 */
+	public ParserGroupBuilder removeBeanFilters(Collection<Class<?>> values) {
+		return property(BEAN_beanFilters_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public ParserGroupBuilder pojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_add
+	 */
+	public ParserGroupBuilder pojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public ParserGroupBuilder setPojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public ParserGroupBuilder setPojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public ParserGroupBuilder removePojoSwaps(Class<?>...values) {
+		return property(BEAN_pojoSwaps_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_pojoSwaps_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 */
+	public ParserGroupBuilder removePojoSwaps(Collection<Class<?>> values) {
+		return property(BEAN_pojoSwaps_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_implClasses} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 */
+	public ParserGroupBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		return property(BEAN_implClasses, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_implClasses_put} property on all parsers in this group.
+	 *
+	 * @param interfaceClass The interface class.
+	 * @param implClass The implementation class.
+	 * @param <T> The class type of the interface.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_implClasses
+	 * @see BeanContext#BEAN_implClasses_put
+	 */
+	public <T> ParserGroupBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		return putToProperty(BEAN_implClasses, interfaceClass, implClass);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_add} property on all parsers in this group.
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public ParserGroupBuilder beanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_add} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_add
+	 */
+	public ParserGroupBuilder beanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary_add, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public ParserGroupBuilder setBeanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary} property on all parsers in this group.
+	 *
+	 * @param values The values to add to this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public ParserGroupBuilder setBeanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public ParserGroupBuilder removeFromBeanDictionary(Class<?>...values) {
+		return property(BEAN_beanDictionary_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanDictionary_remove} property on all parsers in this group.
+	 *
+	 * @param values The values to remove from this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanDictionary_remove
+	 */
+	public ParserGroupBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		return property(BEAN_beanDictionary_remove, values);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_beanTypePropertyName} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_beanTypePropertyName
+	 */
+	public ParserGroupBuilder beanTypePropertyName(String value) {
+		return property(BEAN_beanTypePropertyName, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_defaultParser} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_defaultParser
+	 */
+	public ParserGroupBuilder defaultParser(Class<?> value) {
+		return property(BEAN_defaultParser, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_locale} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_locale
+	 */
+	public ParserGroupBuilder locale(Locale value) {
+		return property(BEAN_locale, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_timeZone} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_timeZone
+	 */
+	public ParserGroupBuilder timeZone(TimeZone value) {
+		return property(BEAN_timeZone, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_mediaType} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_mediaType
+	 */
+	public ParserGroupBuilder mediaType(MediaType value) {
+		return property(BEAN_mediaType, value);
+	}
+
+	/**
+	 * Sets the {@link BeanContext#BEAN_debug} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see BeanContext#BEAN_debug
+	 */
+	public ParserGroupBuilder debug(boolean value) {
+		return property(BEAN_debug, value);
+	}
+
+	/**
+	 * Specifies the classloader to use when resolving classes from strings for all parsers in this group.
+	 * <p>
+	 * Can be used for resolving class names when the classes being created are in a different
+	 * 	classloader from the Juneau code.
+	 * <p>
+	 * If <jk>null</jk>, the system classloader will be used to resolve classes.
+	 *
+	 * @param classLoader The new classloader.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setClassLoader(ClassLoader)
+	 */
+	public ParserGroupBuilder classLoader(ClassLoader classLoader) {
+		propertyStore.setClassLoader(classLoader);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
index e675f5c..9c01704 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserListener.java
@@ -19,7 +19,7 @@ import org.apache.juneau.*;
  * <p>
  * Listeners can be registered with parsers through the {@link Parser#addListener(ParserListener)} method.
  * <p>
- * It should be noted that listeners are not automatically copied over to new parsers when a parser is cloned.
+ * It should be noted that listeners are not automatically copied over to new parsers when a parser is cloned using the {@link Parser#builder()} method.
  */
 public class ParserListener {
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ReaderParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ReaderParser.java b/juneau-core/src/main/java/org/apache/juneau/parser/ReaderParser.java
index 044038d..12d8677 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ReaderParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ReaderParser.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.parser;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 
 /**
@@ -33,6 +34,14 @@ import org.apache.juneau.annotation.*;
  */
 public abstract class ReaderParser extends Parser {
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	protected ReaderParser(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
 	@Override /* Parser */
 	public boolean isReaderParser() {
 		return true;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/package.html b/juneau-core/src/main/java/org/apache/juneau/parser/package.html
index 3c38ac3..ea6b20d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/package.html
@@ -123,7 +123,7 @@
 	}
 	</p>
 	<p>
-		Parsers that take advantage of the entire {@link org.apache.juneau.CoreApi} interface to be able to parse arbitrary beans and POJOs is
+		Parsers that take advantage of the entire {@link org.apache.juneau.CoreObject} interface to be able to parse arbitrary beans and POJOs is
 			considerably more complex and outside the scope of this document.  
 		If developing such a parser, the best course of action would be to replicate what occurs in the {@link org.apache.juneau.json.JsonParser} class.
 	</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
index 86340c7..1006307 100644
--- a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParser.java
@@ -44,6 +44,24 @@ import org.apache.juneau.transform.*;
 @Consumes("text/plain")
 public final class PlainTextParser extends ReaderParser {
 
+	/** Default parser, all default settings.*/
+	public static final PlainTextParser DEFAULT = new PlainTextParser(PropertyStore.create());
+
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public PlainTextParser(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public PlainTextParserBuilder builder() {
+		return new PlainTextParserBuilder(propertyStore);
+	}
+
+
 	//--------------------------------------------------------------------------------
 	// Overridden methods
 	//--------------------------------------------------------------------------------
@@ -52,13 +70,4 @@ public final class PlainTextParser extends ReaderParser {
 	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
 		return session.convertToType(IOUtils.read(session.getReader()), type);
 	}
-
-	@Override /* Lockable */
-	public PlainTextParser clone() {
-		try {
-			return (PlainTextParser)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen.
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
new file mode 100644
index 0000000..febd91f
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextParserBuilder.java
@@ -0,0 +1,457 @@
+// ***************************************************************************************************************************
+// * 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.plaintext;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building instances of plain-text parsers.
+ */
+public class PlainTextParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public PlainTextParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public PlainTextParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParser build() {
+		return new PlainTextParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* ParserBuilder */
+	public PlainTextParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public PlainTextParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public PlainTextParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public PlainTextParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public PlainTextParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> PlainTextParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
index 0cc9dcf..b49380f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializer.java
@@ -43,6 +43,24 @@ import org.apache.juneau.transform.*;
 @Produces("text/plain")
 public final class PlainTextSerializer extends WriterSerializer {
 
+	/** Default serializer, all default settings.*/
+	public static final PlainTextSerializer DEFAULT = new PlainTextSerializer(PropertyStore.create());
+
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public PlainTextSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public PlainTextSerializerBuilder builder() {
+		return new PlainTextSerializerBuilder(propertyStore);
+	}
+
+
 	//--------------------------------------------------------------------------------
 	// Overridden methods
 	//--------------------------------------------------------------------------------
@@ -51,13 +69,4 @@ public final class PlainTextSerializer extends WriterSerializer {
 	protected void doSerialize(SerializerSession session, Object o) throws Exception {
 		session.getWriter().write(o == null ? "null" : session.convertToType(o, String.class));
 	}
-
-	@Override /* Serializer */
-	public PlainTextSerializer clone() {
-		try {
-			return (PlainTextSerializer)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen.
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
new file mode 100644
index 0000000..8ab1255
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/plaintext/PlainTextSerializerBuilder.java
@@ -0,0 +1,528 @@
+// ***************************************************************************************************************************
+// * 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.plaintext;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of plain-text serializers.
+ */
+public class PlainTextSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public PlainTextSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public PlainTextSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializer build() {
+		return new PlainTextSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public PlainTextSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> PlainTextSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public PlainTextSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
index 1c2a2d2..bbfcfb2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/OutputStreamSerializer.java
@@ -14,6 +14,7 @@ package org.apache.juneau.serializer;
 
 import java.io.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -37,7 +38,15 @@ import org.apache.juneau.internal.*;
  */
 public abstract class OutputStreamSerializer extends Serializer {
 
-	@Override /* Serializer */
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	protected OutputStreamSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+		@Override /* Serializer */
 	public boolean isWriterSerializer() {
 		return false;
 	}


[34/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
Add builder classes for all serializers and parsers.

Project: http://git-wip-us.apache.org/repos/asf/incubator-juneau/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-juneau/commit/95e832e1
Tree: http://git-wip-us.apache.org/repos/asf/incubator-juneau/tree/95e832e1
Diff: http://git-wip-us.apache.org/repos/asf/incubator-juneau/diff/95e832e1

Branch: refs/heads/master
Commit: 95e832e1a5f68a0c55c8dc1dd900c1d25d225a84
Parents: d59d737
Author: JamesBognar <ja...@apache.org>
Authored: Fri Mar 10 08:50:51 2017 -0800
Committer: JamesBognar <ja...@apache.org>
Committed: Fri Mar 10 08:50:51 2017 -0800

----------------------------------------------------------------------
 .../apache/juneau/jena/RdfCommonContext.java    |    4 +-
 .../java/org/apache/juneau/jena/RdfParser.java  |  747 +------
 .../apache/juneau/jena/RdfParserBuilder.java    |  728 +++++++
 .../apache/juneau/jena/RdfParserContext.java    |   26 +-
 .../org/apache/juneau/jena/RdfSerializer.java   |  919 +--------
 .../juneau/jena/RdfSerializerBuilder.java       |  890 +++++++++
 .../juneau/jena/RdfSerializerContext.java       |   36 +-
 .../juneau/jena/RdfSerializerSession.java       |    2 +-
 .../java/org/apache/juneau/jena/package.html    |   52 +-
 .../java/org/apache/juneau/BeanConfigTest.java  |  162 +-
 .../java/org/apache/juneau/BeanFilterTest.java  |    4 +-
 .../java/org/apache/juneau/BeanMapTest.java     |   27 +-
 .../java/org/apache/juneau/ClassMetaTest.java   |   14 +-
 .../test/java/org/apache/juneau/ComboTest.java  |   73 +-
 .../org/apache/juneau/ContextFactoryTest.java   |  823 --------
 .../org/apache/juneau/DataConversionTest.java   |    2 +-
 .../org/apache/juneau/IgnoredClassesTest.java   |   30 +-
 .../java/org/apache/juneau/MediaRangeTest.java  |   13 +-
 .../java/org/apache/juneau/PojoSwapTest.java    |    4 +-
 .../org/apache/juneau/PropertyStoreTest.java    |  823 ++++++++
 .../test/java/org/apache/juneau/TestUtils.java  |   40 +-
 .../java/org/apache/juneau/VisibilityTest.java  |  120 +-
 .../org/apache/juneau/XmlValidatorParser.java   |    7 +-
 .../juneau/XmlValidatorParserBuilder.java       |   26 +
 .../a/rttests/RoundTripAddClassAttrsTest.java   |   43 +-
 .../a/rttests/RoundTripBeanInheritanceTest.java |    2 +-
 .../juneau/a/rttests/RoundTripBeanMapsTest.java |   66 +-
 .../juneau/a/rttests/RoundTripClassesTest.java  |    2 +-
 .../juneau/a/rttests/RoundTripDTOsTest.java     |    2 +-
 .../juneau/a/rttests/RoundTripEnumTest.java     |    4 +-
 .../juneau/a/rttests/RoundTripGenericsTest.java |    2 +-
 .../a/rttests/RoundTripLargeObjectsTest.java    |   21 +-
 .../juneau/a/rttests/RoundTripMapsTest.java     |   13 +-
 .../RoundTripNumericConstructorsTest.java       |    3 +-
 .../rttests/RoundTripObjectsAsStringsTest.java  |    2 +-
 .../RoundTripObjectsWithSpecialMethodsTest.java |    2 +-
 .../RoundTripPrimitiveObjectBeansTest.java      |    2 +-
 .../a/rttests/RoundTripPrimitivesBeansTest.java |    2 +-
 .../a/rttests/RoundTripReadOnlyBeansTest.java   |    2 +-
 .../a/rttests/RoundTripSimpleObjectsTest.java   |    2 +-
 .../apache/juneau/a/rttests/RoundTripTest.java  |  119 +-
 .../a/rttests/RoundTripToObjectMapsTest.java    |    2 +-
 .../a/rttests/RoundTripTransformBeansTest.java  |   21 +-
 .../a/rttests/RoundTripTrimStringsTest.java     |    6 +-
 .../java/org/apache/juneau/csv/CsvTest.java     |    2 +-
 .../org/apache/juneau/dto/atom/AtomTest.java    |    8 +-
 .../apache/juneau/dto/cognos/CognosXmlTest.java |   13 +-
 .../apache/juneau/dto/html5/Html5ComboTest.java |    2 +-
 .../dto/html5/Html5TemplateComboTest.java       |    5 +-
 .../juneau/dto/jsonschema/JsonSchemaTest.java   |    4 +-
 .../org/apache/juneau/html/BasicHtmlTest.java   |    5 +-
 .../apache/juneau/html/CommonParserTest.java    |   10 +-
 .../java/org/apache/juneau/html/CommonTest.java |  118 +-
 .../java/org/apache/juneau/html/HtmlTest.java   |   46 +-
 .../org/apache/juneau/ini/ConfigFileTest.java   |    4 +-
 .../apache/juneau/jena/CommonParserTest.java    |   32 +-
 .../java/org/apache/juneau/jena/CommonTest.java |  131 +-
 .../org/apache/juneau/jena/CommonXmlTest.java   |   22 +-
 .../org/apache/juneau/jena/RdfParserTest.java   |    9 +-
 .../java/org/apache/juneau/jena/RdfTest.java    |   66 +-
 .../apache/juneau/json/CommonParserTest.java    |   10 +-
 .../java/org/apache/juneau/json/CommonTest.java |  113 +-
 .../juneau/json/JsonParserEdgeCasesTest.java    |   12 +-
 .../java/org/apache/juneau/json/JsonTest.java   |   12 +-
 .../org/apache/juneau/svl/vars/IfVarTest.java   |    4 +-
 .../apache/juneau/svl/vars/SwitchVarTest.java   |    4 +-
 .../juneau/transforms/BeanFilterTest.java       |    8 +-
 .../apache/juneau/transforms/BeanMapTest.java   |    6 +-
 .../ByteArrayBase64SwapComboTest.java           |   25 +-
 .../transforms/CalendarSwapComboTest.java       |   30 +-
 .../juneau/transforms/CalendarSwapTest.java     |   16 +-
 .../juneau/transforms/DateSwapComboTest.java    |   28 +-
 .../apache/juneau/transforms/DateSwapTest.java  |   12 +-
 .../juneau/transforms/EnumerationSwapTest.java  |    2 +-
 .../juneau/transforms/IteratorSwapTest.java     |    2 +-
 .../juneau/transforms/LocalizedDatesTest.java   |   10 +-
 .../juneau/transforms/ReaderFilterTest.java     |    9 +-
 .../urlencoding/CommonParser_UonTest.java       |   13 +-
 .../CommonParser_UrlEncodingTest.java           |   15 +-
 .../juneau/urlencoding/Common_UonTest.java      |  110 +-
 .../urlencoding/Common_UrlEncodingTest.java     |  109 +-
 .../juneau/urlencoding/UonParserReaderTest.java |    1 +
 .../juneau/urlencoding/UonParserTest.java       |    1 +
 .../juneau/urlencoding/UonSerializerTest.java   |    1 +
 .../urlencoding/UrlEncodingParserTest.java      |    2 +-
 .../urlencoding/UrlEncodingSerializerTest.java  |    6 +-
 .../org/apache/juneau/utils/PojoQueryTest.java  |    4 +-
 .../org/apache/juneau/utils/PojoRestTest.java   |    8 +-
 .../apache/juneau/utils/StringUtilsTest.java    |    2 +-
 .../juneau/utils/StringVarResolverTest.java     |   58 +-
 .../org/apache/juneau/xml/CommonParserTest.java |    6 +-
 .../java/org/apache/juneau/xml/CommonTest.java  |  113 +-
 .../org/apache/juneau/xml/CommonXmlTest.java    |    2 +-
 .../org/apache/juneau/xml/XmlContentTest.java   |    4 +-
 .../org/apache/juneau/xml/XmlParserTest.java    |    2 +-
 .../java/org/apache/juneau/xml/XmlTest.java     |  340 ++--
 juneau-core/.gitignore                          |    1 +
 .../src/main/java/org/apache/juneau/.DS_Store   |  Bin 0 -> 6148 bytes
 .../java/org/apache/juneau/BeanContext.java     |   42 +-
 .../main/java/org/apache/juneau/BeanMap.java    |    4 +-
 .../main/java/org/apache/juneau/Context.java    |   10 +-
 .../java/org/apache/juneau/ContextFactory.java  | 1344 -------------
 .../main/java/org/apache/juneau/CoreApi.java    | 1552 ---------------
 .../main/java/org/apache/juneau/CoreObject.java |  114 ++
 .../org/apache/juneau/CoreObjectBuilder.java    | 1429 ++++++++++++++
 .../main/java/org/apache/juneau/Lockable.java   |   86 -
 .../java/org/apache/juneau/LockedException.java |   30 -
 .../main/java/org/apache/juneau/MediaRange.java |    1 -
 .../java/org/apache/juneau/PropertyStore.java   | 1384 +++++++++++++
 .../main/java/org/apache/juneau/Session.java    |    2 +-
 .../java/org/apache/juneau/annotation/Pojo.java |    4 +-
 .../java/org/apache/juneau/csv/CsvParser.java   |   60 +
 .../org/apache/juneau/csv/CsvParserBuilder.java |  456 +++++
 .../org/apache/juneau/csv/CsvParserContext.java |   53 +
 .../org/apache/juneau/csv/CsvParserSession.java |  111 ++
 .../org/apache/juneau/csv/CsvSerializer.java    |   33 +-
 .../apache/juneau/csv/CsvSerializerBuilder.java |  528 +++++
 .../apache/juneau/csv/CsvSerializerContext.java |   53 +
 .../apache/juneau/csv/CsvSerializerSession.java |   46 +
 .../java/org/apache/juneau/dto/atom/Common.java |    2 +-
 .../org/apache/juneau/dto/atom/CommonEntry.java |    2 +-
 .../java/org/apache/juneau/dto/atom/Entry.java  |    3 +-
 .../org/apache/juneau/dto/atom/Generator.java   |    2 +-
 .../java/org/apache/juneau/dto/atom/Icon.java   |    2 +-
 .../java/org/apache/juneau/dto/atom/Logo.java   |    2 +-
 .../java/org/apache/juneau/dto/atom/Person.java |    3 +-
 .../org/apache/juneau/dto/atom/package.html     |   16 +-
 .../juneau/dto/html5/HtmlElementVoid.java       |    3 +-
 .../apache/juneau/encoders/EncoderGroup.java    |   69 +-
 .../juneau/encoders/EncoderGroupBuilder.java    |  109 +
 .../apache/juneau/html/HtmlDocSerializer.java   |  528 +----
 .../juneau/html/HtmlDocSerializerContext.java   |   20 +-
 .../juneau/html/HtmlDocSerializerSession.java   |    2 +-
 .../java/org/apache/juneau/html/HtmlParser.java |  467 +----
 .../apache/juneau/html/HtmlParserBuilder.java   |  484 +++++
 .../apache/juneau/html/HtmlParserContext.java   |   14 +-
 .../juneau/html/HtmlSchemaDocSerializer.java    |   29 +-
 .../org/apache/juneau/html/HtmlSerializer.java  |  705 +------
 .../juneau/html/HtmlSerializerBuilder.java      |  706 +++++++
 .../juneau/html/HtmlSerializerContext.java      |   26 +-
 .../juneau/html/HtmlSerializerSession.java      |    2 +-
 .../juneau/html/HtmlStrippedDocSerializer.java  |    9 +
 .../org/apache/juneau/ini/ConfigFileImpl.java   |    9 +-
 .../apache/juneau/ini/ConfigFileWrapped.java    |    7 +-
 .../java/org/apache/juneau/ini/package.html     |    2 +-
 .../apache/juneau/internal/JuneauLogger.java    |   18 +-
 .../juneau/jso/JavaSerializedObjectParser.java  |   51 -
 .../jso/JavaSerializedObjectSerializer.java     |   52 -
 .../java/org/apache/juneau/jso/JsoParser.java   |   59 +
 .../org/apache/juneau/jso/JsoParserBuilder.java |  457 +++++
 .../org/apache/juneau/jso/JsoSerializer.java    |   61 +
 .../apache/juneau/jso/JsoSerializerBuilder.java |  529 +++++
 .../java/org/apache/juneau/json/JsonParser.java |  468 +----
 .../apache/juneau/json/JsonParserBuilder.java   |  457 +++++
 .../apache/juneau/json/JsonParserContext.java   |   14 +-
 .../apache/juneau/json/JsonParserSession.java   |    1 -
 .../juneau/json/JsonSchemaSerializer.java       |   42 +-
 .../json/JsonSchemaSerializerBuilder.java       |  545 +++++
 .../org/apache/juneau/json/JsonSerializer.java  |  654 +-----
 .../juneau/json/JsonSerializerBuilder.java      |  594 ++++++
 .../juneau/json/JsonSerializerContext.java      |   20 +-
 .../juneau/json/JsonSerializerSession.java      |    2 +-
 .../java/org/apache/juneau/json/package.html    |   10 +-
 .../apache/juneau/msgpack/MsgPackParser.java    |  444 +----
 .../juneau/msgpack/MsgPackParserBuilder.java    |  457 +++++
 .../juneau/msgpack/MsgPackParserContext.java    |   16 +-
 .../juneau/msgpack/MsgPackParserSession.java    |    1 -
 .../juneau/msgpack/MsgPackSerializer.java       |  509 +----
 .../msgpack/MsgPackSerializerBuilder.java       |  528 +++++
 .../msgpack/MsgPackSerializerContext.java       |   16 +-
 .../msgpack/MsgPackSerializerSession.java       |    3 +-
 .../main/java/org/apache/juneau/package.html    |    9 +-
 .../apache/juneau/parser/InputStreamParser.java |    9 +
 .../java/org/apache/juneau/parser/Parser.java   |  556 +-----
 .../org/apache/juneau/parser/ParserBuilder.java |  571 ++++++
 .../org/apache/juneau/parser/ParserContext.java |   14 +-
 .../org/apache/juneau/parser/ParserGroup.java   | 1139 +----------
 .../juneau/parser/ParserGroupBuilder.java       |  864 ++++++++
 .../apache/juneau/parser/ParserListener.java    |    2 +-
 .../org/apache/juneau/parser/ReaderParser.java  |    9 +
 .../java/org/apache/juneau/parser/package.html  |    2 +-
 .../juneau/plaintext/PlainTextParser.java       |   27 +-
 .../plaintext/PlainTextParserBuilder.java       |  457 +++++
 .../juneau/plaintext/PlainTextSerializer.java   |   27 +-
 .../plaintext/PlainTextSerializerBuilder.java   |  528 +++++
 .../serializer/OutputStreamSerializer.java      |   11 +-
 .../apache/juneau/serializer/Serializer.java    |  886 +--------
 .../juneau/serializer/SerializerBuilder.java    |  896 +++++++++
 .../juneau/serializer/SerializerContext.java    |   36 +-
 .../juneau/serializer/SerializerGroup.java      | 1310 +-----------
 .../serializer/SerializerGroupBuilder.java      |  983 +++++++++
 .../juneau/serializer/SerializerSession.java    |    2 +-
 .../juneau/serializer/WriterSerializer.java     |    8 +
 .../org/apache/juneau/serializer/package.html   |    2 +-
 .../apache/juneau/soap/SoapXmlSerializer.java   |    9 +
 .../juneau/soap/SoapXmlSerializerBuilder.java   |  590 ++++++
 .../main/java/org/apache/juneau/svl/MapVar.java |    1 +
 .../main/java/org/apache/juneau/svl/Var.java    |    2 +-
 .../java/org/apache/juneau/svl/VarResolver.java |   93 +-
 .../apache/juneau/svl/VarResolverBuilder.java   |  109 +
 .../apache/juneau/svl/VarResolverContext.java   |   81 +-
 .../apache/juneau/svl/VarResolverSession.java   |   26 +-
 .../java/org/apache/juneau/svl/package.html     |   10 +-
 .../transform/AnnotationBeanFilterBuilder.java  |   16 +-
 .../juneau/transform/BeanFilterBuilder.java     |   38 +-
 .../transform/InterfaceBeanFilterBuilder.java   |    4 +-
 .../org/apache/juneau/transform/PojoSwap.java   |    2 +-
 .../apache/juneau/transform/SurrogateSwap.java  |    6 +-
 .../org/apache/juneau/transform/package.html    |   46 +-
 .../java/org/apache/juneau/uon/UonParser.java   |  800 ++++++++
 .../org/apache/juneau/uon/UonParserBuilder.java |  495 +++++
 .../org/apache/juneau/uon/UonParserContext.java |   74 +
 .../org/apache/juneau/uon/UonParserSession.java |  118 ++
 .../java/org/apache/juneau/uon/UonReader.java   |  195 ++
 .../org/apache/juneau/uon/UonSerializer.java    |  386 ++++
 .../apache/juneau/uon/UonSerializerBuilder.java |  570 ++++++
 .../apache/juneau/uon/UonSerializerContext.java |  100 +
 .../apache/juneau/uon/UonSerializerSession.java |   88 +
 .../java/org/apache/juneau/uon/UonWriter.java   |  281 +++
 .../juneau/uon/doc-files/Example_HTML.png       |  Bin 0 -> 136001 bytes
 .../org/apache/juneau/uon/doc-files/rfc_uon.txt |  294 +++
 .../java/org/apache/juneau/uon/package.html     | 1339 +++++++++++++
 .../apache/juneau/urlencoding/UonParser.java    | 1191 -----------
 .../juneau/urlencoding/UonParserContext.java    |   73 -
 .../juneau/urlencoding/UonParserSession.java    |  118 --
 .../apache/juneau/urlencoding/UonReader.java    |  195 --
 .../juneau/urlencoding/UonSerializer.java       |  869 --------
 .../urlencoding/UonSerializerContext.java       |   99 -
 .../urlencoding/UonSerializerSession.java       |   88 -
 .../apache/juneau/urlencoding/UonWriter.java    |  281 ---
 .../juneau/urlencoding/UrlEncodingContext.java  |   25 +-
 .../juneau/urlencoding/UrlEncodingParser.java   |  500 +----
 .../urlencoding/UrlEncodingParserBuilder.java   |  513 +++++
 .../urlencoding/UrlEncodingParserContext.java   |   56 +-
 .../urlencoding/UrlEncodingParserSession.java   |    5 +-
 .../urlencoding/UrlEncodingSerializer.java      |  616 +-----
 .../UrlEncodingSerializerBuilder.java           |  590 ++++++
 .../UrlEncodingSerializerContext.java           |   56 +-
 .../UrlEncodingSerializerSession.java           |    7 +-
 .../org/apache/juneau/urlencoding/package.html  |   20 +-
 .../java/org/apache/juneau/utils/PojoQuery.java |    4 +-
 .../java/org/apache/juneau/xml/XmlBeanMeta.java |    1 +
 .../org/apache/juneau/xml/XmlDocSerializer.java |   29 +-
 .../java/org/apache/juneau/xml/XmlParser.java   |  604 +-----
 .../org/apache/juneau/xml/XmlParserBuilder.java |  616 ++++++
 .../org/apache/juneau/xml/XmlParserContext.java |   24 +-
 .../org/apache/juneau/xml/XmlParserSession.java |    2 +-
 .../juneau/xml/XmlSchemaDocSerializer.java      |   12 +-
 .../apache/juneau/xml/XmlSchemaSerializer.java  |   22 +-
 .../juneau/xml/XmlSchemaSerializerBuilder.java  |  570 ++++++
 .../org/apache/juneau/xml/XmlSerializer.java    |  795 +-------
 .../apache/juneau/xml/XmlSerializerBuilder.java |  717 +++++++
 .../apache/juneau/xml/XmlSerializerContext.java |   28 +-
 .../apache/juneau/xml/XmlSerializerSession.java |    2 +-
 .../java/org/apache/juneau/xml/package.html     |   75 +-
 juneau-core/src/main/javadoc/overview.html      |  362 ++--
 .../examples/rest/DockerRegistryResource.java   |    3 +-
 .../juneau/examples/rest/PhotosResource.java    |   18 +
 .../juneau/examples/rest/SqlQueryResource.java  |    2 +-
 .../examples/rest/SystemPropertiesResource.java |    2 +-
 .../juneau/examples/rest/TempDirResource.java   |    2 +-
 .../examples/rest/TumblrParserResource.java     |    5 +-
 .../examples/rest/addressbook/ClientTest.java   |    5 +-
 .../examples/rest/AddressBookResourceTest.java  |   38 +-
 .../juneau/examples/rest/RestTestcase.java      |    5 +-
 .../juneau/examples/rest/RootResourcesTest.java |   33 +-
 .../SampleRemoteableServicesResourceTest.java   |   26 +-
 .../examples/rest/SamplesMicroservice.java      |  110 ++
 .../juneau/examples/rest/SamplesRestClient.java |   69 -
 .../juneau/examples/rest/TestMicroservice.java  |   72 -
 .../rest/TestMultiPartFormPostsTest.java        |    4 +-
 .../apache/juneau/examples/rest/TestUtils.java  |   40 +-
 .../apache/juneau/examples/rest/_TestSuite.java |    4 +-
 .../core/json/JsonConfigurationExample.java     |    8 +-
 .../juneau/microservice/Microservice.java       |   19 +-
 .../apache/juneau/microservice/Resource.java    |    8 +-
 .../juneau/microservice/ResourceGroup.java      |    8 +-
 .../juneau/microservice/RestMicroservice.java   |    3 +-
 .../org/apache/juneau/microservice/package.html |    2 +
 .../microservice/resources/ConfigResource.java  |    2 +-
 .../juneau/rest/client/ResponsePattern.java     |    2 +-
 .../org/apache/juneau/rest/client/RestCall.java |  424 +++-
 .../juneau/rest/client/RestCallLogger.java      |    2 +-
 .../apache/juneau/rest/client/RestClient.java   | 1148 +----------
 .../juneau/rest/client/RestClientBuilder.java   | 1864 ++++++++++++++++++
 .../org/apache/juneau/rest/client/RetryOn.java  |   10 +
 .../org/apache/juneau/rest/client/SSLOpts.java  |    2 +-
 .../rest/client/SerializedNameValuePair.java    |    3 +-
 .../org/apache/juneau/rest/client/package.html  |   70 +-
 .../apache/juneau/rest/jaxrs/BaseProvider.java  |   26 +-
 .../juneau/rest/jaxrs/DefaultProvider.java      |    9 +-
 .../rest/jaxrs/rdf/DefaultJenaProvider.java     |   12 +-
 .../juneau/rest/test/AcceptCharsetResource.java |   10 +
 .../rest/test/CharsetEncodingsResource.java     |   10 +
 .../rest/test/DefaultContentTypesResource.java  |   24 +-
 .../apache/juneau/rest/test/GroupsResource.java |   18 +-
 .../juneau/rest/test/InheritanceResource.java   |   30 +-
 .../juneau/rest/test/NlsPropertyResource.java   |    6 +
 .../juneau/rest/test/OnPostCallResource.java    |    5 +
 .../juneau/rest/test/OnPreCallResource.java     |    5 +
 .../apache/juneau/rest/test/ParamsResource.java |    4 +-
 .../juneau/rest/test/ParsersResource.java       |   20 +
 .../juneau/rest/test/PropertiesResource.java    |   10 +
 .../juneau/rest/test/SerializersResource.java   |   21 +
 .../juneau/rest/test/AcceptCharsetTest.java     |   32 +-
 .../rest/test/BeanContextPropertiesTest.java    |    7 +-
 .../juneau/rest/test/CallbackStringsTest.java   |    2 +-
 .../juneau/rest/test/CharsetEncodingsTest.java  |   30 +-
 .../juneau/rest/test/ClientVersionTest.java     |   37 +-
 .../org/apache/juneau/rest/test/ConfigTest.java |    3 +-
 .../apache/juneau/rest/test/ContentTest.java    |  157 +-
 .../rest/test/DefaultContentTypesTest.java      |  200 +-
 .../juneau/rest/test/ErrorConditionsTest.java   |   13 +-
 .../org/apache/juneau/rest/test/GroupsTest.java |   35 +-
 .../org/apache/juneau/rest/test/GzipTest.java   |   90 +-
 .../juneau/rest/test/InheritanceTest.java       |   16 +-
 .../apache/juneau/rest/test/LargePojosTest.java |   13 +-
 .../apache/juneau/rest/test/MessagesTest.java   |    5 +-
 .../juneau/rest/test/NlsPropertyTest.java       |    9 +-
 .../org/apache/juneau/rest/test/NlsTest.java    |   20 +-
 .../juneau/rest/test/NoParserInputTest.java     |   17 +-
 .../apache/juneau/rest/test/OnPostCallTest.java |   24 +-
 .../apache/juneau/rest/test/OnPreCallTest.java  |    8 +-
 .../juneau/rest/test/OptionsWithoutNlsTest.java |    8 +-
 .../rest/test/OverlappingMethodsTest.java       |   10 +-
 .../org/apache/juneau/rest/test/ParamsTest.java |   47 +-
 .../apache/juneau/rest/test/ParsersTest.java    |   60 +-
 .../org/apache/juneau/rest/test/PathTest.java   |    5 +-
 .../org/apache/juneau/rest/test/PathsTest.java  |    5 +-
 .../apache/juneau/rest/test/PropertiesTest.java |   11 +-
 .../apache/juneau/rest/test/RestClientTest.java |   29 +-
 .../juneau/rest/test/SerializersTest.java       |   48 +-
 .../juneau/rest/test/StaticFilesTest.java       |    5 +-
 .../juneau/rest/test/TestMicroservice.java      |   63 +
 .../apache/juneau/rest/test/TestRestClient.java |   69 -
 .../org/apache/juneau/rest/test/TestUtils.java  |    6 +-
 .../apache/juneau/rest/test/TransformsTest.java |    9 +-
 .../org/apache/juneau/rest/test/UrisTest.java   |   21 +-
 .../apache/juneau/rest/test/UrlContentTest.java |   11 +-
 .../juneau/rest/test/UrlPathPatternTest.java    |    4 +-
 .../org/apache/juneau/rest/RestRequest.java     |   10 +-
 .../org/apache/juneau/rest/RestServlet.java     |  167 +-
 .../apache/juneau/rest/RestServletContext.java  |   24 +-
 .../apache/juneau/rest/RestServletDefault.java  |    7 +-
 .../juneau/rest/annotation/RestResource.java    |    5 +
 .../rest/jena/RestServletJenaDefault.java       |    6 +-
 .../java/org/apache/juneau/rest/package.html    |   18 +-
 .../apache/juneau/rest/remoteable/package.html  |    9 +-
 348 files changed, 30462 insertions(+), 22463 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfCommonContext.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfCommonContext.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfCommonContext.java
index 4c7b5d6..c806198 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfCommonContext.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfCommonContext.java
@@ -539,8 +539,8 @@ public interface RdfCommonContext {
 	 *
 	 * <h5 class='section'>Example:</h5>
 	 * <p class='bcode'>
-	 * 	WriterSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setLooseCollections(<jk>true</jk>);
-	 * 	ReaderParser p = <jk>new</jk> RdfParser.Xml().setLooseCollections(<jk>true</jk>);
+	 * 	WriterSerializer s = <jk>new</jk> RdfSerializerBuilder().xmlabbrev().looseCollections(<jk>true</jk>).build();
+	 * 	ReaderParser p = <jk>new</jk> RdfParserBuilder().xml().looseCollections(<jk>true</jk>).build();
 	 *
 	 * 	List&lt;MyBean&gt; l = createListOfMyBeans();
 	 *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index c842505..2d927dc 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -15,18 +15,14 @@ package org.apache.juneau.jena;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
-import static org.apache.juneau.jena.RdfParserContext.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.jena.annotation.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transform.*;
-import org.apache.juneau.xml.*;
-import org.apache.juneau.xml.annotation.*;
 
 import com.hp.hpl.jena.rdf.model.*;
 import com.hp.hpl.jena.util.iterator.*;
@@ -57,55 +53,107 @@ import com.hp.hpl.jena.util.iterator.*;
 public class RdfParser extends ReaderParser {
 
 	/** Default XML parser, all default settings.*/
-	public static final RdfParser DEFAULT_XML = new RdfParser.Xml().lock();
+	public static final RdfParser DEFAULT_XML = new RdfParser(PropertyStore.create());
 
 	/** Default Turtle parser, all default settings.*/
-	public static final RdfParser DEFAULT_TURTLE = new RdfParser.Turtle().lock();
+	public static final RdfParser DEFAULT_TURTLE = new Turtle(PropertyStore.create());
 
 	/** Default N-Triple parser, all default settings.*/
-	public static final RdfParser DEFAULT_NTRIPLE = new RdfParser.NTriple().lock();
+	public static final RdfParser DEFAULT_NTRIPLE = new NTriple(PropertyStore.create());
 
 	/** Default N3 parser, all default settings.*/
-	public static final RdfParser DEFAULT_N3 = new RdfParser.N3().lock();
-
+	public static final RdfParser DEFAULT_N3 = new N3(PropertyStore.create());
+	
 
 	/** Consumes RDF/XML input */
 	@Consumes("text/xml+rdf")
 	public static class Xml extends RdfParser {
-		/** Constructor */
-		public Xml() {
-			setLanguage(LANG_RDF_XML);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Xml(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+		
+		@Override
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML);
 		}
 	}
 
 	/** Consumes N-Triple input */
 	@Consumes(value="text/n-triple")
 	public static class NTriple extends RdfParser {
-		/** Constructor */
-		public NTriple() {
-			setLanguage(LANG_NTRIPLE);
+		
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public NTriple(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+		
+		@Override
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE);
 		}
 	}
 
 	/** Consumes Turtle input */
 	@Consumes(value="text/turtle")
 	public static class Turtle extends RdfParser {
-		/** Constructor */
-		public Turtle() {
-			setLanguage(LANG_TURTLE);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Turtle(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+		
+		@Override
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_TURTLE);
 		}
 	}
 
 	/** Consumes N3 input */
 	@Consumes(value="text/n3")
 	public static class N3 extends RdfParser {
-		/** Constructor */
-		public N3() {
-			setLanguage(LANG_N3);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public N3(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+		
+		@Override
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_N3);
 		}
 	}
 
 
+	private final RdfParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public RdfParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(RdfParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public RdfParserBuilder builder() {
+		return new RdfParserBuilder(propertyStore);
+	}
+
 	@SuppressWarnings({"unchecked", "rawtypes"})
 	@Override /* ReaderParser */
 	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -398,7 +446,6 @@ public class RdfParser extends ReaderParser {
 			}
 
 		}
-		// TODO Auto-generated method stub
 		return m;
 	}
 
@@ -425,660 +472,6 @@ public class RdfParser extends ReaderParser {
 
 	@Override /* Parser */
 	public RdfParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new RdfParserSession(getContext(RdfParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
-	}
-	
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Trim whitespace from text elements.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RdfParser.trimWhitespace"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, whitespace in text elements will be automatically trimmed.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_trimWhitespace</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfParserContext#RDF_trimWhitespace
-	 */
-	public RdfParser setTrimWhitespace(boolean value) throws LockedException {
-		return setProperty(RDF_trimWhitespace, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  RDF language.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.language"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"RDF/XML-ABBREV"</js>
-	 * </ul>
-	 * <p>
-	 * Can be any of the following:
-	 * <ul class='spaced-list'>
-	 * 	<li><js>"RDF/XML"</js>
-	 * 	<li><js>"RDF/XML-ABBREV"</js>
-	 * 	<li><js>"N-TRIPLE"</js>
-	 * 	<li><js>"N3"</js> - General name for the N3 writer.
-	 * 		Will make a decision on exactly which writer to use (pretty writer, plain writer or simple writer) when created.
-	 * 		Default is the pretty writer but can be overridden with system property	<code>com.hp.hpl.jena.n3.N3JenaWriter.writer</code>.
-	 * 	<li><js>"N3-PP"</js> - Name of the N3 pretty writer.
-	 * 		The pretty writer uses a frame-like layout, with prefixing, clustering like properties and embedding one-referenced bNodes.
-	 * 	<li><js>"N3-PLAIN"</js> - Name of the N3 plain writer.
-	 * 		The plain writer writes records by subject.
-	 * 	<li><js>"N3-TRIPLES"</js> - Name of the N3 triples writer.
-	 * 		This writer writes one line per statement, like N-Triples, but does N3-style prefixing.
-	 * 	<li><js>"TURTLE"</js> -  Turtle writer.
-	 * 		http://www.dajobe.org/2004/01/turtle/
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_language</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfParserContext#RDF_language
-	 */
-	public RdfParser setLanguage(String value) throws LockedException {
-		return setProperty(RDF_language, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XML namespace for Juneau properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.juneauNs"</js>
-	 * 	<li><b>Data type:</b> {@link Namespace}
-	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_juneauNs</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfParserContext#RDF_juneauNs
-	 */
-	public RdfParser setJuneauNs(Namespace value) throws LockedException {
-		return setProperty(RDF_juneauNs, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default XML namespace for bean properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.juneauBpNs"</js>
-	 * 	<li><b>Data type:</b> {@link Namespace}
-	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_juneauBpNs</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfParserContext#RDF_juneauBpNs
-	 */
-	public RdfParser setJuneauBpNs(Namespace value) throws LockedException {
-		return setProperty(RDF_juneauBpNs, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Reuse XML namespaces when RDF namespaces not specified.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.useXmlNamespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * When specified, namespaces defined using {@link XmlNs} and {@link Xml} will be inherited by the RDF serializers.
-	 * Otherwise, namespaces will be defined using {@link RdfNs} and {@link Rdf}.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_useXmlNamespaces</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfParserContext#RDF_useXmlNamespaces
-	 */
-	public RdfParser setUseXmlNamespaces(boolean value) throws LockedException {
-		return setProperty(RDF_useXmlNamespaces, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  RDF format for representing collections and arrays.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.collectionFormat"</js>
-	 * 	<li><b>Data type:</b> <code>RdfCollectionFormat</code>
-	 * 	<li><b>Default:</b> <js>"DEFAULT"</js>
-	 * </ul>
-	 * <p>
-	 * Possible values:
-	 * <ul class='spaced-list'>
-	 * 	<li><js>"DEFAULT"</js> - Default format.  The default is an RDF Sequence container.
-	 * 	<li><js>"SEQ"</js> - RDF Sequence container.
-	 * 	<li><js>"BAG"</js> - RDF Bag container.
-	 * 	<li><js>"LIST"</js> - RDF List container.
-	 * 	<li><js>"MULTI_VALUED"</js> - Multi-valued properties.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the order of the elements in the collection will get lost.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_collectionFormat</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfCommonContext#RDF_collectionFormat
-	 */
-	public RdfParser setCollectionFormat(RdfCollectionFormat value) throws LockedException {
-		return setProperty(RDF_collectionFormat, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Collections should be serialized and parsed as loose collections.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.looseCollections"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * When specified, collections of resources are handled as loose collections of resources in RDF instead of
-	 * resources that are children of an RDF collection (e.g. Sequence, Bag).
-	 * <p>
-	 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of
-	 * losslessly representing POJO models, since the tree structure of these POJO models are lost
-	 * when serialized as loose collections.
-	 * <p>
-	 * This setting is typically only useful if the beans being parsed into do not have a bean property
-	 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	WriterSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setLooseCollections(<jk>true</jk>);
-	 * 	ReaderParser p = <jk>new</jk> RdfParser.Xml().setLooseCollections(<jk>true</jk>);
-	 *
-	 * 	List&lt;MyBean&gt; l = createListOfMyBeans();
-	 *
-	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
-	 * 	String rdfXml = s.serialize(l);
-	 *
-	 * <jc>// Parse back into a Java collection</jc>
-	 * 	l = p.parse(rdfXml, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
-	 *
-	 * 	MyBean[] b = createArrayOfMyBeans();
-	 *
-	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
-	 * 	String rdfXml = s.serialize(b);
-	 *
-	 * <jc>// Parse back into a bean array</jc>
-	 * 	b = p.parse(rdfXml, MyBean[].<jk>class</jk>);
-	 * </p>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_looseCollections</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfCommonContext#RDF_looseCollections
-	 */
-	public RdfParser setLooseCollections(boolean value) throws LockedException {
-		return setProperty(RDF_looseCollections, value);
-	}
-
-	@Override /* Parser */
-	public RdfParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public RdfParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public RdfParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public RdfParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-	
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public RdfParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public RdfParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public RdfParser clone() {
-		try {
-			RdfParser c = (RdfParser)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
+		return new RdfParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
new file mode 100644
index 0000000..1a71a2b
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserBuilder.java
@@ -0,0 +1,728 @@
+// ***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfParserContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.xml.*;
+import org.apache.juneau.xml.annotation.*;
+
+/**
+ * Builder class for building instances of RDF parsers.
+ */
+public class RdfParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public RdfParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public RdfParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParser build() {
+		return new RdfParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Trim whitespace from text elements.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RdfParser.trimWhitespace"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, whitespace in text elements will be automatically trimmed.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_trimWhitespace</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfParserContext#RDF_trimWhitespace
+	 */
+	public RdfParserBuilder trimWhitespace(boolean value) {
+		return property(RDF_trimWhitespace, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  RDF language.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.language"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"RDF/XML-ABBREV"</js>
+	 * </ul>
+	 * <p>
+	 * Can be any of the following:
+	 * <ul class='spaced-list'>
+	 * 	<li><js>"RDF/XML"</js>
+	 * 	<li><js>"RDF/XML-ABBREV"</js>
+	 * 	<li><js>"N-TRIPLE"</js>
+	 * 	<li><js>"N3"</js> - General name for the N3 writer.
+	 * 		Will make a decision on exactly which writer to use (pretty writer, plain writer or simple writer) when created.
+	 * 		Default is the pretty writer but can be overridden with system property	<code>com.hp.hpl.jena.n3.N3JenaWriter.writer</code>.
+	 * 	<li><js>"N3-PP"</js> - Name of the N3 pretty writer.
+	 * 		The pretty writer uses a frame-like layout, with prefixing, clustering like properties and embedding one-referenced bNodes.
+	 * 	<li><js>"N3-PLAIN"</js> - Name of the N3 plain writer.
+	 * 		The plain writer writes records by subject.
+	 * 	<li><js>"N3-TRIPLES"</js> - Name of the N3 triples writer.
+	 * 		This writer writes one line per statement, like N-Triples, but does N3-style prefixing.
+	 * 	<li><js>"TURTLE"</js> -  Turtle writer.
+	 * 		http://www.dajobe.org/2004/01/turtle/
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_language</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfParserContext#RDF_language
+	 */
+	public RdfParserBuilder language(String value) {
+		return property(RDF_language, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfParserBuilder xml() {
+		return language(Constants.LANG_RDF_XML);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML_ABBREV</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfParserBuilder xmlabbrev() {
+		return language(Constants.LANG_RDF_XML_ABBREV);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_NTRIPLE</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfParserBuilder ntriple() {
+		return language(Constants.LANG_NTRIPLE);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_N3</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfParserBuilder n3() {
+		return language(Constants.LANG_N3);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_TURTLE</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfParserBuilder turtle() {
+		return language(Constants.LANG_TURTLE);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XML namespace for Juneau properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.juneauNs"</js>
+	 * 	<li><b>Data type:</b> {@link Namespace}
+	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_juneauNs</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfParserContext#RDF_juneauNs
+	 */
+	public RdfParserBuilder juneauNs(Namespace value) {
+		return property(RDF_juneauNs, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default XML namespace for bean properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.juneauBpNs"</js>
+	 * 	<li><b>Data type:</b> {@link Namespace}
+	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_juneauBpNs</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfParserContext#RDF_juneauBpNs
+	 */
+	public RdfParserBuilder juneauBpNs(Namespace value) {
+		return property(RDF_juneauBpNs, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Reuse XML namespaces when RDF namespaces not specified.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.useXmlNamespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * When specified, namespaces defined using {@link XmlNs} and {@link Xml} will be inherited by the RDF parsers.
+	 * Otherwise, namespaces will be defined using {@link RdfNs} and {@link Rdf}.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_useXmlNamespaces</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfParserContext#RDF_useXmlNamespaces
+	 */
+	public RdfParserBuilder useXmlNamespaces(boolean value) {
+		return property(RDF_useXmlNamespaces, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  RDF format for representing collections and arrays.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.collectionFormat"</js>
+	 * 	<li><b>Data type:</b> <code>RdfCollectionFormat</code>
+	 * 	<li><b>Default:</b> <js>"DEFAULT"</js>
+	 * </ul>
+	 * <p>
+	 * Possible values:
+	 * <ul class='spaced-list'>
+	 * 	<li><js>"DEFAULT"</js> - Default format.  The default is an RDF Sequence container.
+	 * 	<li><js>"SEQ"</js> - RDF Sequence container.
+	 * 	<li><js>"BAG"</js> - RDF Bag container.
+	 * 	<li><js>"LIST"</js> - RDF List container.
+	 * 	<li><js>"MULTI_VALUED"</js> - Multi-valued properties.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the order of the elements in the collection will get lost.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_collectionFormat</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfCommonContext#RDF_collectionFormat
+	 */
+	public RdfParserBuilder collectionFormat(RdfCollectionFormat value) {
+		return property(RDF_collectionFormat, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Collections should be serialized and parsed as loose collections.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.looseCollections"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * When specified, collections of resources are handled as loose collections of resources in RDF instead of
+	 * resources that are children of an RDF collection (e.g. Sequence, Bag).
+	 * <p>
+	 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of
+	 * losslessly representing POJO models, since the tree structure of these POJO models are lost
+	 * when serialized as loose collections.
+	 * <p>
+	 * This setting is typically only useful if the beans being parsed into do not have a bean property
+	 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	WriterSerializer s = <jk>new</jk> RdfSerializerBuilder().xmlabbrev().looseCollections(<jk>true</jk>).build();
+	 * 	ReaderParser p = <jk>new</jk> RdfParserBuilder().xml().looseCollections(<jk>true</jk>).build();
+	 *
+	 * 	List&lt;MyBean&gt; l = createListOfMyBeans();
+	 *
+	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
+	 * 	String rdfXml = s.serialize(l);
+	 *
+	 * <jc>// Parse back into a Java collection</jc>
+	 * 	l = p.parse(rdfXml, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 *
+	 * 	MyBean[] b = createArrayOfMyBeans();
+	 *
+	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
+	 * 	String rdfXml = s.serialize(b);
+	 *
+	 * <jc>// Parse back into a bean array</jc>
+	 * 	b = p.parse(rdfXml, MyBean[].<jk>class</jk>);
+	 * </p>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_looseCollections</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfCommonContext#RDF_looseCollections
+	 */
+	public RdfParserBuilder looseCollections(boolean value) {
+		return property(RDF_looseCollections, value);
+	}
+
+	@Override /* ParserBuilder */
+	public RdfParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public RdfParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public RdfParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+	
+	@Override /* ParserBuilder */
+	public RdfParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public RdfParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> RdfParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
index 0161f11..708fd5b 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfParserContext.java
@@ -21,10 +21,10 @@ import org.apache.juneau.xml.*;
 /**
  * Configurable properties on the {@link RdfParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h6 class='topic' id='ConfigProperties'>Configurable properties inherited by the RDF parsers</h6>
  * <ul class='javahierarchy'>
@@ -62,18 +62,18 @@ public final class RdfParserContext extends ParserContext implements RdfCommonCo
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public RdfParserContext(ContextFactory cf) {
-		super(cf);
-		trimWhitespace = cf.getProperty(RDF_trimWhitespace, boolean.class, false);
-		looseCollections = cf.getProperty(RDF_looseCollections, boolean.class, false);
-		rdfLanguage = cf.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
-		juneauNs = cf.getProperty(RDF_juneauNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneau/"));
-		juneauBpNs = cf.getProperty(RDF_juneauBpNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneaubp/"));
-		collectionFormat = cf.getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
+	public RdfParserContext(PropertyStore ps) {
+		super(ps);
+		trimWhitespace = ps.getProperty(RDF_trimWhitespace, boolean.class, false);
+		looseCollections = ps.getProperty(RDF_looseCollections, boolean.class, false);
+		rdfLanguage = ps.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
+		juneauNs = ps.getProperty(RDF_juneauNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneau/"));
+		juneauBpNs = ps.getProperty(RDF_juneauBpNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneaubp/"));
+		collectionFormat = ps.getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
 	}
 
 	@Override /* Context */


[18/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
new file mode 100644
index 0000000..bb397dd
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserBuilder.java
@@ -0,0 +1,571 @@
+// ***************************************************************************************************************************
+// * 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.parser;
+
+import static org.apache.juneau.parser.ParserContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+
+/**
+ * Builder class for building instances of parsers.
+ */
+public class ParserBuilder extends CoreObjectBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public ParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public ParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public Parser build() {
+		return null;
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Trim parsed strings.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Parser.trimStrings"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>PARSER_trimStrings</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_trimStrings
+	 */
+	public ParserBuilder trimStrings(boolean value) {
+		return property(PARSER_trimStrings, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Strict mode.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Parser.strict"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, strict mode for the parser is enabled.
+	 * <p>
+	 * Strict mode can mean different things for different parsers.
+	 * <p>
+	 * <table class='styled'>
+	 * 	<tr><th>Parser class</th><th>Strict behavior</th></tr>
+	 * 	<tr>
+	 * 		<td>All reader-based parsers</td>
+	 * 		<td>
+	 * 			When enabled, throws {@link ParseException ParseExceptions} on malformed charset input.
+	 * 			Otherwise, malformed input is ignored.
+	 * 		</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>{@link JsonParser}</td>
+	 * 		<td>
+	 * 			When enabled, throws exceptions on the following invalid JSON syntax:
+	 * 			<ul>
+	 * 				<li>Unquoted attributes.
+	 * 				<li>Missing attribute values.
+	 * 				<li>Concatenated strings.
+	 * 				<li>Javascript comments.
+	 * 				<li>Numbers and booleans when Strings are expected.
+	 * 				<li>Numbers valid in Java but not JSON (e.g. octal notation, etc...)
+	 * 			</ul>
+	 * 		</td>
+	 * 	</tr>
+	 * </table>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>PARSER_strict</jsf>,value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_strict
+	 */
+	public ParserBuilder strict(boolean value) {
+		return property(PARSER_strict, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>strict(<jk>true</jk>)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public ParserBuilder strict() {
+		return strict(true);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Input stream charset.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Parser.inputStreamCharset"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"UTF-8"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * The character set to use for converting <code>InputStreams</code> and byte arrays to readers.
+	 * <p>
+	 * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>PARSER_inputStreamCharset</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_inputStreamCharset
+	 */
+	public ParserBuilder inputStreamCharset(String value) {
+		return property(PARSER_inputStreamCharset, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  File charset.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Parser.fileCharset"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"default"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * The character set to use for reading <code>Files</code> from the file system.
+	 * <p>
+	 * Used when passing in files to {@link Parser#parse(Object, Class)}.
+	 * <p>
+	 * <js>"default"</js> can be used to indicate the JVM default file system charset.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>PARSER_fileCharset</jsf>,value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_fileCharset
+	 */
+	public ParserBuilder fileCharset(String value) {
+		return property(PARSER_fileCharset, value);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CoreObjectBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public ParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
index 1432efb..e0ee73c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserContext.java
@@ -117,14 +117,14 @@ public class ParserContext extends BeanContext {
 	/**
 	 * Constructor.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public ParserContext(ContextFactory cf) {
-		super(cf);
-		this.trimStrings = cf.getProperty(PARSER_trimStrings, boolean.class, false);
-		this.strict = cf.getProperty(PARSER_strict, boolean.class, false);
-		this.inputStreamCharset = cf.getProperty(PARSER_inputStreamCharset, String.class, "UTF-8");
-		this.fileCharset = cf.getProperty(PARSER_fileCharset, String.class, "default");
+	public ParserContext(PropertyStore ps) {
+		super(ps);
+		this.trimStrings = ps.getProperty(PARSER_trimStrings, boolean.class, false);
+		this.strict = ps.getProperty(PARSER_strict, boolean.class, false);
+		this.inputStreamCharset = ps.getProperty(PARSER_inputStreamCharset, String.class, "UTF-8");
+		this.fileCharset = ps.getProperty(PARSER_fileCharset, String.class, "default");
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
index f78f733..3dd0dc7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/ParserGroup.java
@@ -12,12 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.parser;
 
-import static org.apache.juneau.internal.ArrayUtils.*;
-
 import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
 
 /**
  * Represents a group of {@link Parser Parsers} that can be looked up by media type.
@@ -44,16 +43,17 @@ import org.apache.juneau.*;
  *
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
- * 	<jc>// Construct a new parser group</jc>
- * 	ParserGroup g = <jk>new</jk> ParserGroup();
+ * 	<jc>// Construct a new parser group builder</jc>
+ * 	ParserGroupBuilder b = <jk>new</jk> ParserGroupBuilder();
  *
  * 	<jc>// Add some parsers to it</jc>
- * 	g.append(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
+ * 	b.append(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>);
  *
  * 	<jc>// Change settings on parsers simultaneously</jc>
- * 	g.setProperty(BeanContext.<jsf>BEAN_beansRequireSerializable</jsf>, <jk>true</jk>)
- * 		.addPojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>)
- * 		.lock();
+ * 	b.property(BeanContext.<jsf>BEAN_beansRequireSerializable</jsf>, <jk>true</jk>)
+ * 		.pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>);
+ *
+ * 	ParserGroup g = b.build();
  *
  * 	<jc>// Find the appropriate parser by Content-Type</jc>
  * 	ReaderParser p = (ReaderParser)g.getParser(<js>"text/json"</js>);
@@ -63,68 +63,26 @@ import org.apache.juneau.*;
  * 	AddressBook addressBook = p.parse(json, AddressBook.<jk>class</jk>);
  * </p>
  */
-public final class ParserGroup extends Lockable {
+public final class ParserGroup {
 
 	// Maps Content-Type headers to matches.
 	private final Map<String,ParserMatch> cache = new ConcurrentHashMap<String,ParserMatch>();
 
-	private final CopyOnWriteArrayList<Parser> parsers = new CopyOnWriteArrayList<Parser>();
-
-	/**
-	 * Adds the specified parser to the beginning of this group.
-	 *
-	 * @param p The parser to add to this group.
-	 * @return This object (for method chaining).
-	 */
-	public ParserGroup append(Parser p) {
-		checkLock();
-		synchronized(this) {
-			cache.clear();
-			parsers.add(0, p);
-		}
-		return this;
-	}
-
-	/**
-	 * Registers the specified parsers with this group.
-	 *
-	 * @param p The parsers to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Parser} could not be constructed.
-	 */
-	public ParserGroup append(Class<? extends Parser>...p) throws Exception {
-		for (Class<? extends Parser> pp : reverse(p))
-			append(pp);
-		return this;
-	}
+	final Parser[] parsers;
+	private final PropertyStore propertyStore;
 
 	/**
-	 * Same as {@link #append(Class[])}, except specify a single class to avoid unchecked compile warnings.
+	 * Constructor.
 	 *
-	 * @param p The parser to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Parser} could not be constructed.
+	 * @param propertyStore The modifiable properties that were used to initialize the parsers.
+	 * A snapshot of these will be made so that we can clone and modify this group.
+	 * @param parsers The parsers defined in this group.
+	 * The order is important because they will be tried in reverse order (e.g.
+	 * 	newer first) in which they will be tried to match against media types.
 	 */
-	public ParserGroup append(Class<? extends Parser> p) throws Exception {
-		try {
-			append(p.newInstance());
-		} catch (NoClassDefFoundError e) {
-			// Ignore if dependent library not found (e.g. Jena).
-			System.err.println(e); // NOT DEBUG
-		}
-		return this;
-	}
-
-	/**
-	 * Adds the parsers in the specified group to this group.
-	 *
-	 * @param g The group containing the parsers to add to this group.
-	 * @return This object (for method chaining).
-	 */
-	public ParserGroup append(ParserGroup g) {
-		for (Parser p : reverse(g.parsers.toArray(new Parser[g.parsers.size()])))
-			append(p);
-		return this;
+	public ParserGroup(PropertyStore propertyStore, Parser[] parsers) {
+		this.propertyStore = PropertyStore.create(propertyStore);
+		this.parsers = ArrayUtils.reverse(parsers);
 	}
 
 	/**
@@ -203,1060 +161,23 @@ public final class ParserGroup extends Lockable {
 		return l;
 	}
 
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * Calls {@link Parser#setTrimStrings(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_trimStrings
-	 */
-	public ParserGroup setTrimStrings(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setTrimStrings(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setStrict(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_strict
-	 */
-	public ParserGroup setStrict(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setStrict(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setInputStreamCharset(String)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_inputStreamCharset
-	 */
-	public ParserGroup setInputStreamCharset(String value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setInputStreamCharset(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setFileCharset(String)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_fileCharset
-	 */
-	public ParserGroup setFileCharset(String value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setFileCharset(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeansRequireDefaultConstructor(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
-	 */
-	public ParserGroup setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeansRequireSerializable(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSerializable
-	 */
-	public ParserGroup setBeansRequireSerializable(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeansRequireSettersForGetters(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSettersForGetters
-	 */
-	public ParserGroup setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeansRequireSomeProperties(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSomeProperties
-	 */
-	public ParserGroup setBeansRequireSomeProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanMapPutReturnsOldValue(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
-	 */
-	public ParserGroup setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanConstructorVisibility(Visibility)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanConstructorVisibility
-	 */
-	public ParserGroup setBeanConstructorVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanClassVisibility(Visibility)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanClassVisibility
-	 */
-	public ParserGroup setBeanClassVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanClassVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanFieldVisibility(Visibility)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFieldVisibility
-	 */
-	public ParserGroup setBeanFieldVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setMethodVisibility(Visibility)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_methodVisibility
-	 */
-	public ParserGroup setMethodVisibility(Visibility value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setMethodVisibility(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setUseJavaBeanIntrospector(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useJavaBeanIntrospector
-	 */
-	public ParserGroup setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setUseInterfaceProxies(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useInterfaceProxies
-	 */
-	public ParserGroup setUseInterfaceProxies(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setIgnoreUnknownBeanProperties(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
-	 */
-	public ParserGroup setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setIgnoreUnknownNullBeanProperties(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
-	 */
-	public ParserGroup setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setIgnorePropertiesWithoutSetters(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
-	 */
-	public ParserGroup setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setIgnoreInvocationExceptionsOnGetters(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
-	 */
-	public ParserGroup setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setIgnoreInvocationExceptionsOnSetters(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
-	 */
-	public ParserGroup setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setSortProperties(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_sortProperties
-	 */
-	public ParserGroup setSortProperties(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setSortProperties(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setNotBeanPackages(String...)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public ParserGroup setNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setNotBeanPackages(Collection)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public ParserGroup setNotBeanPackages(Collection<String> value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setNotBeanPackages(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addNotBeanPackages(String...)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public ParserGroup addNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addNotBeanPackages(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public ParserGroup addNotBeanPackages(Collection<String> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeNotBeanPackages(String...)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public ParserGroup removeNotBeanPackages(String...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeNotBeanPackages(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public ParserGroup removeNotBeanPackages(Collection<String> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeNotBeanPackages(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setNotBeanClasses(Class...)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 */
-	public ParserGroup setNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setNotBeanClasses(Collection)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public ParserGroup setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addNotBeanClasses(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public ParserGroup addNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addNotBeanClasses(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public ParserGroup addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeNotBeanClasses(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public ParserGroup removeNotBeanClasses(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeNotBeanClasses(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public ParserGroup removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeNotBeanClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanFilters(Class...)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public ParserGroup setBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanFilters(Collection)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public ParserGroup setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addBeanFilters(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public ParserGroup addBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addBeanFilters(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public ParserGroup addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeBeanFilters(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public ParserGroup removeBeanFilters(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeBeanFilters(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public ParserGroup removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeBeanFilters(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setPojoSwaps(Class...)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public ParserGroup setPojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setPojoSwaps(Collection)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public ParserGroup setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setPojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addPojoSwaps(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
-	 */
-	public ParserGroup addPojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addPojoSwaps(values);
-		return this;
-	}
-
 	/**
-	 * Calls {@link Parser#addPojoSwaps(Collection)} on all parsers in this group.
+	 * Returns a copy of the property store that was used to create the parsers in this group.
+	 * This method returns a new factory each time so is somewhat expensive.
 	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
+	 * @return A new copy of the property store passed in to the constructor.
 	 */
-	public ParserGroup addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addPojoSwaps(values);
-		return this;
+	public PropertyStore createPropertyStore() {
+		return PropertyStore.create(propertyStore);
 	}
 
 	/**
-	 * Calls {@link Parser#removePojoSwaps(Class...)} on all parsers in this group.
+	 * Returns a copy of the parsers in this group.
+	 * This method returns a new array each time so is somewhat expensive.
 	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
+	 * @return A new array containing the parsers in this group.
 	 */
-	public ParserGroup removePojoSwaps(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removePojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removePojoSwaps(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
-	 */
-	public ParserGroup removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removePojoSwaps(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setImplClasses(Map)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 */
-	public ParserGroup setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setImplClasses(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addImplClass(Class,Class)} on all parsers in this group.
-	 *
-	 * @param interfaceClass The interface class.
-	 * @param implClass The implementation class.
-	 * @param <T> The class type of the interface.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 * @see BeanContext#BEAN_implClasses_put
-	 */
-	public <T> ParserGroup addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanDictionary(Class...)} on all parsers in this group.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 */
-	public ParserGroup setBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanDictionary(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public ParserGroup setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addToBeanDictionary(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public ParserGroup addToBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addToBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addToBeanDictionary(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public ParserGroup addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addToBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeFromBeanDictionary(Class...)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public ParserGroup removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeFromBeanDictionary(Collection)} on all parsers in this group.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public ParserGroup removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setBeanTypePropertyName(String)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanTypePropertyName
-	 */
-	public ParserGroup setBeanTypePropertyName(String value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setDefaultParser(Class)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_defaultParser
-	 */
-	public ParserGroup setDefaultParser(Class<?> value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setDefaultParser(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setLocale(Locale)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_locale
-	 */
-	public ParserGroup setLocale(Locale value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setLocale(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setTimeZone(TimeZone)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_timeZone
-	 */
-	public ParserGroup setTimeZone(TimeZone value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setTimeZone(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setMediaType(MediaType)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_mediaType
-	 */
-	public ParserGroup setMediaType(MediaType value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setMediaType(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setDebug(boolean)} on all parsers in this group.
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_debug
-	 */
-	public ParserGroup setDebug(boolean value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setDebug(value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setProperty(String,Object)} on all parsers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The property value.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object or {@link ContextFactory} object.
-	 * @see ContextFactory#setProperty(String, Object)
-	 */
-	public ParserGroup setProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#setProperties(ObjectMap)} on all parsers in this group.
-	 *
-	 * @param properties The properties to set on this class.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 * @see ContextFactory#setProperties(java.util.Map)
-	 */
-	public ParserGroup setProperties(ObjectMap properties) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setProperties(properties);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#addToProperty(String,Object)} on all parsers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The new value to add to the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public ParserGroup addToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.addToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#putToProperty(String,Object,Object)} on all parsers in this group.
-	 *
-	 * @param name The property name.
-	 * @param key The property value map key.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public ParserGroup putToProperty(String name, Object key, Object value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.putToProperty(name, key, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#putToProperty(String,Object)} on all parsers in this group.
-	 *
-	 * @param name The property value.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public ParserGroup putToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.putToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Calls {@link Parser#removeFromProperty(String,Object)} on all parsers in this group.
-	 *
-	 * @param name The property name.
-	 * @param value The property value in the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public ParserGroup removeFromProperty(String name, Object value) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * Calls {@link Parser#setClassLoader(ClassLoader)} on all parsers in this group.
-	 *
-	 * @param classLoader The new classloader.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#setClassLoader(ClassLoader)
-	 */
-	public ParserGroup setClassLoader(ClassLoader classLoader) throws LockedException {
-		checkLock();
-		for (Parser p : parsers)
-			p.setClassLoader(classLoader);
-		return this;
-	}
-
-	/**
-	 * Locks this group and all parsers in this group.
-	 */
-	@Override /* Lockable */
-	public ParserGroup lock() {
-		super.lock();
-		for (Parser p : parsers)
-			p.lock();
-		return this;
-	}
-
-	/**
-	 * Clones this group and all parsers in this group.
-	 */
-	@Override /* Lockable */
-	public ParserGroup clone() throws CloneNotSupportedException {
-		ParserGroup g = new ParserGroup();
-
-		List<Parser> l = new ArrayList<Parser>(parsers.size());
-		for (Parser p : parsers)
-			l.add(p.clone());
-
-		g.parsers.addAll(l);
-
-		return g;
+	public Parser[] getParsers() {
+		return ArrayUtils.reverse(parsers);
 	}
 }


[12/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
new file mode 100644
index 0000000..96bb20b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerBuilder.java
@@ -0,0 +1,570 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.uon.UonSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Builder class for building instances of UON serializers.
+ */
+public class UonSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public UonSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public UonSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializer build() {
+		return new UonSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Encode non-valid URI characters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UonSerializer.encodeChars"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonSerializer}, <jk>true</jk> for {@link UrlEncodingSerializer}
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Encode non-valid URI characters with <js>"%xx"</js> constructs.
+	 * <p>
+	 * If <jk>true</jk>, non-valid URI characters will be converted to <js>"%xx"</js> sequences.
+	 * Set to <jk>false</jk> if parameter value is being passed to some other code that will already
+	 * 	perform URL-encoding of non-valid URI characters.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>UON_encodeChars</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see UonSerializerContext#UON_encodeChars
+	 */
+	public UonSerializerBuilder encodeChars(boolean value) {
+		return property(UON_encodeChars, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>setEncodeChars(true)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public UonSerializerBuilder encoding() {
+		return encodeChars(true);
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UonSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> UonSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UonSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
new file mode 100644
index 0000000..b9ce464
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerContext.java
@@ -0,0 +1,100 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Configurable properties on the {@link UonSerializer} class.
+ * <p>
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
+ * <p>
+ * See {@link PropertyStore} for more information about context properties.
+ *
+ * <h5 class='section'>Inherited configurable properties:</h5>
+ * <ul class='javahierarchy'>
+ * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
+ * 	<ul>
+ * 		<li class='c'><a class="doclink" href="../serializer/SerializerContext.html#ConfigProperties">SerializerContext</a> - Configurable properties common to all serializers.
+ * 	</ul>
+ * </ul>
+ */
+public class UonSerializerContext extends SerializerContext {
+
+	/**
+	 * <b>Configuration property:</b>  Encode non-valid URI characters.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UonSerializer.encodeChars"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonSerializer}, <jk>true</jk> for {@link UrlEncodingSerializer}
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Encode non-valid URI characters with <js>"%xx"</js> constructs.
+	 * <p>
+	 * If <jk>true</jk>, non-valid URI characters will be converted to <js>"%xx"</js> sequences.
+	 * Set to <jk>false</jk> if parameter value is being passed to some other code that will already
+	 * 	perform URL-encoding of non-valid URI characters.
+	 */
+	public static final String UON_encodeChars = "UonSerializer.encodeChars";
+
+	/**
+	 * <b>Configuration property:</b>  Add <js>"_type"</js> properties when needed.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UonSerializer.addBeanTypeProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred through reflection.
+	 * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
+	 * For example, when serializing a {@code Map<String,Object>} field, where the bean class cannot be determined from the value type.
+	 * <p>
+	 * When present, this value overrides the {@link SerializerContext#SERIALIZER_addBeanTypeProperties} setting and is
+	 * provided to customize the behavior of specific serializers in a {@link SerializerGroup}.
+	 */
+	public static final String UON_addBeanTypeProperties = "UonSerializer.addBeanTypeProperties";
+
+
+	final boolean
+		encodeChars,
+		addBeanTypeProperties;
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
+	 *
+	 * @param ps The property store that created this context.
+	 */
+	public UonSerializerContext(PropertyStore ps) {
+		super(ps);
+		encodeChars = ps.getProperty(UON_encodeChars, boolean.class, false);
+		addBeanTypeProperties = ps.getProperty(UON_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	}
+
+	@Override /* Context */
+	public ObjectMap asMap() {
+		return super.asMap()
+			.append("UonSerializerContext", new ObjectMap()
+				.append("encodeChars", encodeChars)
+				.append("addBeanTypeProperties", addBeanTypeProperties)
+			);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
new file mode 100644
index 0000000..92fbe56
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonSerializerSession.java
@@ -0,0 +1,88 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import static org.apache.juneau.msgpack.MsgPackSerializerContext.*;
+import static org.apache.juneau.uon.UonSerializerContext.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link UonSerializer}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ */
+public class UonSerializerSession extends SerializerSession {
+
+	private final boolean
+		encodeChars,
+		addBeanTypeProperties;
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * The context contains all the configuration settings for this object.
+	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
+	 * @param op The override properties.
+	 * These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
+	 * @param locale The session locale.
+	 * If <jk>null</jk>, then the locale defined on the context is used.
+	 * @param timeZone The session timezone.
+	 * If <jk>null</jk>, then the timezone defined on the context is used.
+	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
+	 */
+	protected UonSerializerSession(UonSerializerContext ctx, ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
+		if (op == null || op.isEmpty()) {
+			encodeChars = ctx.encodeChars;
+			addBeanTypeProperties = ctx.addBeanTypeProperties;
+		} else {
+			encodeChars = op.getBoolean(UON_encodeChars, ctx.encodeChars);
+			addBeanTypeProperties = op.getBoolean(MSGPACK_addBeanTypeProperties, ctx.addBeanTypeProperties);
+		}
+	}
+
+	/**
+	 * Returns the {@link UonSerializerContext#UON_encodeChars} setting value for this session.
+	 *
+	 * @return The {@link UonSerializerContext#UON_encodeChars} setting value for this session.
+	 */
+	public final boolean isEncodeChars() {
+		return encodeChars;
+	}
+
+	/**
+	 * Returns the {@link UonSerializerContext#UON_addBeanTypeProperties} setting value for this session.
+	 *
+	 * @return The {@link UonSerializerContext#UON_addBeanTypeProperties} setting value for this session.
+	 */
+	@Override /* SerializerSession */
+	public final boolean isAddBeanTypeProperties() {
+		return addBeanTypeProperties;
+	}
+
+	@Override /* SerializerSession */
+	public final UonWriter getWriter() throws Exception {
+		Object output = getOutput();
+		if (output instanceof UonWriter)
+			return (UonWriter)output;
+		return new UonWriter(this, super.getWriter(), isUseWhitespace(), isEncodeChars(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase());
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java b/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
new file mode 100644
index 0000000..96f2405
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/UonWriter.java
@@ -0,0 +1,281 @@
+// ***************************************************************************************************************************
+// * 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.uon;
+
+import java.io.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Specialized writer for serializing UON-encoded text.
+ * <p>
+ * <h5 class='section'>Notes:</h5>
+ * <ul>
+ * 	<li>This class is not intended for external use.
+ * </ul>
+ */
+public final class UonWriter extends SerializerWriter {
+
+	private final UonSerializerSession session;
+	private final boolean encodeChars;
+
+	// Characters that do not need to be URL-encoded in strings.
+	private static final AsciiSet unencodedChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~=");
+
+	// Characters that do not need to be URL-encoded in attribute names.
+	// Identical to unencodedChars, but excludes '='.
+	private static final AsciiSet unencodedCharsAttrName = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~");
+
+	// Characters that need to be preceeded with an escape character.
+	private static final AsciiSet escapedChars = new AsciiSet("~'");
+
+	private static final AsciiSet needsQuoteChars = new AsciiSet("),=\n\t\r\b\f ");
+
+	private static final AsciiSet maybeNeedsQuotesFirstChar = new AsciiSet("),=\n\t\r\b\f tfn+-.#0123456789");
+
+	private static char[] hexArray = "0123456789ABCDEF".toCharArray();
+
+	/**
+	 * Constructor.
+	 *
+	 * @param session The session that created this writer.
+	 * @param out The writer being wrapped.
+	 * @param useWhitespace If <jk>true</jk>, tabs will be used in output.
+	 * @param encodeChars If <jk>true</jk>, special characters should be encoded.
+	 * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized.
+	 * @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>).
+	 * @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>).
+	 */
+	protected UonWriter(UonSerializerSession session, Writer out, boolean useWhitespace, boolean encodeChars, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) {
+		super(out, useWhitespace, trimStrings, '\'', relativeUriBase, absolutePathUriBase);
+		this.session = session;
+		this.encodeChars = encodeChars;
+	}
+
+	/**
+	 * Serializes the specified simple object as a UON string value.
+	 *
+	 * @param o The object being serialized.
+	 * @param isTopAttrName If this is a top-level attribute name we're serializing.
+	 * @return This object (for method chaining).
+	 * @throws IOException Should never happen.
+	 */
+	public final UonWriter appendObject(Object o, boolean isTopAttrName) throws IOException {
+
+		if (o instanceof Boolean)
+			return appendBoolean(o);
+		if (o instanceof Number)
+			return appendNumber(o);
+		if (o == null)
+			return append("null");
+
+		String s = session.toString(o);
+		char c0 = s.isEmpty() ? 0 : s.charAt(0);
+
+		boolean needsQuotes =
+			s.isEmpty()
+			|| c0 == '@'
+			|| c0 == '('
+			|| needsQuoteChars.contains(s)
+			|| (
+				maybeNeedsQuotesFirstChar.contains(c0)
+				&& (
+					"true".equals(s)
+					|| "false".equals(s)
+					|| "null".equals(s)
+					|| StringUtils.isNumeric(s)
+				)
+			)
+		;
+
+		AsciiSet unenc = (isTopAttrName ? unencodedCharsAttrName : unencodedChars);
+		AsciiSet esc = escapedChars;
+
+		if (needsQuotes)
+			append('\'');
+		for (int i = 0; i < s.length(); i++) {
+			char c = s.charAt(i);
+			if (esc.contains(c))
+				append('~');
+			if ((!encodeChars) || unenc.contains(c))
+				append(c);
+			else {
+				if (c == ' ')
+					append('+');
+				else {
+					int p = s.codePointAt(i);
+					if (p < 0x0080)
+						appendHex(p);
+					else if (p < 0x0800) {
+						int p1=p>>>6;
+						appendHex(p1+192).appendHex((p&63)+128);
+					} else if (p < 0x10000) {
+						int p1=p>>>6, p2=p1>>>6;
+						appendHex(p2+224).appendHex((p1&63)+128).appendHex((p&63)+128);
+					} else {
+						i++;  // Two-byte codepoint...skip past surrogate pair lower byte.
+						int p1=p>>>6, p2=p1>>>6, p3=p2>>>6;
+						appendHex(p3+240).appendHex((p2&63)+128).appendHex((p1&63)+128).appendHex((p&63)+128);
+					}
+				}
+			}
+		}
+		if (needsQuotes)
+			append('\'');
+
+		return this;
+	}
+
+	/**
+	 * Appends a boolean value to the output.
+	 *
+	 * @param o The boolean value to append to the output.
+	 * @return This object (for method chaining).
+	 * @throws IOException
+	 */
+	protected UonWriter appendBoolean(Object o) throws IOException {
+		append(o.toString());
+		return this;
+	}
+
+	/**
+	 * Appends a numeric value to the output.
+	 *
+	 * @param o The numeric value to append to the output.
+	 * @return This object (for method chaining).
+	 * @throws IOException
+	 */
+	protected UonWriter appendNumber(Object o) throws IOException {
+		append(o.toString());
+		return this;
+	}
+
+	/**
+	 * Prints out a two-byte %xx sequence for the given byte value.
+	 */
+	private UonWriter appendHex(int b) throws IOException {
+		if (b > 255)
+			throw new IOException("Invalid value passed to appendHex.  Must be in the range 0-255.  Value=" + b);
+		append('%').append(hexArray[b>>>4]).append(hexArray[b&0x0F]);
+		return this;
+	}
+
+	/**
+	 * Appends a URI to the output.
+	 *
+	 * @param uri The URI to append to the output.
+	 * @return This object (for method chaining).
+	 * @throws IOException
+	 */
+	@Override
+	public SerializerWriter appendUri(Object uri) throws IOException {
+		String s = uri.toString();
+		if (s.indexOf("://") == -1) {
+			if (StringUtils.startsWith(s, '/')) {
+				if (absolutePathUriBase != null)
+					append(absolutePathUriBase);
+			} else {
+				if (relativeUriBase != null) {
+					append(relativeUriBase);
+					if (! relativeUriBase.equals("/"))
+						append("/");
+				}
+			}
+		}
+		return appendObject(s, false);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Overridden methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerWriter */
+	public UonWriter cr(int depth) throws IOException {
+		super.cr(depth);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter appendln(int indent, String text) throws IOException {
+		super.appendln(indent, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter appendln(String text) throws IOException {
+		super.appendln(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter append(int indent, String text) throws IOException {
+		super.append(indent, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter append(int indent, char c) throws IOException {
+		super.append(indent, c);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter q() throws IOException {
+		super.q();
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter i(int indent) throws IOException {
+		super.i(indent);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter nl() throws IOException {
+		super.nl();
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter append(Object text) throws IOException {
+		super.append(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter append(String text) throws IOException {
+		super.append(text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter appendIf(boolean b, String text) throws IOException {
+		super.appendIf(b, text);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter appendIf(boolean b, char c) throws IOException {
+		super.appendIf(b, c);
+		return this;
+	}
+
+	@Override /* SerializerWriter */
+	public UonWriter append(char c) throws IOException {
+		super.append(c);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/Example_HTML.png
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/Example_HTML.png b/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/Example_HTML.png
new file mode 100644
index 0000000..04dcf41
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/Example_HTML.png differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/rfc_uon.txt
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/rfc_uon.txt b/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/rfc_uon.txt
new file mode 100644
index 0000000..7880064
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/doc-files/rfc_uon.txt
@@ -0,0 +1,294 @@
+Network Working Group                                          J. Bognar
+Request for Comments: 9999                                                
+Category: Informational                                       Salesforce
+                                                                Feb 2017
+
+                            ***DRAFT***
+               URI Object Notation (UON): Generic Syntax
+
+
+About this document
+
+   This memo provides information for the Internet community.  It does
+   not specify an Internet standard of any kind.  Distribution of this
+   memo is unlimited.
+
+Copyright Notice
+
+  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.
+
+Abstract
+
+   This document describes a grammar that builds upon RFC2396
+   (Uniform Resource Identifiers).  Its purpose is to define a 
+   generalized object notation for URI query parameter values similar in 
+   concept to Javascript Object Notation (RFC4627).  The goal is a 
+   syntax that allows for array and map structures to be
+   such that any data structure defined in JSON can be losslessly 
+   defined in an equivalent URI-based grammar, yet be fully compliant 
+   with the RFC2396 specification. 
+
+   This grammar provides the ability to construct the following data 
+   structures in URL parameter values: 
+	
+      OBJECT
+      ARRAY
+      NUMBER
+      BOOLEAN
+      STRING
+      NULL
+
+   Example:
+
+      The following shows a sample object defined in Javascript:
+
+         var x = { 
+            id: 1, 
+            name: 'John Smith', 
+            uri: 'http://sample/addressBook/person/1', 
+            addressBookUri: 'http://sample/addressBook', 
+            birthDate: '1946-08-12T00:00:00Z', 
+            otherIds: null,
+            addresses: [ 
+               { 
+                  uri: 'http://sample/addressBook/address/1', 
+                  personUri: 'http://sample/addressBook/person/1', 
+                  id: 1, 
+                  street: '100 Main Street', 
+                  city: 'Anywhereville', 
+                  state: 'NY', 
+                  zip: 12345, 
+                  isCurrent: true,
+               } 
+            ] 
+         } 
+
+      Using the syntax defined in this document, the equivalent 
+      UON notation would be as follows:
+
+         x=(id=1,name='John+Smith',uri=http://sample/
+         addressBook/person/1,addressBookUri=http://sample/
+         addressBook,birthDate=1946-08-12T00:00:00Z,otherIds=null,
+         addresses=@((uri=http://sample/addressBook/
+         address/1,personUri=http://sample/addressBook/
+         person/1,id=1,street='100+Main+Street',city=
+         Anywhereville,state=NY,zip=12345,isCurrent=true))) 
+
+1. Language constraints
+
+   The grammar syntax is constrained to usage of characters allowed by 
+      URI notation:
+
+      uric       = reserved | unreserved | escaped
+      reserved   = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
+                   "$" | ","
+      unreserved = alphanum | mark
+      mark       = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
+
+   In particular, the URI specification disallows the following 
+   characters in unencoded form:
+
+      unwise     = "{" | "}" | "|" | "\" | "^" | "[" | "]" | "`"
+      delims     = "<" | ">" | "#" | "%" | <">
+
+   The exclusion of {} and [] characters eliminates the possibility of 
+   using JSON as parameter values.
+
+
+2. Grammar constructs
+
+   The grammar consists of the following language constructs:
+   
+      Objects - Values consisting of one or more child name/value pairs.
+      Arrays - Values consisting of zero or more child values.
+      Booleans - Values consisting of true/false values.
+      Numbers - Decimal and floating point values.
+      Strings - Everything else.
+
+2.1. Objects 
+
+   Objects are values consisting of one or more child name/value pairs.
+   The (...) construct is used to define an object.
+
+   Example:  A simple map with two key/value pairs:
+
+      a1=(b1=x1,b2=x2)
+
+   Example:  A nested map:
+   
+      a1=(b1=(c1=x1,c2=x2))
+
+2.2. Arrays
+
+   Arrays are values consisting of zero or more child values.
+   The @(...) construct is used to define an array.
+
+   Example:  An array of two string values:
+
+      a1=@(x1,x2)
+
+   Example:  A 2-dimensional array:
+
+      a1=@(@(x1,x2),@(x3,x4))
+
+   Example:  An array of objects:
+
+      a1=@((b1=x1,b2=x2),(c1=x1,c2=x2))
+
+2.3. Booleans
+
+   Booleans are values that can only take on values "true" or "false".  
+   
+   Example:  Two boolean values:
+
+      a1=true&a2=false
+   
+2.4. Numbers
+
+   Numbers are represented without constructs.
+   Both decimal and float numbers are supported.
+   
+   Example:  Two numerical values, one decimal and one float:
+
+      a1=123&a2=1.23e1
+
+2.5. Null values
+
+   Nulls are represented by the keyword 'null':
+
+      a1=null
+
+2.6. Strings
+
+   Strings are encapsulated in single quote (') characters.
+   
+   Example:  Simple string values:
+
+      a1='foobar'&a2='123'&a3='true'
+         
+   The quotes are optional when the string cannot be confused
+   with one of the constructs listed above (i.e. objects/arrays/
+   booleans/numbers/null). 
+   
+   Example:  A simple string value, unquoted:
+
+      a1=foobar
+    
+   Strings must be quoted for the following cases:
+      
+      - The string can be confused with a boolean or number.
+      - The string is empty.
+      - The string contains one or more whitespace characters.
+      - The string starts with one of the following characters:
+        @ (
+      - The string contains any of the following characters:
+        ) , =
+   
+   For example, the string literal "(b1=x)" should be 
+   represented as follows:
+
+      a1='(b1=x)'
+   
+   The tilde character (~) is used for escaping characters to prevent 
+   them from being confused with syntax characters.  
+
+   The following characters must be escaped in string literals:  
+
+      ' ~
+   
+   Example:  The string "foo'bar~baz"
+
+      a1='foo~'bar~~baz'
+   
+2.7. Top-level attribute names
+
+   Top-level attribute names (e.g. "a1" in "&a1=foobar") are treated
+   as strings but for one exception.  The '=' character must be
+   encoded so as not to be confused as a key/value separator.
+   Note that the '=' character must also be escaped per the UON
+   notation.
+   
+   For example, the UON equivalent of {"a=b":"a=b"} constructed as
+   a top-level query parameter string would be as follows:
+   
+      a~%3Db=a~=b
+      
+   Note that the '=' character is encoded in the attribute name,
+   but it is not necessary to have it encoded in the attribute value.
+
+2.8. URL-encoded characters
+
+   UON notation allows for any character, even UON grammar
+   characters, to be URL-encoded.
+   
+   The following query strings are fully equivalent in structure:
+   
+     a1=(b1='x1',b2='x2')
+     %61%31=%79%6f%75%20%61%72%65%20%61%20%6e%65%72%64%21
+
+
+3. BNF
+
+   The following BNF describes the syntax for top-level URI query 
+   parameter values (e.g. ?<attrname>=<value>).
+
+   attrname    = (string | null)
+   value       = (var | string | null)
+
+   string      = ("'" litchar* "'") | litchar*
+   null        = "null"
+   
+   var         = ovar | avar | nvar | boolean | number
+   ovar        = "(" [pairs] ")"
+   avar        = "@(" [values] ")"
+
+   pairs       = pair ["," pairs]
+   pair        = key "=" value	
+   values      = value ["," values]
+   key         = (string | null)
+   boolean     = "true" | "false"
+
+   escape_seq  = "~" escaped
+   encode_seq  = "%" digithex digithex
+
+   number      = [-] (decimal | float) [exp]
+   decimal     = "0" | (digit19 digit*)
+   float       = decimal "." digit+
+   exp         = "e" [("+" | "-")] digit+
+
+   litchar     = unencoded | encode_seq | escape_seq
+   escaped     = "@" | "," | "(" | ")" | "~" | "=" 
+   unencoded   = alpha | digit | 
+                 ";" | "/" | "?" | ":" | "@" |
+                 "-" | "_" | "." | "!" | "*" | "'" 
+   alpha       = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
+                 "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
+                 "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" |
+                 "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |             
+                 "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
+                 "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
+   digit       = "0" | digit19
+   digit19     = "1" | "2" | "3" | "4" | "5" | "6" | "7" |
+                 "8" | "9"
+   digithex    = digit | 
+                 "A" | "B" | "C" | "D" | "E" | "F" |
+                 "a" | "b" | "c" | "d" | "e" | "f"
+
+
+
+



[32/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
index 0b328db..a254525 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanMapTest.java
@@ -22,6 +22,7 @@ import org.apache.juneau.html.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transforms.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.utils.*;
 import org.apache.juneau.xml.*;
@@ -30,11 +31,11 @@ import org.junit.*;
 @SuppressWarnings({"unchecked","rawtypes","serial","javadoc"})
 public class BeanMapTest {
 
-	JsonSerializer serializer = JsonSerializer.DEFAULT_LAX.clone();
+	JsonSerializer serializer = JsonSerializer.DEFAULT_LAX;
 
-	BeanContext bc = ContextFactory.create()
-			.addToBeanDictionary(MyBeanDictionaryMap.class)
-			.addPojoSwaps(CalendarSwap.ISO8601DTZ.class)
+	BeanContext bc = PropertyStore.create()
+			.setBeanDictionary(MyBeanDictionaryMap.class)
+			.setPojoSwaps(CalendarSwap.ISO8601DTZ.class)
 			.getBeanContext();
 	BeanSession session = bc.createSession();
 
@@ -478,7 +479,7 @@ public class BeanMapTest {
 		m.put("b", new D2());
 		assertEquals("default", t.b.s);
 
-		JsonParser p = new JsonParser().addToBeanDictionary(D2.class);
+		JsonParser p = new JsonParserBuilder().beanDictionary(D2.class).build();
 		m.put("lb1", new ObjectList("[{_type:'D2',s:'foobar'}]", p));
 		assertEquals(ObjectList.class.getName(), t.lb1.getClass().getName());
 		assertEquals(D2.class.getName(), t.lb1.get(0).getClass().getName());
@@ -664,7 +665,7 @@ public class BeanMapTest {
 		assertEquals(HEnum.THREE, t7.getEnum2());
 
 		// Create instance directly from JSON.
-		JsonParser p = new JsonParser().addToBeanDictionary(H.class);
+		JsonParser p = new JsonParserBuilder().beanDictionary(H.class).build();
 		t7 = (H)p.parse("{_type:'H',enum1:'THREE',enum2:'ONE'}", Object.class);
 		assertEquals("{_type:'H',enum1:'THREE',enum2:'ONE'}", serializer.serialize(t7));
 		assertEquals(HEnum.THREE, t7.enum1);
@@ -956,7 +957,7 @@ public class BeanMapTest {
 
 		// JSON
 		String json = "{baz:789,foo:123,bar:456}";
-		p = new JsonParser().setIgnoreUnknownBeanProperties(true);
+		p = new JsonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		t = p.parse(json, O.class);
 		assertEquals(123, t.foo);
 
@@ -970,7 +971,7 @@ public class BeanMapTest {
 
 		// XML
 		String xml = "<object><baz type='number'>789</baz><foo type='number'>123</foo><bar type='number'>456</bar></object>";
-		p = new XmlParser().setIgnoreUnknownBeanProperties(true);
+		p = new XmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		t = p.parse(xml, O.class);
 		assertEquals(123, t.foo);
 
@@ -984,7 +985,7 @@ public class BeanMapTest {
 
 		// HTML
 		String html = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>baz</string></td><td><number>789</number></td></tr><tr><td><string>foo</string></td><td><number>123</number></td></tr><tr><td><string>bar</string></td><td><number>456</number></td></tr></table>";
-		p = new HtmlParser().setIgnoreUnknownBeanProperties(true);
+		p = new HtmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		t = p.parse(html, O.class);
 		assertEquals(123, t.foo);
 
@@ -998,12 +999,12 @@ public class BeanMapTest {
 
 		// UON
 		String uon = "(baz=789,foo=123,bar=456)";
-		p = new UonParser().setIgnoreUnknownBeanProperties(true);
+		p = new UonParserBuilder().ignoreUnknownBeanProperties(true).build();
 		t = p.parse(uon, O.class);
 		assertEquals(123, t.foo);
 
 		try {
-			p = new UonParser();
+			p = UonParser.DEFAULT;
 			t = p.parse(json, O.class);
 			fail("Expected exception never occurred");
 		} catch (Exception e) {
@@ -1012,12 +1013,12 @@ public class BeanMapTest {
 
 		// URL-Encoding
 		String urlencoding = "baz=789&foo=123&bar=456";
-		p = new UrlEncodingParser().setIgnoreUnknownBeanProperties(true);
+		p = new UrlEncodingParserBuilder().ignoreUnknownBeanProperties(true).build();
 		t = p.parse(urlencoding, O.class);
 		assertEquals(123, t.foo);
 
 		try {
-			p = new UrlEncodingParser();
+			p = UrlEncodingParser.DEFAULT;
 			t = p.parse(json, O.class);
 			fail("Expected exception never occurred");
 		} catch (Exception e) {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
index 10a02a9..e01e5d5 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ClassMetaTest.java
@@ -115,7 +115,7 @@ public class ClassMetaTest {
 		BeanContext bc;
 		ClassMeta<?> ooo, hi1, hc1, hi2, hc2;
 
-		bc = ContextFactory.create().getBeanContext();
+		bc = PropertyStore.create().getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -137,7 +137,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), HC2.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HI1Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HI1Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -159,7 +159,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HC1Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HC1Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -181,7 +181,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HI2Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HI2Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -203,7 +203,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HC2Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HC2Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -225,7 +225,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), HI2.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HI1Swap.class,HC1Swap.class,HI2Swap.class,HC2Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HI1Swap.class,HC1Swap.class,HI2Swap.class,HC2Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);
@@ -247,7 +247,7 @@ public class ClassMetaTest {
 		assertEquals(hi2.getSerializedClassMeta().getInnerClass(), Map.class);
 		assertEquals(hc2.getSerializedClassMeta().getInnerClass(), Map.class);
 
-		bc = ContextFactory.create().addPojoSwaps(HC2Swap.class,HI2Swap.class,HC1Swap.class,HI1Swap.class).getBeanContext();
+		bc = PropertyStore.create().setPojoSwaps(HC2Swap.class,HI2Swap.class,HC1Swap.class,HI1Swap.class).getBeanContext();
 		ooo = bc.getClassMeta(Object.class);
 		hi1 = bc.getClassMeta(HI1.class);
 		hc1 = bc.getClassMeta(HC1.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/ComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ComboTest.java
index cb4b935..4b89c8e 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/ComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ComboTest.java
@@ -12,37 +12,22 @@
 // ***************************************************************************************************************************
 package org.apache.juneau;
 
-import static org.junit.Assert.assertEquals;
+import static org.apache.juneau.jena.Constants.*;
+import static org.junit.Assert.*;
 
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.IdentityHashMap;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
-import org.apache.juneau.html.HtmlParser;
-import org.apache.juneau.html.HtmlSerializer;
-import org.apache.juneau.jena.RdfParser;
-import org.apache.juneau.jena.RdfSerializer;
-import org.apache.juneau.json.JsonParser;
-import org.apache.juneau.json.JsonSerializer;
-import org.apache.juneau.msgpack.MsgPackParser;
-import org.apache.juneau.msgpack.MsgPackSerializer;
-import org.apache.juneau.parser.InputStreamParser;
-import org.apache.juneau.parser.Parser;
-import org.apache.juneau.parser.ReaderParser;
-import org.apache.juneau.serializer.OutputStreamSerializer;
-import org.apache.juneau.serializer.Serializer;
-import org.apache.juneau.serializer.WriterSerializer;
-import org.apache.juneau.urlencoding.UonParser;
-import org.apache.juneau.urlencoding.UonSerializer;
-import org.apache.juneau.urlencoding.UrlEncodingParser;
-import org.apache.juneau.urlencoding.UrlEncodingSerializer;
-import org.apache.juneau.xml.XmlParser;
-import org.apache.juneau.xml.XmlSerializer;
-import org.junit.FixMethodOrder;
-import org.junit.Test;
-import org.junit.runners.MethodSorters;
+import org.apache.juneau.html.*;
+import org.apache.juneau.jena.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.msgpack.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
+import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.xml.*;
+import org.junit.*;
+import org.junit.runners.*;
 
 /**
  * Superclass for tests that verify results against all supported content types. 
@@ -297,8 +282,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// JSON - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sJsonT = JsonSerializer.DEFAULT_LAX.clone().setBeanTypePropertyName("t");
-	ReaderParser pJsonT = JsonParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	WriterSerializer sJsonT = new JsonSerializerBuilder().simple().beanTypePropertyName("t").build();
+	ReaderParser pJsonT = new JsonParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeJsonT() throws Exception {
@@ -345,8 +330,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// XML - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sXmlT = XmlSerializer.DEFAULT_SQ.clone().setBeanTypePropertyName("t");
-	ReaderParser pXmlT = XmlParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	WriterSerializer sXmlT = new XmlSerializerBuilder().sq().beanTypePropertyName("t").build();
+	ReaderParser pXmlT = new XmlParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeXmlT() throws Exception {
@@ -409,8 +394,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// HTML - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sHtmlT = HtmlSerializer.DEFAULT_SQ.clone().setBeanTypePropertyName("t");
-	ReaderParser pHtmlT = HtmlParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	WriterSerializer sHtmlT = new HtmlSerializerBuilder().sq().beanTypePropertyName("t").build();
+	ReaderParser pHtmlT =  new HtmlParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeHtmlT() throws Exception {
@@ -457,8 +442,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// UON - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sUonT = UonSerializer.DEFAULT.clone().setBeanTypePropertyName("t");
-	ReaderParser pUonT = UonParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	WriterSerializer sUonT = new UonSerializerBuilder().beanTypePropertyName("t").build();
+	ReaderParser pUonT = new UonParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeUonT() throws Exception {
@@ -505,8 +490,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// UrlEncoding - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sUrlEncodingT = UrlEncodingSerializer.DEFAULT.clone().setBeanTypePropertyName("t");
-	ReaderParser pUrlEncodingT = UrlEncodingParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	WriterSerializer sUrlEncodingT = new UrlEncodingSerializerBuilder().beanTypePropertyName("t").build();
+	ReaderParser pUrlEncodingT = new UrlEncodingParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeUrlEncodingT() throws Exception {
@@ -558,8 +543,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// MsgPack - 't' property
 	//--------------------------------------------------------------------------------
-	OutputStreamSerializer sMsgPackT = MsgPackSerializer.DEFAULT.clone().setBeanTypePropertyName("t");
-	InputStreamParser pMsgPackT = MsgPackParser.DEFAULT.clone().setBeanTypePropertyName("t");
+	OutputStreamSerializer sMsgPackT = new MsgPackSerializerBuilder().beanTypePropertyName("t").build();
+	InputStreamParser pMsgPackT = new MsgPackParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeMsgPackT() throws Exception {
@@ -595,8 +580,8 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// RdfXml - 't' property
 	//--------------------------------------------------------------------------------
-	WriterSerializer sRdfXmlT = RdfSerializer.DEFAULT_XMLABBREV.clone().setBeanTypePropertyName("t");
-	ReaderParser pRdfXmlT = RdfParser.DEFAULT_XML.clone().setBeanTypePropertyName("t");
+	WriterSerializer sRdfXmlT = new RdfSerializerBuilder().language(LANG_RDF_XML_ABBREV).beanTypePropertyName("t").build();
+	ReaderParser pRdfXmlT = new RdfParserBuilder().beanTypePropertyName("t").build();
 	
 	@Test
 	public void serializeRdfXmlT() throws Exception {
@@ -611,7 +596,7 @@ public abstract class ComboTest {
 	//--------------------------------------------------------------------------------
 	// RdfXml - Readable
 	//--------------------------------------------------------------------------------
-	WriterSerializer sRdfXmlR = RdfSerializer.DEFAULT_XMLABBREV.clone().setUseWhitespace(true);
+	WriterSerializer sRdfXmlR = new RdfSerializerBuilder().language(LANG_RDF_XML_ABBREV).ws().build();
 	ReaderParser pRdfXmlR = RdfParser.DEFAULT_XML;
 	
 	@Test

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/ContextFactoryTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ContextFactoryTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ContextFactoryTest.java
deleted file mode 100644
index f48b825..0000000
--- a/juneau-core-test/src/test/java/org/apache/juneau/ContextFactoryTest.java
+++ /dev/null
@@ -1,823 +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;
-
-import static org.apache.juneau.TestUtils.*;
-import static org.junit.Assert.*;
-
-import java.util.*;
-
-import org.apache.juneau.xml.*;
-import org.junit.*;
-
-
-@SuppressWarnings({"rawtypes","javadoc"})
-public class ContextFactoryTest {
-
-	//====================================================================================================
-	// testSimpleProperties()
-	//====================================================================================================
-	@Test
-	public void testSimpleProperties() {
-		ContextFactory f = ContextFactory.create();
-
-		f.setProperty("A.f1", "1");
-		f.setProperty("A.f2", "2");
-
-		assertObjectEquals("{'A.f1':'1','A.f2':'2'}", f.getPropertyMap("A").asMap());
-
-		f.setProperty("B.f3", "3");
-		f.setProperty("A.f1", String.class);
-		f.setProperty("A.f2", 4);
-
-		assertObjectEquals("{'A.f1':'java.lang.String','A.f2':4}", f.getPropertyMap("A").asMap());
-
-		f.setProperty("A.f2", null);
-		f.setProperty("A.f2", null);
-		assertObjectEquals("{'A.f1':'java.lang.String'}", f.getPropertyMap("A").asMap());
-
-		try {
-			f.setProperty(null, null);
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Invalid property name specified: 'null'", e.getMessage());
-		}
-
-		try {
-			f.addToProperty("A.f1", "foo");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot add value 'foo' (java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
-		}
-
-		try {
-			f.removeFromProperty("A.f1", "foo");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot remove value 'foo' (java.lang.String) from property 'A.f1' (SIMPLE).", e.getMessage());
-		}
-
-		try {
-			f.putToProperty("A.f1", "foo", "bar");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot put value 'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
-		}
-
-		try {
-			f.putToProperty("A.f1", "foo");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot put value 'foo' (java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
-		}
-	}
-
-	//====================================================================================================
-	// testSetProperties()
-	//====================================================================================================
-	@Test
-	public void testSetProperties() {
-		ContextFactory f = ContextFactory.create();
-		String key = "A.f1.set";
-
-		f.setProperty(key, Arrays.asList(2,3,1));
-		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
-
-		f.addToProperty(key, 0);
-		f.addToProperty(key, new int[]{4,5});
-		assertObjectEquals("[0,1,2,3,4,5]", f.getProperty(key, int[].class, null));
-		f.addToProperty(key, new HashSet<String>(Arrays.asList("6","7")));
-		assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, int[].class, null));
-		f.addToProperty(key, new int[]{4,5});
-		assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, int[].class, null));
-
-		f.removeFromProperty(key, 4);
-		f.removeFromProperty(key, new HashSet<String>(Arrays.asList("1")));
-		f.removeFromProperty(key, new String[]{"2","9"});
-		assertObjectEquals("[0,3,5,6,7]", f.getProperty(key, int[].class, null));
-		assertObjectEquals("['0','3','5','6','7']", f.getProperty(key, String[].class, null));
-
-		f.setProperty(key, Arrays.asList("foo","bar","baz"));
-		assertObjectEquals("['bar','baz','foo']", f.getProperty(key, String[].class, null));
-
-		f.setProperty(key, "[1,2,3]");
-		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
-
-		f.setProperty(key, "['1','2','3']");
-		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
-
-		try {
-			f.putToProperty("A.f1.set", "foo");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot put value 'foo' (java.lang.String) to property 'A.f1.set' (SET).", e.getMessage());
-		}
-
-		try {
-			f.putToProperty("A.f1.set", "foo", "bar");
-			fail("Exception expected");
-		} catch (Exception e) {
-			assertEquals("Cannot put value 'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1.set' (SET).", e.getMessage());
-		}
-	}
-
-	//====================================================================================================
-	// testListProperties()
-	//====================================================================================================
-	@Test
-	public void testListProperties() {
-		ContextFactory f = ContextFactory.create();
-		String key = "A.f1.list";
-
-		f.setProperty(key, Arrays.asList(2,3,1));
-		assertObjectEquals("[2,3,1]", f.getProperty(key, int[].class, null));
-
-		f.addToProperty(key, 0);
-		f.addToProperty(key, new int[]{4,5});
-		assertObjectEquals("[4,5,0,2,3,1]", f.getProperty(key, int[].class, null));
-		f.addToProperty(key, new TreeSet<String>(Arrays.asList("6","7")));
-		assertObjectEquals("[6,7,4,5,0,2,3,1]", f.getProperty(key, int[].class, null));
-		f.addToProperty(key, new int[]{4,5});
-		assertObjectEquals("[4,5,6,7,0,2,3,1]", f.getProperty(key, int[].class, null));
-
-		f.removeFromProperty(key, 4);
-		f.removeFromProperty(key, new HashSet<String>(Arrays.asList("1")));
-		f.removeFromProperty(key, new String[]{"2","9"});
-		assertObjectEquals("[5,6,7,0,3]", f.getProperty(key, int[].class, null));
-		assertObjectEquals("['5','6','7','0','3']", f.getProperty(key, String[].class, null));
-
-		f.setProperty(key, Arrays.asList("foo","bar","baz"));
-		assertObjectEquals("['foo','bar','baz']", f.getProperty(key, String[].class, null));
-	}
-
-	//====================================================================================================
-	// testMapProperties()
-	//====================================================================================================
-	@SuppressWarnings("serial")
-	@Test
-	public void testMapProperties() {
-		ContextFactory f = ContextFactory.create();
-		String key = "A.f1.map";
-
-		f.setProperty(key, new HashMap<String,String>(){{put("1","1");put("3","3");put("2","2");}});
-		assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, Integer.class, Integer.class, null));
-
-		f.setProperty(key, "{'1':1,'2':2,'3':3}");
-		assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, Integer.class, Integer.class, null));
-
-		f.putToProperty(key, "{'3':4,'4':5,'5':6}");
-		assertObjectEquals("{'1':1,'2':2,'3':4,'4':5,'5':6}", f.getMap(key, Integer.class, Integer.class, null));
-	}
-
-	//====================================================================================================
-	// Hash code and comparison
-	//====================================================================================================
-	@SuppressWarnings({ "serial" })
-	@Test
-	public void testHashCodes() throws Exception {
-		ContextFactory f1 = ContextFactory.create();
-		f1.setProperty("A.a", 1);
-		f1.setProperty("A.b", true);
-		f1.setProperty("A.c", String.class);
-		f1.setProperty("A.d.set", new Object[]{1, true, String.class});
-		f1.setProperty("A.e.map", new HashMap<Object,Object>(){{put(true,true);put(1,1);put(String.class,String.class);}});
-
-		ContextFactory f2 = ContextFactory.create();
-		f2.setProperty("A.e.map", new HashMap<Object,Object>(){{put("1","1");put("true","true");put("java.lang.String","java.lang.String");}});
-		f2.setProperty("A.d.set", new Object[]{"true","1","java.lang.String"});
-		f2.setProperty("A.c", "java.lang.String");
-		f2.setProperty("A.b", "true");
-		f2.setProperty("A.a", "1");
-
-		ContextFactory.PropertyMap p1 = f1.getPropertyMap("A");
-		ContextFactory.PropertyMap p2 = f2.getPropertyMap("A");
-		assertEquals(p1.hashCode(), p2.hashCode());
-	}
-
-	@SuppressWarnings("unchecked")
-	private static class ConversionTest {
-		ContextFactory config = ContextFactory.create();
-		String pName;
-		Object in;
-
-		private ConversionTest(String pName, Object in) {
-			this.pName = pName;
-			this.in = in;
-		}
-
-		private ConversionTest test(Class c, String expected) {
-			try {
-				config.setProperty(pName, in);
-				assertObjectEquals(expected, config.getProperty(pName, c, null));
-			} catch (Exception x) {
-				assertEquals(expected.toString(), x.getLocalizedMessage());
-			}
-			return this;
-		}
-
-		private ConversionTest testMap(Class k, Class v, String expected) {
-			try {
-				config.setProperty(pName, in);
-				assertObjectEquals(expected, config.getMap(pName, k, v, null));
-			} catch (Exception x) {
-				assertEquals(expected, x.getLocalizedMessage());
-			}
-			return this;
-		}
-	}
-
-	//====================================================================================================
-	// Conversions on simple properties
-	//====================================================================================================
-	@Test
-	@SuppressWarnings({ "serial" })
-	public void testConversionsOnSimpleProperties() throws Exception {
-		String pName = "A.a";
-
-		//--------------------------------------------------------------------------------
-		// boolean
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, true)
-			.test(boolean.class, "true")
-			.test(int.class, "1")
-			.test(String.class, "'true'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class'.  Value=true.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=true.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.String[]'.  Value=true.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class[]'.  Value=true.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=true.")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=true.")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=true.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// int
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, 123)
-			.test(boolean.class, "true")
-			.test(int.class, "123")
-			.test(String.class, "'123'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class'.  Value=123.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=123.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.String[]'.  Value=123.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class[]'.  Value=123.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=123.")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=123.")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=123.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, String.class)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'int'.  Value='java.lang.String'.")
-			.test(String.class, "'java.lang.String'")
-			.test(Class.class, "'java.lang.String'")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value='java.lang.String'.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.String[]'.  Value='java.lang.String'.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.Class[]'.  Value='java.lang.String'.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value='java.lang.String'.")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='java.lang.String'.")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='java.lang.String'.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, "foo")
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'int'.  Value='foo'.")
-			.test(String.class, "'foo'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class'.  Value='foo'.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value='foo'.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.String[]'.  Value='foo'.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class[]'.  Value='foo'.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value='foo'.")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='foo'.")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='foo'.")
-		;
-		new ConversionTest(pName, "java.lang.String")
-			.test(Class.class, "'java.lang.String'")
-		;
-		new ConversionTest(pName, "true")
-			.test(boolean.class, "true")
-		;
-		new ConversionTest(pName, "ONE")
-			.test(TestEnum.class, "'ONE'")
-		;
-		new ConversionTest(pName, "123")
-			.test(int.class, "123")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, TestEnum.ONE)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'int'.  Value='ONE'.")
-			.test(String.class, "'ONE'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'java.lang.Class'.  Value='ONE'.")
-			.test(TestEnum.class, "'ONE'")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'java.lang.String[]'.  Value='ONE'.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'java.lang.Class[]'.  Value='ONE'.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value='ONE'.")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='ONE'.")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='ONE'.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new String[]{"foo","bar"})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'int'.  Value=['foo','bar'].")
-			.test(String.class, "'[\\'foo\\',\\'bar\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.lang.Class'.  Value=['foo','bar'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['foo','bar'].")
-			.test(String[].class, "['foo','bar']")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.lang.Class[]'.  Value=['foo','bar'].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['foo','bar'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['foo','bar'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['foo','bar'].")
-		;
-		new ConversionTest(pName, new String[]{"ONE","TWO"})
-			.test(TestEnum[].class, "['ONE','TWO']")
-		;
-		new ConversionTest(pName, new String[]{"true","false"})
-			.test(boolean[].class, "[true,false]")
-		;
-		new ConversionTest(pName, new String[]{"java.lang.String","java.lang.Integer"})
-			.test(Class[].class, "['java.lang.String','java.lang.Integer']")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Class[]{String.class,Integer.class})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'int'.  Value=['java.lang.String','java.lang.Integer'].")
-			.test(String.class, "'[\\'java.lang.String\\',\\'java.lang.Integer\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.lang.Class'.  Value=['java.lang.String','java.lang.Integer'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['java.lang.String','java.lang.Integer'].")
-			.test(String[].class, "['java.lang.String','java.lang.Integer']")
-			.test(Class[].class, "['java.lang.String','java.lang.Integer']")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['java.lang.String','java.lang.Integer'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.String','java.lang.Integer'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.String','java.lang.Integer'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'int'.  Value=['ONE','TWO'].")
-			.test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'java.lang.Class'.  Value=['ONE','TWO'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['ONE','TWO'].")
-			.test(String[].class, "['ONE','TWO']")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'java.lang.Class[]'.  Value=['ONE','TWO'].")
-			.test(TestEnum[].class, "['ONE','TWO']")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE','TWO'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.ContextFactoryTest$TestEnum[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE','TWO'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<String,String>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
-		m1.put("foo","bar");
-		new ConversionTest(pName, m1)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'int'.  Value={foo:'bar'}.")
-			.test(String.class, "'{foo:\\'bar\\'}'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value={foo:'bar'}.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value={foo:'bar'}.")
-			.testMap(String.class, String.class, "{foo:'bar'}")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value={foo:'bar'}.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<Class,Class>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
-		m2.put(String.class, Integer.class);
-		new ConversionTest(pName, m2)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'int'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
-			.test(Class.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(Class[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")
-			.testMap(Class.class, Class.class, "{'java.lang.String':'java.lang.Integer'}")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Namespace
-		//--------------------------------------------------------------------------------
-		final Namespace n = new Namespace("foo","bar");
-		new ConversionTest(pName, n)
-			.test(String.class, "'{name:\\'foo\\',uri:\\'bar\\'}'")
-			.test(Namespace.class, "{name:'foo',uri:'bar'}");
-
-		//--------------------------------------------------------------------------------
-		// Namespace[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Namespace[]{n})
-			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
-			.test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
-
-		//--------------------------------------------------------------------------------
-		// Map<Namespace,Namespace>
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
-			.testMap(Namespace.class, Namespace.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
-			.testMap(String.class, String.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
-	}
-
-	//====================================================================================================
-	// Conversions on set properties
-	//====================================================================================================
-	@Test
-	@SuppressWarnings({ "serial" })
-	public void testConversionsOnSetProperties() throws Exception {
-		String pName = "A.a.set";
-
-		//--------------------------------------------------------------------------------
-		// boolean
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, true)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[true].")
-			.test(String.class, "'[true]'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[true].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=[true].")
-			.test(String[].class, "['true']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[true].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=[true].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[true].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[true].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// int
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, 123)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[123].")
-			.test(String.class, "'[123]'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[123].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=[123].")
-			.test(String[].class, "['123']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[123].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=[123].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[123].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[123].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, String.class)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['java.lang.String'].")
-			.test(String.class, "'[\\'java.lang.String\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['java.lang.String'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['java.lang.String'].")
-			.test(String[].class, "['java.lang.String']")
-			.test(Class[].class, "['java.lang.String']")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['java.lang.String'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.String'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.String'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, "foo")
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['foo'].")
-			.test(String.class, "'[\\'foo\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['foo'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['foo'].")
-			.test(String[].class, "['foo']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['foo'].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['foo'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['foo'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['foo'].")
-		;
-		new ConversionTest(pName, Arrays.asList("java.lang.String"))
-			.test(Class[].class, "['java.lang.String']")
-		;
-		new ConversionTest(pName, Arrays.asList("true"))
-			.test(boolean[].class, "[true]")
-		;
-		new ConversionTest(pName, Arrays.asList("ONE"))
-			.test(TestEnum[].class, "['ONE']")
-		;
-		new ConversionTest(pName, Arrays.asList("123"))
-			.test(int[].class, "[123]")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, TestEnum.ONE)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['ONE'].")
-			.test(String.class, "'[\\'ONE\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['ONE'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['ONE'].")
-			.test(String[].class, "['ONE']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['ONE'].")
-			.test(TestEnum[].class, "['ONE']")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new String[]{"foo","bar"})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['bar','foo'].")
-			.test(String.class, "'[\\'bar\\',\\'foo\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['bar','foo'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['bar','foo'].")
-			.test(String[].class, "['bar','foo']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['bar','foo'].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['bar','foo'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['bar','foo'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['bar','foo'].")
-		;
-		new ConversionTest(pName, new String[]{"ONE","TWO"})
-			.test(TestEnum[].class, "['ONE','TWO']")
-		;
-		new ConversionTest(pName, new String[]{"true","false"})
-			.test(boolean[].class, "[false,true]")
-		;
-		new ConversionTest(pName, new String[]{"java.lang.String","java.lang.Integer"})
-			.test(Class[].class, "['java.lang.Integer','java.lang.String']")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Class[]{String.class,Integer.class})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['java.lang.Integer','java.lang.String'].")
-			.test(String.class, "'[\\'java.lang.Integer\\',\\'java.lang.String\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['java.lang.Integer','java.lang.String'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['java.lang.Integer','java.lang.String'].")
-			.test(String[].class, "['java.lang.Integer','java.lang.String']")
-			.test(Class[].class, "['java.lang.Integer','java.lang.String']")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=['java.lang.Integer','java.lang.String'].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.Integer','java.lang.String'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.Integer','java.lang.String'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['ONE','TWO'].")
-			.test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['ONE','TWO'].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=['ONE','TWO'].")
-			.test(String[].class, "['ONE','TWO']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['ONE','TWO'].")
-			.test(TestEnum[].class, "['ONE','TWO']")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE','TWO'].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE','TWO'].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<String,String>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
-		m1.put("foo","bar");
-		new ConversionTest(pName, m1)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[{foo:'bar'}].")
-			.test(String.class, "'[{foo:\\'bar\\'}]'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[{foo:'bar'}].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=[{foo:'bar'}].")
-			.test(String[].class, "['{foo:\\'bar\\'}']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[{foo:'bar'}].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=[{foo:'bar'}].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{foo:'bar'}].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[{foo:'bar'}].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<Class,Class>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
-		m2.put(String.class, Integer.class);
-		new ConversionTest(pName, m2)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.test(String.class, "'[{\\'java.lang.String\\':\\'java.lang.Integer\\'}]'")
-			.test(Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.test(String[].class, "['{\\'java.lang.String\\':\\'java.lang.Integer\\'}']")
-			.test(Class[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Namespace
-		//--------------------------------------------------------------------------------
-		final Namespace n = new Namespace("foo","bar");
-		new ConversionTest(pName, Arrays.asList(n))
-			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
-			.test(Namespace.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.xml.Namespace'.  Value=[{name:'foo',uri:'bar'}].");
-
-		//--------------------------------------------------------------------------------
-		// Namespace[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Namespace[]{n})
-			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
-			.test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
-
-		//--------------------------------------------------------------------------------
-		// Map<Namespace,Namespace>
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
-			.testMap(Namespace.class, Namespace.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<org.apache.juneau.xml.Namespace,org.apache.juneau.xml.Namespace>'.  Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].")
-			.testMap(String.class, String.class, "Could not retrieve config property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].");
-	}
-
-
-	//====================================================================================================
-	// Conversions on map properties
-	//====================================================================================================
-	@Test
-	@SuppressWarnings({ "serial" })
-	public void testConversionsOnMapProperties() throws Exception {
-		String pName = "A.a.map";
-
-		//--------------------------------------------------------------------------------
-		// boolean
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, true)
-			.test(boolean.class, "Cannot put value true (java.lang.Boolean) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// int
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, 123)
-			.test(int.class, "Cannot put value 123 (java.lang.Integer) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, String.class)
-			.test(Class.class, "Cannot put value 'java.lang.String' (java.lang.Class) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, "foo")
-			.test(String.class, "Cannot put value 'foo' (java.lang.String) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, TestEnum.ONE)
-			.test(TestEnum.class, "Cannot put value 'ONE' (org.apache.juneau.ContextFactoryTest$TestEnum) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// String[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new String[]{"foo","bar"})
-			.test(String[].class, "Cannot put value ['foo','bar'] (java.lang.String[]) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Class[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Class[]{String.class,Integer.class})
-			.test(Class[].class, "Cannot put value ['java.lang.String','java.lang.Integer'] (java.lang.Class[]) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// enum[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
-			.test(TestEnum[].class, "Cannot put value ['ONE','TWO'] (org.apache.juneau.ContextFactoryTest$TestEnum[]) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<String,String>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
-		m1.put("foo","bar");
-		new ConversionTest(pName, m1)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'int'.  Value={foo:'bar'}.")
-			.test(String.class, "'{foo:\\'bar\\'}'")
-			.test(Class.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value={foo:'bar'}.")
-			.test(String[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
-			.test(Class[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value={foo:'bar'}.")
-			.testMap(String.class, String.class, "{foo:'bar'}")
-			.testMap(Class.class, Class.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value={foo:'bar'}.")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<Class,Class>
-		//--------------------------------------------------------------------------------
-		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
-		m2.put(String.class, Integer.class);
-		new ConversionTest(pName, m2)
-			.test(boolean.class, "false")
-			.test(int.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'int'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
-			.test(Class.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(TestEnum.class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(String[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(Class[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.test(TestEnum[].class, "Could not retrieve config property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.ContextFactoryTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
-			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")
-			.testMap(Class.class, Class.class, "{'java.lang.String':'java.lang.Integer'}")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Namespace
-		//--------------------------------------------------------------------------------
-		final Namespace n = new Namespace("foo","bar");
-		new ConversionTest(pName, Arrays.asList(n))
-			.test(String.class, "Cannot put value [{name:'foo',uri:'bar'}] (java.util.Arrays$ArrayList) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Namespace[]
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new Namespace[]{n})
-			.test(String.class, "Cannot put value [{name:'foo',uri:'bar'}] (org.apache.juneau.xml.Namespace[]) to property 'A.a.map' (MAP).")
-		;
-
-		//--------------------------------------------------------------------------------
-		// Map<Namespace,Namespace>
-		//--------------------------------------------------------------------------------
-		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
-			.testMap(Namespace.class, Namespace.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
-			.testMap(String.class, String.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
-	}
-
-	public enum TestEnum {
-		ONE,TWO,TREE;
-	}
-
-	//====================================================================================================
-	// testSystemPropertyDefaults()
-	//====================================================================================================
-	@Test
-	public void testSystemPropertyDefaults() {
-		System.setProperty("Foo.f1", "true");
-		System.setProperty("Foo.f2", "123");
-		System.setProperty("Foo.f3", "TWO");
-
-		ContextFactory f = ContextFactory.create();
-
-		assertObjectEquals("true", f.getProperty("Foo.f1", boolean.class, false));
-		assertObjectEquals("123", f.getProperty("Foo.f2", int.class, 0));
-		assertObjectEquals("'TWO'", f.getProperty("Foo.f3", TestEnum.class, TestEnum.ONE));
-
-		f.setProperty("Foo.f1", false);
-		f.setProperty("Foo.f2", 456);
-		f.setProperty("Foo.f3", TestEnum.TREE);
-
-		assertObjectEquals("false", f.getProperty("Foo.f1", boolean.class, false));
-		assertObjectEquals("456", f.getProperty("Foo.f2", int.class, 0));
-		assertObjectEquals("'TREE'", f.getProperty("Foo.f3", TestEnum.class, TestEnum.ONE));
-	}
-
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/DataConversionTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/DataConversionTest.java b/juneau-core-test/src/test/java/org/apache/juneau/DataConversionTest.java
index d3d8ed1..be7c264 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/DataConversionTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/DataConversionTest.java
@@ -144,7 +144,7 @@ public class DataConversionTest {
 	@Test
 	public void testObjectSwaps() throws Exception {
 		String s = "Jan 12, 2001";
-		BeanSession session = ContextFactory.create().addPojoSwaps(CalendarSwap.DateMedium.class).getBeanContext().createSession();
+		BeanSession session = PropertyStore.create().setPojoSwaps(CalendarSwap.DateMedium.class).getBeanContext().createSession();
 		Calendar c = session.convertToType(s, GregorianCalendar.class);
 		assertEquals(2001, c.get(Calendar.YEAR));
 		c = session.convertToType(s, Calendar.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/IgnoredClassesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/IgnoredClassesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/IgnoredClassesTest.java
index 28674f3..e22d86d 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/IgnoredClassesTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/IgnoredClassesTest.java
@@ -41,24 +41,24 @@ public class IgnoredClassesTest {
 	@Test
 	public void testIgnorePackages() throws Exception {
 		A a = new A();
-		JsonSerializer s = new JsonSerializer.Simple();
-		assertEquals("{f1:'isBean'}", s.serialize(a));
-		s.addNotBeanPackages("org.apache.juneau");
-		assertEquals("'isNotBean'", s.serialize(a));
+		JsonSerializerBuilder s = new JsonSerializerBuilder().simple();
+		assertEquals("{f1:'isBean'}", s.build().serialize(a));
+		s.notBeanPackages("org.apache.juneau");
+		assertEquals("'isNotBean'", s.build().serialize(a));
 		s.removeNotBeanPackages("org.apache.juneau");
-		assertEquals("{f1:'isBean'}", s.serialize(a));
-		s.addNotBeanPackages("org.apache.juneau.*");
-		assertEquals("'isNotBean'", s.serialize(a));
+		assertEquals("{f1:'isBean'}", s.build().serialize(a));
+		s.notBeanPackages("org.apache.juneau.*");
+		assertEquals("'isNotBean'", s.build().serialize(a));
 		s.removeNotBeanPackages("org.apache.juneau.*");
-		assertEquals("{f1:'isBean'}", s.serialize(a));
-		s.addNotBeanPackages("org.apache.juneau.*");
-		assertEquals("'isNotBean'", s.serialize(a));
+		assertEquals("{f1:'isBean'}", s.build().serialize(a));
+		s.notBeanPackages("org.apache.juneau.*");
+		assertEquals("'isNotBean'", s.build().serialize(a));
 		s.removeNotBeanPackages("org.apache.juneau.*");
-		assertEquals("{f1:'isBean'}", s.serialize(a));
-		s.addNotBeanPackages("org.apache.juneau");
-		assertEquals("'isNotBean'", s.serialize(a));
-		s.addNotBeanPackages("org.apache.juneau.x");
-		assertEquals("'isNotBean'", s.serialize(a));
+		assertEquals("{f1:'isBean'}", s.build().serialize(a));
+		s.notBeanPackages("org.apache.juneau");
+		assertEquals("'isNotBean'", s.build().serialize(a));
+		s.notBeanPackages("org.apache.juneau.x");
+		assertEquals("'isNotBean'", s.build().serialize(a));
 	}
 
 	public static class A {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/MediaRangeTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/MediaRangeTest.java b/juneau-core-test/src/test/java/org/apache/juneau/MediaRangeTest.java
index f3fd216..882ca6a 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/MediaRangeTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/MediaRangeTest.java
@@ -12,15 +12,14 @@
 // ***************************************************************************************************************************
 package org.apache.juneau;
 
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.*;
 
-import java.util.Arrays;
-import java.util.Collection;
+import java.util.*;
 
-import org.apache.juneau.json.JsonSerializer;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
+import org.apache.juneau.json.*;
+import org.junit.*;
+import org.junit.runner.*;
+import org.junit.runners.*;
 
 /**
  * Verifies that the MediaRange and MediaType classes parse and sort Accept headers correctly.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/PojoSwapTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/PojoSwapTest.java b/juneau-core-test/src/test/java/org/apache/juneau/PojoSwapTest.java
index d9b7944..5fa73b2 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/PojoSwapTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/PojoSwapTest.java
@@ -29,8 +29,8 @@ public class PojoSwapTest {
 	//====================================================================================================
 	@Test
 	public void testSameType() throws Exception {
-		JsonSerializer s = JsonSerializer.DEFAULT_LAX.clone().addPojoSwaps(ASwap.class);
-		JsonParser p = JsonParser.DEFAULT.clone().addPojoSwaps(ASwap.class);
+		JsonSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(ASwap.class).build();
+		JsonParser p = new JsonParserBuilder().pojoSwaps(ASwap.class).build();
 		String r;
 
 		r = s.serialize("foobar");


[22/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
new file mode 100644
index 0000000..be8cc9c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserBuilder.java
@@ -0,0 +1,484 @@
+// ***************************************************************************************************************************
+// * 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.html;
+
+import java.util.*;
+
+import javax.xml.stream.*;
+import javax.xml.stream.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Builder class for building instances of HTML parsers.
+ */
+public class HtmlParserBuilder extends XmlParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public HtmlParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public HtmlParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParser build() {
+		return new HtmlParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* XmlParserBuilder */
+	public HtmlParserBuilder validating(boolean value) {
+		super.validating(value);
+		return this;
+	}
+
+	@Override /* XmlParserBuilder */
+	public HtmlParserBuilder reporter(XMLReporter value) {
+		super.reporter(value);
+		return this;
+	}
+
+	@Override /* XmlParserBuilder */
+	public HtmlParserBuilder resolver(XMLResolver value) {
+		super.resolver(value);
+		return this;
+	}
+
+	@Override /* XmlParserBuilder */
+	public HtmlParserBuilder eventAllocator(XMLEventAllocator value) {
+		super.eventAllocator(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public HtmlParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public HtmlParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public HtmlParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public HtmlParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public HtmlParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CoreObjectBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserContext.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserContext.java
index 8ea06a2..b71eae0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParserContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.xml.*;
 /**
  * Configurable properties on the {@link HtmlParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -36,12 +36,12 @@ public final class HtmlParserContext extends XmlParserContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public HtmlParserContext(ContextFactory cf) {
-		super(cf);
+	public HtmlParserContext(PropertyStore ps) {
+		super(ps);
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
index 0223623..582abcd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSchemaDocSerializer.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.html;
 
 import static org.apache.juneau.internal.ClassUtils.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -44,28 +45,36 @@ import org.apache.juneau.transform.*;
 @Produces(value="text/html+schema", contentType="text/html")
 public final class HtmlSchemaDocSerializer extends HtmlDocSerializer {
 
+	@SuppressWarnings("hiding")
+	final HtmlDocSerializerContext ctx;
+
 	/**
 	 * Constructor.
+	 * @param propertyStore The property store to use for creating the context for this serializer.
 	 */
-	public HtmlSchemaDocSerializer() {
-		setDetectRecursions(true);
-		setIgnoreRecursions(true);
+	public HtmlSchemaDocSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(HtmlDocSerializerContext.class);
 	}
 
 	/**
 	 * Constructor.
-	 *
-	 * @param cf The context factory to use for creating the context for this serializer.
+	 * @param propertyStore The property store to use for creating the context for this serializer.
+	 * @param overrideProperties
 	 */
-	public HtmlSchemaDocSerializer(ContextFactory cf) {
-		getContextFactory().copyFrom(cf);
-		setDetectRecursions(true);
-		setIgnoreRecursions(true);
+	public HtmlSchemaDocSerializer(PropertyStore propertyStore, Map<String,Object> overrideProperties) {
+		super(propertyStore);
+		this.ctx = this.propertyStore.create(overrideProperties).getContext(HtmlDocSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	protected ObjectMap getOverrideProperties() {
+		return super.getOverrideProperties().append(SERIALIZER_detectRecursions, true).append(SERIALIZER_ignoreRecursions, true);
 	}
 
 	@Override /* Serializer */
 	public HtmlDocSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new HtmlDocSerializerSession(getContext(HtmlDocSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new HtmlDocSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* ISchemaSerializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
index f66d57f..de4768e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializer.java
@@ -13,7 +13,7 @@
 package org.apache.juneau.html;
 
 import static org.apache.juneau.html.HtmlSerializer.ContentResult.*;
-import static org.apache.juneau.html.HtmlSerializerContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -71,12 +71,10 @@ import org.apache.juneau.xml.annotation.*;
  * 		String html = HtmlSerializer.<jsf>DEFAULT</jsf>.serialize(someObject);
  *
  * 		<jc>// Create a custom serializer that doesn't use whitespace and newlines</jc>
- * 		HtmlSerializer serializer = <jk>new</jk> HtmlSerializer()
- * 			.setUseIndentation(<jk>false</jk>);
+ * 		HtmlSerializer serializer = <jk>new</jk> HtmlSerializerBuider().ws().build();
  *
  * 		<jc>// Same as above, except uses cloning</jc>
- * 		HtmlSerializer serializer = HtmlSerializer.<jsf>DEFAULT</jsf>.clone()
- * 			.setUseIndentation(<jk>false</jk>);
+ * 		HtmlSerializer serializer = HtmlSerializer.<jsf>DEFAULT</jsf>.builder().ws().build();
  *
  * 		<jc>// Serialize POJOs to HTML</jc>
  *
@@ -132,30 +130,68 @@ import org.apache.juneau.xml.annotation.*;
 public class HtmlSerializer extends XmlSerializer {
 
 	/** Default serializer, all default settings. */
-	public static final HtmlSerializer DEFAULT = new HtmlSerializer().lock();
+	public static final HtmlSerializer DEFAULT = new HtmlSerializer(PropertyStore.create());
 
 	/** Default serializer, single quotes. */
-	public static final HtmlSerializer DEFAULT_SQ = new HtmlSerializer.Sq().lock();
+	public static final HtmlSerializer DEFAULT_SQ = new HtmlSerializer.Sq(PropertyStore.create());
 
 	/** Default serializer, single quotes, whitespace added. */
-	public static final HtmlSerializer DEFAULT_SQ_READABLE = new HtmlSerializer.SqReadable().lock();
+	public static final HtmlSerializer DEFAULT_SQ_READABLE = new HtmlSerializer.SqReadable(PropertyStore.create());
+
 
 	/** Default serializer, single quotes. */
 	public static class Sq extends HtmlSerializer {
-		/** Constructor */
-		public Sq() {
-			setQuoteChar('\'');
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Sq(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_quoteChar, '\'');
 		}
 	}
 
 	/** Default serializer, single quotes, whitespace added. */
-	public static class SqReadable extends Sq {
-		/** Constructor */
-		public SqReadable() {
-			setUseWhitespace(true);
+	public static class SqReadable extends HtmlSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public SqReadable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_quoteChar, '\'').append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
+
+	final HtmlSerializerContext ctx;
+	private volatile HtmlSchemaDocSerializer schemaSerializer;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public HtmlSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(HtmlSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public HtmlSerializerBuilder builder() {
+		return new HtmlSerializerBuilder(propertyStore);
+	}
+
 	/**
 	 * Main serialization routine.
 	 * @param session The serialization context object.
@@ -633,12 +669,9 @@ public class HtmlSerializer extends XmlSerializer {
 	 */
 	@Override /* XmlSerializer */
 	public HtmlSerializer getSchemaSerializer() {
-		try {
-			return new HtmlSchemaDocSerializer(getContextFactory().clone());
-		} catch (CloneNotSupportedException e) {
-			// Should never happen.
-			throw new RuntimeException(e);
-		}
+		if (schemaSerializer == null)
+			schemaSerializer = new HtmlSchemaDocSerializer(propertyStore, getOverrideProperties());
+		return schemaSerializer;
 	}
 
 
@@ -648,7 +681,7 @@ public class HtmlSerializer extends XmlSerializer {
 
 	@Override /* Serializer */
 	public HtmlSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new HtmlSerializerSession(getContext(HtmlSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new HtmlSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* Serializer */
@@ -656,632 +689,4 @@ public class HtmlSerializer extends XmlSerializer {
 		HtmlSerializerSession s = (HtmlSerializerSession)session;
 		doSerialize(s, o, s.getWriter());
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Anchor text source.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"HtmlSerializer.uriAnchorText"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"toString"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * When creating anchor tags (e.g. <code><xt>&lt;a</xt> <xa>href</xa>=<xs>'...'</xs><xt>&gt;</xt>text<xt>&lt;/a&gt;</xt></code>)
-	 * 	in HTML, this setting defines what to set the inner text to.
-	 * <p>
-	 * Possible values:
-	 * <ul class='spaced-list'>
-	 * 	<li>{@link HtmlSerializerContext#TO_STRING} / <js>"toString"</js> - Set to whatever is returned by {@link #toString()} on the object.
-	 * 	<li>{@link HtmlSerializerContext#URI} / <js>"uri"</js> - Set to the URI value.
-	 * 	<li>{@link HtmlSerializerContext#LAST_TOKEN} / <js>"lastToken"</js> - Set to the last token of the URI value.
-	 * 	<li>{@link HtmlSerializerContext#PROPERTY_NAME} / <js>"propertyName"</js> - Set to the bean property name.
-	 * 	<li>{@link HtmlSerializerContext#URI_ANCHOR} / <js>"uriAnchor"</js> - Set to the anchor of the URL.  (e.g. <js>"http://localhost:9080/foobar#anchorTextHere"</js>)
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>HTML_uriAnchorText</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see HtmlSerializerContext#HTML_uriAnchorText
-	 */
-	public HtmlSerializer setUriAnchorText(String value) throws LockedException {
-		return setProperty(HTML_uriAnchorText, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for URLs in {@link String Strings}.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"HtmlSerializer.detectLinksInStrings"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If a string looks like a URL (e.g. starts with <js>"http://"</js> or <js>"https://"</js>, then treat it like a URL
-	 * 	and make it into a hyperlink based on the rules specified by {@link HtmlSerializerContext#HTML_uriAnchorText}.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>HTML_detectLinksInStrings</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see HtmlSerializerContext#HTML_detectLinksInStrings
-	 */
-	public HtmlSerializer setDetectLinksInStrings(boolean value) throws LockedException {
-		return setProperty(HTML_detectLinksInStrings, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for link labels in the <js>"label"</js> parameter of the URL.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"HtmlSerializer.lookForLabelParameters"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If the URL has a label parameter (e.g. <js>"?label=foobar"</js>), then use that as the anchor text of the link.
-	 * <p>
-	 * The parameter name can be changed via the {@link HtmlSerializerContext#HTML_labelParameter} property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>HTML_lookForLabelParameters</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see HtmlSerializerContext#HTML_lookForLabelParameters
-	 */
-	public HtmlSerializer setLookForLabelParameters(boolean value) throws LockedException {
-		return setProperty(HTML_lookForLabelParameters, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  The parameter name to use when using {@link HtmlSerializerContext#HTML_lookForLabelParameters}.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"HtmlSerializer.labelParameter"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"label"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>HTML_labelParameter</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see HtmlSerializerContext#HTML_labelParameter
-	 */
-	public HtmlSerializer setLabelParameter(String value) throws LockedException {
-		return setProperty(HTML_labelParameter, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add key/value headers on bean/map tables.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"HtmlSerializer.addKeyValueTableHeaders"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>HTML_addKeyValueTableHeaders</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see HtmlSerializerContext#HTML_addKeyValueTableHeaders
-	 */
-	public HtmlSerializer setAddKeyValueTableHeaders(boolean value) throws LockedException {
-		return setProperty(HTML_addKeyValueTableHeaders, value);
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public HtmlSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlSerializer clone() {
-		HtmlSerializer c = (HtmlSerializer)super.clone();
-		return c;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
new file mode 100644
index 0000000..7c9a923
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerBuilder.java
@@ -0,0 +1,706 @@
+// ***************************************************************************************************************************
+// * 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.html;
+
+import static org.apache.juneau.html.HtmlSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Builder class for building instances of HTML serializers.
+ */
+public class HtmlSerializerBuilder extends XmlSerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public HtmlSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public HtmlSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializer build() {
+		return new HtmlSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Anchor text source.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"HtmlSerializer.uriAnchorText"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"toString"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * When creating anchor tags (e.g. <code><xt>&lt;a</xt> <xa>href</xa>=<xs>'...'</xs><xt>&gt;</xt>text<xt>&lt;/a&gt;</xt></code>)
+	 * 	in HTML, this setting defines what to set the inner text to.
+	 * <p>
+	 * Possible values:
+	 * <ul class='spaced-list'>
+	 * 	<li>{@link HtmlSerializerContext#TO_STRING} / <js>"toString"</js> - Set to whatever is returned by {@link #toString()} on the object.
+	 * 	<li>{@link HtmlSerializerContext#URI} / <js>"uri"</js> - Set to the URI value.
+	 * 	<li>{@link HtmlSerializerContext#LAST_TOKEN} / <js>"lastToken"</js> - Set to the last token of the URI value.
+	 * 	<li>{@link HtmlSerializerContext#PROPERTY_NAME} / <js>"propertyName"</js> - Set to the bean property name.
+	 * 	<li>{@link HtmlSerializerContext#URI_ANCHOR} / <js>"uriAnchor"</js> - Set to the anchor of the URL.  (e.g. <js>"http://localhost:9080/foobar#anchorTextHere"</js>)
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>HTML_uriAnchorText</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see HtmlSerializerContext#HTML_uriAnchorText
+	 */
+	public HtmlSerializerBuilder uriAnchorText(String value) {
+		return property(HTML_uriAnchorText, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for URLs in {@link String Strings}.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"HtmlSerializer.detectLinksInStrings"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If a string looks like a URL (e.g. starts with <js>"http://"</js> or <js>"https://"</js>, then treat it like a URL
+	 * 	and make it into a hyperlink based on the rules specified by {@link HtmlSerializerContext#HTML_uriAnchorText}.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>HTML_detectLinksInStrings</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see HtmlSerializerContext#HTML_detectLinksInStrings
+	 */
+	public HtmlSerializerBuilder detectLinksInStrings(boolean value) {
+		return property(HTML_detectLinksInStrings, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Look for link labels in the <js>"label"</js> parameter of the URL.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"HtmlSerializer.lookForLabelParameters"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If the URL has a label parameter (e.g. <js>"?label=foobar"</js>), then use that as the anchor text of the link.
+	 * <p>
+	 * The parameter name can be changed via the {@link HtmlSerializerContext#HTML_labelParameter} property.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>HTML_lookForLabelParameters</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see HtmlSerializerContext#HTML_lookForLabelParameters
+	 */
+	public HtmlSerializerBuilder lookForLabelParameters(boolean value) {
+		return property(HTML_lookForLabelParameters, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  The parameter name to use when using {@link HtmlSerializerContext#HTML_lookForLabelParameters}.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"HtmlSerializer.labelParameter"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"label"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>HTML_labelParameter</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see HtmlSerializerContext#HTML_labelParameter
+	 */
+	public HtmlSerializerBuilder labelParameter(String value) {
+		return property(HTML_labelParameter, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add key/value headers on bean/map tables.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"HtmlSerializer.addKeyValueTableHeaders"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>HTML_addKeyValueTableHeaders</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see HtmlSerializerContext#HTML_addKeyValueTableHeaders
+	 */
+	public HtmlSerializerBuilder addKeyValueTableHeaders(boolean value) {
+		return property(HTML_addKeyValueTableHeaders, value);
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder enableNamespaces(boolean value) {
+		super.enableNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder autoDetectNamespaces(boolean value) {
+		super.autoDetectNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder addNamespaceUrisToRoot(boolean value) {
+		super.addNamespaceUrisToRoot(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder defaultNamespace(String value) {
+		super.defaultNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder xsNamespace(Namespace value) {
+		super.xsNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public HtmlSerializerBuilder namespaces(Namespace...values) {
+		super.namespaces(values);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public HtmlSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> HtmlSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public HtmlSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerContext.java
index b2096c1..948ee18 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerContext.java
@@ -19,10 +19,10 @@ import org.apache.juneau.xml.*;
 /**
  * Configurable properties on the {@link HtmlSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -158,18 +158,18 @@ public class HtmlSerializerContext extends XmlSerializerContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public HtmlSerializerContext(ContextFactory cf) {
-		super(cf);
-		uriAnchorText = cf.getProperty(HTML_uriAnchorText, String.class, TO_STRING);
-		lookForLabelParameters = cf.getProperty(HTML_lookForLabelParameters, Boolean.class, true);
-		detectLinksInStrings = cf.getProperty(HTML_detectLinksInStrings, Boolean.class, true);
-		labelParameter = cf.getProperty(HTML_labelParameter, String.class, "label");
-		addKeyValueTableHeaders = cf.getProperty(HTML_addKeyValueTableHeaders, Boolean.class, false);
-		addBeanTypeProperties = cf.getProperty(HTML_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	public HtmlSerializerContext(PropertyStore ps) {
+		super(ps);
+		uriAnchorText = ps.getProperty(HTML_uriAnchorText, String.class, TO_STRING);
+		lookForLabelParameters = ps.getProperty(HTML_lookForLabelParameters, Boolean.class, true);
+		detectLinksInStrings = ps.getProperty(HTML_detectLinksInStrings, Boolean.class, true);
+		labelParameter = ps.getProperty(HTML_labelParameter, String.class, "label");
+		addKeyValueTableHeaders = ps.getProperty(HTML_addKeyValueTableHeaders, Boolean.class, false);
+		addBeanTypeProperties = ps.getProperty(HTML_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
index 1ce2efc..4c1ee2f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlSerializerSession.java
@@ -55,7 +55,7 @@ public class HtmlSerializerSession extends XmlSerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
index 7efdfa0..29f4c78 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlStrippedDocSerializer.java
@@ -15,6 +15,7 @@ package org.apache.juneau.html;
 import java.lang.reflect.*;
 import java.util.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.serializer.*;
 
@@ -35,6 +36,14 @@ import org.apache.juneau.serializer.*;
 @Produces(value="text/html+stripped",contentType="text/html")
 public class HtmlStrippedDocSerializer extends HtmlSerializer {
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public HtmlStrippedDocSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
 	//---------------------------------------------------------------------------
 	// Overridden methods
 	//---------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileImpl.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileImpl.java b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileImpl.java
index a4b2f89..e8da4c3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileImpl.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileImpl.java
@@ -705,7 +705,12 @@ public final class ConfigFileImpl extends ConfigFile {
 
 	@Override /* ConfigFile */
 	public ConfigFile getResolving() {
-		return getResolving(VarResolver.DEFAULT.clone().addVars(ConfigFileVar.class,IfVar.class,SwitchVar.class).setContextObject(ConfigFileVar.SESSION_config, this));
+		return getResolving(
+			new VarResolverBuilder()
+				.vars(SystemPropertiesVar.class, EnvVariablesVar.class, SwitchVar.class, IfVar.class, ConfigFileVar.class,IfVar.class,SwitchVar.class)
+				.contextObject(ConfigFileVar.SESSION_config, this)
+				.build()
+		);
 	}
 
 	/*
@@ -730,7 +735,7 @@ public final class ConfigFileImpl extends ConfigFile {
 		}
 	}
 
-	private void addChange(Set<String> changes, String section, String key, String oldVal, String newVal) {
+	private static void addChange(Set<String> changes, String section, String key, String oldVal, String newVal) {
 		if (! StringUtils.isEquals(oldVal, newVal))
 			changes.add(getFullKey(section, key));
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileWrapped.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileWrapped.java b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileWrapped.java
index 44fdd0d..62f3899 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileWrapped.java
+++ b/juneau-core/src/main/java/org/apache/juneau/ini/ConfigFileWrapped.java
@@ -39,9 +39,10 @@ public final class ConfigFileWrapped extends ConfigFile {
 
 	ConfigFileWrapped(ConfigFileImpl cf, VarResolver vr) {
 		this.cf = cf;
-		this.vs = vr.clone()
-			.addVars(ConfigFileVar.class)
-			.setContextObject(ConfigFileVar.SESSION_config, cf)
+		this.vs = vr.builder()
+			.vars(ConfigFileVar.class)
+			.contextObject(ConfigFileVar.SESSION_config, cf)
+			.build()
 			.createSession();
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/ini/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ini/package.html b/juneau-core/src/main/java/org/apache/juneau/ini/package.html
index 4b0e158..a35c338 100644
--- a/juneau-core/src/main/java/org/apache/juneau/ini/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/ini/package.html
@@ -596,7 +596,7 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new REST client with JSON support</jc>
-	RestClient c = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>);
+	RestClient c = <jk>new</jk> RestClientBuilder().build();
 
 	<jc>// Retrieve config file through REST interface</jc>
 	ConfigFile cf = c.doGet(<js>"http://localhost:10000/sample/config"</js>).getResponse(ConfigFileImpl.<jk>class</jk>);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/internal/JuneauLogger.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/internal/JuneauLogger.java b/juneau-core/src/main/java/org/apache/juneau/internal/JuneauLogger.java
index 021e4c3..b89e32c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/internal/JuneauLogger.java
+++ b/juneau-core/src/main/java/org/apache/juneau/internal/JuneauLogger.java
@@ -28,13 +28,15 @@ import org.apache.juneau.transforms.*;
  */
 public class JuneauLogger extends java.util.logging.Logger {
 
-	private static final WriterSerializer serializer = JsonSerializer.DEFAULT_LAX.clone()
-		.addPojoSwaps(
+	private static final WriterSerializer serializer = new JsonSerializerBuilder()
+		.pojoSwaps(
 			CalendarSwap.ISO8601DTZ.class,
 			DateSwap.ISO8601DTZ.class,
 			EnumerationSwap.class,
 			IteratorSwap.class
-		);
+		)
+		.simple()
+		.build();
 
 	private static final ConcurrentHashMap<Class<?>,String> rbMap = new ConcurrentHashMap<Class<?>,String>();
 
@@ -120,7 +122,7 @@ public class JuneauLogger extends java.util.logging.Logger {
 
 	/**
 	 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#INFO} level.
-	 * 
+	 *
 	 * @param msg The message to log.
 	 * @param args Optional {@link MessageFormat}-style arguments.
 	 */
@@ -131,7 +133,7 @@ public class JuneauLogger extends java.util.logging.Logger {
 
 	/**
 	 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#CONFIG} level.
-	 * 
+	 *
 	 * @param msg The message to log.
 	 * @param args Optional {@link MessageFormat}-style arguments.
 	 */
@@ -142,7 +144,7 @@ public class JuneauLogger extends java.util.logging.Logger {
 
 	/**
 	 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINE} level.
-	 * 
+	 *
 	 * @param msg The message to log.
 	 * @param args Optional {@link MessageFormat}-style arguments.
 	 */
@@ -153,7 +155,7 @@ public class JuneauLogger extends java.util.logging.Logger {
 
 	/**
 	 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINER} level.
-	 * 
+	 *
 	 * @param msg The message to log.
 	 * @param args Optional {@link MessageFormat}-style arguments.
 	 */
@@ -164,7 +166,7 @@ public class JuneauLogger extends java.util.logging.Logger {
 
 	/**
 	 * Logs a message with the specified {@link MessageFormat}-style arguments at {@link Level#FINEST} level.
-	 * 
+	 *
 	 * @param msg The message to log.
 	 * @param args Optional {@link MessageFormat}-style arguments.
 	 */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectParser.java b/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectParser.java
deleted file mode 100644
index 92181bc..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectParser.java
+++ /dev/null
@@ -1,51 +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.jso;
-
-import java.io.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.parser.*;
-
-/**
- * Parses POJOs from HTTP responses as Java {@link ObjectInputStream ObjectInputStreams}.
- *
- * <h5 class='section'>Media types:</h5>
- * <p>
- * Consumes <code>Content-Type</code> types: <code>application/x-java-serialized-object</code>
- */
-@Consumes("application/x-java-serialized-object")
-public final class JavaSerializedObjectParser extends InputStreamParser {
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@SuppressWarnings("unchecked")
-	@Override /* InputStreamParser */
-	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
-		ObjectInputStream ois = new ObjectInputStream(session.getInputStream());
-		return (T)ois.readObject();
-	}
-
-
-	@Override /* Lockable */
-	public JavaSerializedObjectParser clone() {
-		try {
-			return (JavaSerializedObjectParser)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectSerializer.java b/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectSerializer.java
deleted file mode 100644
index 4cfde6a..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/jso/JavaSerializedObjectSerializer.java
+++ /dev/null
@@ -1,52 +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.jso;
-
-import java.io.*;
-
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * Serializes POJOs to HTTP responses as Java {@link ObjectOutputStream ObjectOutputStreams}.
- *
- * <h5 class='section'>Media types:</h5>
- * <p>
- * Handles <code>Accept</code> types: <code>application/x-java-serialized-object</code>
- * <p>
- * Produces <code>Content-Type</code> types: <code>application/x-java-serialized-object</code>
- */
-@Produces("application/x-java-serialized-object")
-public final class JavaSerializedObjectSerializer extends OutputStreamSerializer {
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* OutputStreamSerializer */
-	protected void doSerialize(SerializerSession session, Object o) throws Exception {
-		ObjectOutputStream oos = new ObjectOutputStream(session.getOutputStream());
-		oos.writeObject(o);
-		oos.flush();
-		oos.close();
-	}
-
-	@Override /* Serializer */
-	public JavaSerializedObjectSerializer clone() {
-		try {
-			return (JavaSerializedObjectSerializer)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
-}


[23/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
new file mode 100644
index 0000000..219211d
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerBuilder.java
@@ -0,0 +1,528 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of CSV serializers.
+ */
+public class CsvSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public CsvSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public CsvSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializer build() {
+		return new CsvSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public CsvSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CsvSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerContext.java
new file mode 100644
index 0000000..8346570
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerContext.java
@@ -0,0 +1,53 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Configurable properties on the {@link CsvSerializer} class.
+ * <p>
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
+ * <p>
+ * See {@link PropertyStore} for more information about context properties.
+ *
+ * <h5 class='section'>Inherited configurable properties:</h5>
+ * <ul class='javahierarchy'>
+ * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
+ * 	<ul>
+ * 		<li class='c'><a class="doclink" href="../serializer/SerializerContext.html#ConfigProperties">SerializerContext</a> - Configurable properties common to all serializers.
+ * 	</ul>
+ * </ul>
+ */
+public final class CsvSerializerContext extends SerializerContext {
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
+	 *
+	 * @param ps The property store that created this context.
+	 */
+	public CsvSerializerContext(PropertyStore ps) {
+		super(ps);
+	}
+
+	@Override /* Context */
+	public ObjectMap asMap() {
+		return super.asMap()
+			.append("CsvSerializerContext", new ObjectMap()
+		);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
new file mode 100644
index 0000000..bee169f
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializerSession.java
@@ -0,0 +1,46 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link CsvSerializer}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ */
+public final class CsvSerializerSession extends SerializerSession {
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * The context contains all the configuration settings for this object.
+	 * @param output The output object.
+	 * @param op The override properties.
+	 * These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
+	 * @param locale The session locale.
+	 * If <jk>null</jk>, then the locale defined on the context is used.
+	 * @param timeZone The session timezone.
+	 * If <jk>null</jk>, then the timezone defined on the context is used.
+	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
+	 */
+	protected CsvSerializerSession(CsvSerializerContext ctx, ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Common.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Common.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Common.java
index da813ac..c97d66c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Common.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Common.java
@@ -12,13 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.net.URI;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.xml.annotation.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomCommonAttributes</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/CommonEntry.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/CommonEntry.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/CommonEntry.java
index 160e196..b8df85a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/CommonEntry.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/CommonEntry.java
@@ -12,8 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
-import static org.apache.juneau.xml.annotation.XmlFormat.*;
 import static org.apache.juneau.dto.atom.Utils.*;
+import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.util.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Entry.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Entry.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Entry.java
index 754bb08..b5b55e5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Entry.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Entry.java
@@ -12,12 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
+
 import java.net.URI;
 import java.util.*;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.transforms.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomEntry</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Generator.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Generator.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Generator.java
index 861ed61..8dcea3c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Generator.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Generator.java
@@ -12,13 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.net.URI;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.xml.annotation.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomGenerator</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Icon.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Icon.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Icon.java
index 4cfa907..bb7f00d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Icon.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Icon.java
@@ -12,13 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.net.URI;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.xml.annotation.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomIcon</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Logo.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Logo.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Logo.java
index 1153455..744179b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Logo.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Logo.java
@@ -12,13 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.net.URI;
 
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.xml.annotation.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomLogo</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/Person.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Person.java b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Person.java
index 544ee63..02ea54a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/Person.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/Person.java
@@ -12,10 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.atom;
 
+import static org.apache.juneau.dto.atom.Utils.*;
+
 import java.net.URI;
 
 import org.apache.juneau.annotation.*;
-import static org.apache.juneau.dto.atom.Utils.*;
 
 /**
  * Represents an <code>atomPersonConstruct</code> construct in the RFC4287 specification.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/atom/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/atom/package.html b/juneau-core/src/main/java/org/apache/juneau/dto/atom/package.html
index 88caad0..ac7c3bd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/atom/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/atom/package.html
@@ -133,7 +133,7 @@
 		<h6 class='figure'>Example with no namespaces</h6>
 		<p class='bcode'>
 	<jc>// Create a serializer with readable output, no namespaces yet.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer.SqReadable();
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().sq().ws().build();
 
 	<jc>// Serialize to ATOM/XML</jc>
 	String atomXml = s.serialize(feed);
@@ -193,7 +193,7 @@
 		<h6 class='figure'>Example with namespaces</h6>
 		<p class='bcode'>
 	<jc>// Create a serializer with readable output with namespaces.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer.SqReadable();
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().sq().ws().build();
 
 	<jc>// Serialize to ATOM/XML</jc>
 	String atomXml = s.serialize(feed);
@@ -257,7 +257,7 @@
 		<h6 class='figure'>Example with namespaces with ATOM as the default namespace</h6>
 		<p class='bcode'>
 	<jc>// Create a serializer with readable output with namespaces.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer.SqReadable().setDefaultNamespaceUri(<js>"atom"</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().sq().ws().defaultNamespaceUri(<js>"atom"</js>).build();
 
 	<jc>// Serialize to ATOM/XML</jc>
 	String atomXml = s.serialize(feed);
@@ -426,10 +426,12 @@
 			<h6 class='figure'>ATOM/RDF/XML example</h6>
 			<p class='bcode'>
 	<jc>// Get RDF/XML serializer with readable output.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>)
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.ws()
+		.sq()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3)
+		.build();
 
 	<jc>// Serialize to ATOM/RDF/XML</jc>
 	String atomRdfXml = s.serialize(feed);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
index 03ff3d3..82e6ef2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
+++ b/juneau-core/src/main/java/org/apache/juneau/dto/html5/HtmlElementVoid.java
@@ -12,9 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.dto.html5;
 
-import org.apache.juneau.xml.annotation.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
+import org.apache.juneau.xml.annotation.*;
+
 /**
  * A subclass of HTML elements that have no content or end tags.
  * <p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java
index 4bf4e03..ce948c6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java
+++ b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroup.java
@@ -12,14 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.encoders;
 
-import static org.apache.juneau.internal.ArrayUtils.*;
-
 import java.util.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.internal.*;
-import org.apache.juneau.serializer.*;
 
 /**
  * Represents the group of {@link Encoder encoders} keyed by codings.
@@ -39,13 +35,13 @@ import org.apache.juneau.serializer.*;
  * Adding new entries will cause the entries to be prepended to the group.
  * This allows for previous encoders to be overridden through subsequent calls.
  * <p>
- * For example, calling <code>g.append(E1.<jk>class</jk>,E2.<jk>class</jk>).append(E3.<jk>class</jk>,E4.<jk>class</jk>)</code>
+ * For example, calling <code>groupBuilder.append(E1.<jk>class</jk>,E2.<jk>class</jk>).append(E3.<jk>class</jk>,E4.<jk>class</jk>)</code>
  * 	will result in the order <code>E3, E4, E1, E2</code>.
  *
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Create an encoder group with support for gzip compression.</jc>
- * 	EncoderGroup g = <jk>new</jk> EncoderGroup().append(GzipEncoder.<jk>class</jk>);
+ * 	EncoderGroup g = <jk>new</jk> EncoderGroupBuilder().append(GzipEncoder.<jk>class</jk>).build();
  *
  * 	<jc>// Should return "gzip"</jc>
  * 	String matchedCoding = g.findMatch(<js>"compress;q=1.0, gzip;q=0.8, identity;q=0.5, *;q=0"</js>);
@@ -54,69 +50,22 @@ import org.apache.juneau.serializer.*;
  * 	IEncoder encoder = g.getEncoder(matchedCoding);
  * </p>
  */
-public final class EncoderGroup extends Lockable {
+public final class EncoderGroup {
 
 	// Maps Accept-Encoding headers to matching encoders.
 	private final Map<String,EncoderMatch> cache = new ConcurrentHashMap<String,EncoderMatch>();
 
-	private final CopyOnWriteArrayList<Encoder> encoders = new CopyOnWriteArrayList<Encoder>();
+	final Encoder[] encoders;
 
 	/**
-	 * Adds the specified encoder to the beginning of this group.
+	 * Constructor
 	 *
-	 * @param e The encoder to add to this group.
-	 * @return This object (for method chaining).
+	 * @param encoders The encoders to add to this group.
 	 */
-	public EncoderGroup append(Encoder e) {
-		checkLock();
-		synchronized(this) {
-			cache.clear();
-			encoders.add(0, e);
-		}
-		return this;
+	public EncoderGroup(Encoder[] encoders) {
+		this.encoders = Arrays.copyOf(encoders, encoders.length);
 	}
 
-	/**
-	 * Registers the specified encoders with this group.
-	 *
-	 * @param e The encoders to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Encoder} could not be constructed.
-	 */
-	public EncoderGroup append(Class<? extends Encoder>...e) throws Exception {
-		for (Class<? extends Encoder> ee : ArrayUtils.reverse(e))
-			append(ee);
-		return this;
-	}
-
-	/**
-	 * Same as {@link #append(Class[])}, except specify a single class to avoid unchecked compile warnings.
-	 *
-	 * @param e The encoder to append to this group.
-	 * @return This object (for method chaining).
-	 * @throws Exception Thrown if {@link Serializer} could not be constructed.
-	 */
-	public EncoderGroup append(Class<? extends Encoder> e) throws Exception {
-		try {
-			append(e.newInstance());
-		} catch (NoClassDefFoundError x) {
-			// Ignore if dependent library not found (e.g. Jena).
-			System.err.println(e); // NOT DEBUG
-		}
-		return this;
-	}
-
-	/**
-	 * Adds the encoders in the specified group to this group.
-	 *
-	 * @param g The group containing the encoders to add to this group.
-	 * @return This object (for method chaining).
-	 */
-	public EncoderGroup append(EncoderGroup g) {
-		for (Encoder e : reverse(g.encoders.toArray(new Encoder[g.encoders.size()])))
-			append(e);
-		return this;
-	}
 
 	/**
 	 * Returns the coding string for the matching encoder that can handle the specified <code>Accept-Encoding</code>
@@ -130,7 +79,7 @@ public final class EncoderGroup extends Lockable {
 	 * @return The coding value (e.g. <js>"gzip"</js>).
 	 */
 	public EncoderMatch getEncoderMatch(String acceptEncoding) {
-		if (encoders.size() == 0)
+		if (encoders.length == 0)
 			return null;
 
 		EncoderMatch em = cache.get(acceptEncoding);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
new file mode 100644
index 0000000..7a965c6
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/encoders/EncoderGroupBuilder.java
@@ -0,0 +1,109 @@
+// ***************************************************************************************************************************
+// * 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.encoders;
+
+import java.util.*;
+
+/**
+ * Builder class for creating instances of {@link EncoderGroup}.
+ */
+public class EncoderGroupBuilder {
+
+	private final List<Encoder> encoders;
+
+	/**
+	 * Create an empty encoder group builder.
+	 */
+	public EncoderGroupBuilder() {
+		this.encoders = new ArrayList<Encoder>();
+	}
+
+	/**
+	 * Clone an existing encoder group builder.
+	 * @param copyFrom The encoder group that we're copying settings and encoders from.
+	 */
+	public EncoderGroupBuilder(EncoderGroup copyFrom) {
+		this.encoders = new ArrayList<Encoder>(Arrays.asList(copyFrom.encoders));
+	}
+
+	/**
+	 * Registers the specified encoders with this group.
+	 *
+	 * @param e The encoders to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public EncoderGroupBuilder append(Class<?>...e) {
+		for (Class<?> ee : e) {
+			try {
+				encoders.add((Encoder)((Class<?>)ee).newInstance());
+			} catch (Exception x) {
+				throw new RuntimeException(x);
+			}
+		}
+		return this;
+	}
+
+	/**
+	 * Registers the specified encoders with this group.
+	 *
+	 * @param e The encoders to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public EncoderGroupBuilder append(Encoder...e) {
+		encoders.addAll(Arrays.asList(e));
+		return this;
+	}
+
+	/**
+	 * Registers the specified encoders with this group.
+	 *
+	 * @param e The encoders to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public EncoderGroupBuilder append(Collection<Encoder> e) {
+		encoders.addAll(e);
+		return this;
+	}
+
+	/**
+	 * Registers the encoders in the specified group with this group.
+	 *
+	 * @param eg The encoders to append to this group.
+	 * @return This object (for method chaining).
+	 */
+	public EncoderGroupBuilder append(EncoderGroup eg) {
+		append(eg.encoders);
+		return this;
+	}
+
+	/**
+	 * Creates a new {@link EncoderGroup} object using a snapshot of the settings defined in this builder.
+	 * <p>
+	 * This method can be called multiple times to produce multiple encoder groups.
+	 *
+	 * @return A new {@link EncoderGroup} object.
+	 */
+	@SuppressWarnings("unchecked")
+	public EncoderGroup build() {
+		try {
+			List<Encoder> l = new ArrayList<Encoder>();
+			for (Object e : encoders) {
+				l.add(e instanceof Class ? ((Class<? extends Encoder>)e).getConstructor().newInstance() : (Encoder)e);
+			}
+			Collections.reverse(l);
+			return new EncoderGroup(l.toArray(new Encoder[l.size()]));
+		} catch (Exception x) {
+			throw new RuntimeException("Could not instantiate encoder.", x);
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
index 6428d8a..7359699 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializer.java
@@ -54,7 +54,19 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 
 
 	/** Default serializer, all default settings. */
-	public static final HtmlDocSerializer DEFAULT = new HtmlDocSerializer().lock();
+	public static final HtmlDocSerializer DEFAULT = new HtmlDocSerializer(PropertyStore.create());
+
+
+	final HtmlDocSerializerContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public HtmlDocSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(HtmlDocSerializerContext.class);
+	}
 
 
 	//--------------------------------------------------------------------------------
@@ -63,7 +75,7 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 
 	@Override /* Serializer */
 	public HtmlDocSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new HtmlDocSerializerSession(getContext(HtmlDocSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new HtmlDocSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* Serializer */
@@ -164,516 +176,4 @@ public class HtmlDocSerializer extends HtmlStrippedDocSerializer {
 			return true;
 		return false;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	@Override /* HtmlSerializer */
-	public HtmlDocSerializer setUriAnchorText(String value) throws LockedException {
-		super.setUriAnchorText(value);
-		return this;
-	}
-
-	@Override /* HtmlSerializer */
-	public HtmlDocSerializer setDetectLinksInStrings(boolean value) throws LockedException {
-		super.setDetectLinksInStrings(value);
-		return this;
-	}
-
-	@Override /* HtmlSerializer */
-	public HtmlDocSerializer setLookForLabelParameters(boolean value) throws LockedException {
-		super.setLookForLabelParameters(value);
-		return this;
-	}
-
-	@Override /* HtmlSerializer */
-	public HtmlDocSerializer setLabelParameter(String value) throws LockedException {
-		super.setLabelParameter(value);
-		return this;
-	}
-
-	@Override /* HtmlSerializer */
-	public HtmlDocSerializer setAddKeyValueTableHeaders(boolean value) throws LockedException {
-		super.setAddKeyValueTableHeaders(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public HtmlDocSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public HtmlDocSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlDocSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlDocSerializer clone() {
-		HtmlDocSerializer c = (HtmlDocSerializer)super.clone();
-		return c;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
index 56f6fb6..1849755 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerContext.java
@@ -231,18 +231,18 @@ public final class HtmlDocSerializerContext extends HtmlSerializerContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public HtmlDocSerializerContext(ContextFactory cf) {
-		super(cf);
-		cssImports = cf.getProperty(HTMLDOC_cssImports, String[].class, new String[0]);
-		title = cf.getProperty(HTMLDOC_title, String.class, null);
-		description = cf.getProperty(HTMLDOC_description, String.class, null);
-		cssUrl = cf.getProperty(HTMLDOC_cssUrl, String.class, null);
-		nowrap = cf.getProperty(HTMLDOC_nowrap, boolean.class, false);
-		links = cf.getMap(HTMLDOC_links, String.class, String.class, Collections.<String,String>emptyMap());
+	public HtmlDocSerializerContext(PropertyStore ps) {
+		super(ps);
+		cssImports = ps.getProperty(HTMLDOC_cssImports, String[].class, new String[0]);
+		title = ps.getProperty(HTMLDOC_title, String.class, null);
+		description = ps.getProperty(HTMLDOC_description, String.class, null);
+		cssUrl = ps.getProperty(HTMLDOC_cssUrl, String.class, null);
+		nowrap = ps.getProperty(HTMLDOC_nowrap, boolean.class, false);
+		links = ps.getMap(HTMLDOC_links, String.class, String.class, Collections.<String,String>emptyMap());
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
index b4745cd..94666f8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlDocSerializerSession.java
@@ -44,7 +44,7 @@ public final class HtmlDocSerializerSession extends HtmlSerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
index 92eb48f..bce548c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/html/HtmlParser.java
@@ -20,7 +20,6 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import javax.xml.stream.*;
-import javax.xml.stream.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
@@ -51,10 +50,27 @@ import org.apache.juneau.xml.*;
  */
 @SuppressWarnings({ "rawtypes", "unchecked", "hiding" })
 @Consumes("text/html,text/html+stripped")
-public final class HtmlParser extends XmlParser {
+public class HtmlParser extends XmlParser {
 
 	/** Default parser, all default settings.*/
-	public static final HtmlParser DEFAULT = new HtmlParser().lock();
+	public static final HtmlParser DEFAULT = new HtmlParser(PropertyStore.create());
+
+
+	private final HtmlParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public HtmlParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(HtmlParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public HtmlParserBuilder builder() {
+		return new HtmlParserBuilder(propertyStore);
+	}
 
 	/*
 	 * Reads anything starting at the current event.
@@ -350,7 +366,7 @@ public final class HtmlParser extends XmlParser {
 
 			String type = getAttribute(r, session.getBeanTypePropertyName(), null);
 			ClassMeta elementType2 = session.getClassMeta(type, pMeta, null);
-			if (elementType2 != null) 
+			if (elementType2 != null)
 				elementType = elementType2;
 
 			if (elementType.canCreateNewBean(l)) {
@@ -523,7 +539,7 @@ public final class HtmlParser extends XmlParser {
 
 	@Override /* Parser */
 	public HtmlParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new HtmlParserSession(getContext(HtmlParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new HtmlParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	@Override /* Parser */
@@ -549,445 +565,4 @@ public final class HtmlParser extends XmlParser {
 		HtmlParserSession s = (HtmlParserSession)session;
 		return parseArgs(s, s.getXmlStreamReader(), argTypes);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	@Override /* XmlParser */
-	public HtmlParser setValidating(boolean value) throws LockedException {
-		super.setValidating(value);
-		return this;
-	}
-
-	@Override /* XmlParser */
-	public HtmlParser setReporter(XMLReporter value) throws LockedException {
-		super.setReporter(value);
-		return this;
-	}
-
-	@Override /* XmlParser */
-	public HtmlParser setResolver(XMLResolver value) throws LockedException {
-		super.setResolver(value);
-		return this;
-	}
-
-	@Override /* XmlParser */
-	public HtmlParser setEventAllocator(XMLEventAllocator value) throws LockedException {
-		super.setEventAllocator(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public HtmlParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public HtmlParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public HtmlParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public HtmlParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public HtmlParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public HtmlParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public HtmlParser clone() {
-		return (HtmlParser)super.clone();
-	}
 }


[24/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java b/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java
new file mode 100644
index 0000000..2bfc27b
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/PropertyStore.java
@@ -0,0 +1,1384 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import static org.apache.juneau.BeanContext.*;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.concurrent.locks.*;
+
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * A store for instantiating {@link Context} objects.
+ * <p>
+ * The hierarchy of these objects are...
+ * <ul class='spaced-list'>
+ * 	<li>{@link PropertyStore} - A thread-safe, modifiable context property store.<br>
+ * 		Used to create {@link Context} objects.
+ * 	<li>{@link Context} - A reusable, cachable, thread-safe, read-only context with configuration properties copied from the store.<br>
+ * 		Often used to create {@link Session} objects.
+ * 	<li>{@link Session} - A one-time-use non-thread-safe object.<br>
+ * 		Used by serializers and parsers to retrieve context properties and to be used as scratchpads.
+ * </ul>
+ *
+ * <h6 class='topic'>PropertyStore objects</h6>
+ * <p>
+ * Property stores can be thought of as consisting of the following:
+ * <ul class='spaced-list'>
+ * 	<li>A <code>Map&lt;String,Object&gt;</code> of context properties.
+ * 	<li>A <code>Map&lt;Class,Context&gt;</code> of context instances.
+ * </ul>
+ * <p>
+ * Property stores are used to create and cache {@link Context} objects using the {@link #getContext(Class)} method.
+ * <p>
+ * As a general rule, {@link PropertyStore} objects are 'slow'.<br>
+ * Setting and retrieving properties on a store can involve relatively slow data conversion and synchronization.<br>
+ * However, the {@link #getContext(Class)} method is fast, and will return cached context objects if the context properties have not changed.
+ * <p>
+ * Property stores can be used to store context properties for a variety of contexts.<br>
+ * For example, a single store can store context properties for the JSON serializer, XML serializer, HTML serializer
+ * 	etc... and can thus be used to retrieve context objects for those serializers.<br>
+ * <p>
+ *
+ * <h6 class='topic'>Context properties</h6>
+ * <p>
+ * Context properties are 'settings' for serializers and parsers.<br>
+ * For example, the {@link BeanContext#BEAN_sortProperties} context property defines whether
+ * 	bean properties should be serialized in alphabetical order.
+ * <p>
+ * Each {@link Context} object should contain the context properties that apply to it as static
+ * 	fields (e.g {@link BeanContext#BEAN_sortProperties}).
+ * <p>
+ * Context properties can be of the following types:
+ * <ul class='spaced-list'>
+ * 	<li><l>SIMPLE</l> - A simple property.<br>
+ * 		Examples include:  booleans, integers, Strings, Classes, etc...<br>
+ * 		<br>
+ * 		An example of this would be the {@link BeanContext#BEAN_sortProperties} property.<br>
+ * 		It's name is simply <js>"BeanContext.sortProperties"</js>.
+ *
+ * 	<li><l>SET</l> - A sorted set of objects.<br>
+ * 	These are denoted by appending <js>".set"</js> to the property name.<br>
+ * 		Objects can be of any type, even complex types.<br>
+ * 		Sorted sets use tree sets to maintain the value in alphabetical order.<br>
+ * 		<br>
+ * 		For example, the {@link BeanContext#BEAN_notBeanClasses} property is used to store classes that should not be treated like beans.<br>
+ * 		It's name is <js>"BeanContext.notBeanClasses.set"</js>.
+ *
+ * 	<li><l>LIST</l> - A list of unique objects.<br>
+ * 		These are denoted by appending <js>".list"</js> to the property name.<br>
+ * 		Objects can be of any type, even complex types.<br>
+ * 		Use lists if the ordering of the values in the set is important (similar to how the order of entries in a classpath is important).<br>
+ * 		<br>
+ * 		For example, the {@link BeanContext#BEAN_beanFilters} property is used to store bean filters.<br>
+ * 		It's name is <js>"BeanContext.transforms.list"</js>.
+ *
+ * 	<li><l>MAP</l> - A sorted map of key-value pairs.<br>
+ * 		These are denoted by appending <js>".map"</js> to the property name.<br>
+ * 		Keys can be any type directly convertable to and from Strings.
+ * 		Values can be of any type, even complex types.<br>
+ * 		<br>
+ * 		For example, the {@link BeanContext#BEAN_implClasses} property is used to specify the names of implementation classes for interfaces.<br>
+ * 		It's name is <js>"BeanContext.implClasses.map"</js>.<br>
+ * </ul>
+ * <p>
+ * All context properties are set using the {@link #setProperty(String, Object)} method.
+ * <p>
+ * Default values for context properties can be specified globally as system properties.<br>
+ * Example: <code>System.<jsm>setProperty</jsm>(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);</code>
+ * <p>
+ * SET and LIST properties can be added to using the {@link #addToProperty(String, Object)} method and removed from using the {@link #removeFromProperty(String, Object)} method.
+ * <p>
+ * SET and LIST properties can also be added to and removed from by appending <js>".add"</js> or <js>".remove"</js> to the property name and using the {@link #setProperty(String, Object)} method.
+ * <p>
+ * The following shows the two different ways to append to a set or list property:
+ * <p class='bcode'>
+ * 	PropertyStore ps = <jk>new</jk> PropertyStore().setProperty(<js>"BeanContext.notBeanClasses.set"</js>, Collections.<jsm>emptySet</jsm>());
+ *
+ * 	<jc>// Append to set property using addTo().</jc>
+ * 	ps.addToProperty(<js>"BeanContext.notBeanClasses.set"</js>, MyNotBeanClass.<jk>class</jk>);
+ *
+ * 	<jc>// Append to set property using set().</jc>
+ * 	ps.setProperty(<js>"BeanContext.notBeanClasses.set.add"</js>, MyNotBeanClass.<jk>class</jk>);
+ * </p>
+ * <p>
+ * SET and LIST properties can also be set and manipulated using JSON strings.
+ * <p class='bcode'>
+ * 	PropertyStore ps = PropertyStore.<jsm>create</jsm>();
+ *
+ * 	<jc>// Set SET value using JSON array.
+ * 	ps.setProperty(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass1']"</js>);
+ *
+ * 	<jc>// Add to SET using simple string.
+ * 	ps.addToProperty(<js>"BeanContext.notBeanClasses.set"</js>, <js>"com.my.MyNotBeanClass2"</js>);
+ *
+ * 	<jc>// Add an array of values as a JSON array..
+ * 	ps.addToProperty(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass3']"</js>);
+ *
+ * 	<jc>// Remove an array of values as a JSON array..
+ * 	ps.removeFromProperty(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass3']"</js>);
+ * </p>
+ * <p>
+ * MAP properties can be added to using the {@link #putToProperty(String, Object, Object)} and {@link #putToProperty(String, Object)} methods.<br>
+ * MAP property entries can be removed by setting the value to <jk>null</jk> (e.g. <code>putToProperty(<js>"BEAN_implClasses"</js>, MyNotBeanClass.<jk>class</jk>, <jk>null</jk>);</code>.<br>
+ * MAP properties can also be added to by appending <js>".put"</js> to the property name and using the {@link #setProperty(String, Object)} method.<br>
+ * <p>
+ * The following shows the two different ways to append to a set property:
+ * <p class='bcode'>
+ * 	PropertyStore ps = PropertyStore.<jsm>create</jsm>().setProperty(<js>"BeanContext.implClasses.map"</js>, Collections.<jsm>emptyMap</jsm>());
+ *
+ * 	<jc>// Append to map property using putTo().</jc>
+ * 	ps.putToProperty(<js>"BeanContext.implClasses.map"</js>, MyInterface.<jk>class</jk>, MyInterfaceImpl.<jk>class</jk>);
+ *
+ * 	<jc>// Append to map property using set().</jc>
+ * 	Map m = <jk>new</jk> HashMap(){{put(MyInterface.<jk>class</jk>,MyInterfaceImpl.<jk>class</jk>)}};
+ * 	ps.setProperty(<js>"BeanContext.implClasses.map.put"</js>, m);
+ * </p>
+ * <p>
+ * MAP properties can also be set and manipulated using JSON strings.
+ * <p class='bcode'>
+ * 	PropertyStore ps = PropertyStore.<jsm>create</jsm>();
+ *
+ * 	<jc>// Set MAP value using JSON object.</jc>
+ * 	ps.setProperty(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface1':'com.my.MyInterfaceImpl1'}"</js>);
+ *
+ * 	<jc>// Add to MAP using JSON object.</jc>
+ * 	ps.putToProperty(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface2':'com.my.MyInterfaceImpl2'}"</js>);
+ *
+ * 	<jc>// Remove from MAP using JSON object.</jc>
+ * 	ps.putToProperty(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface2':null}"</js>);
+ * </p>
+ * <p>
+ * Context properties are retrieved from this store using the following 3 methods:
+ * <ul class='spaced-list'>
+ * 	<li>{@link #getProperty(String, Class, Object)} - Retrieve a SIMPLE or SET property converted to the specified class type.
+ * 	<li>{@link #getMap(String, Class, Class, Map)} - Retrieve a MAP property with keys/values converted to the specified class types.
+ * 	<li>{@link #getPropertyMap(String)} - Retrieve a map of all context properties with the specified prefix (e.g. <js>"BeanContext"</js> for {@link BeanContext} properties).
+ * </ul>
+ * <p>
+ * As a general rule, only {@link Context} objects will use these read methods.
+ *
+ * <h6 class='topic'>Context objects</h6>
+ * <p>
+ * A Context object can be thought of as unmodifiable snapshot of a store.<br>
+ * They should be 'fast' by avoiding synchronization by using final fields whenever possible.<br>
+ * However, they MUST be thread safe.
+ * <p>
+ * Context objects are created using the {@link #getContext(Class)} method.<br>
+ * As long as the properties on a store have not been modified, the store will return a cached copy
+ * 	of a context.
+ * <p class='bcode'>
+ * 	PropertyStore ps = PropertyStore.<jsm>create</jsm>();
+ *
+ * 	<jc>// Get BeanContext with default store settings.</jc>
+ * 	BeanContext bc = ps.getContext(BeanContext.<jk>class</jk>);
+ *
+ * 	<jc>// Get another one.  This will be the same one.</jc>
+ * 	BeanContext bc2 = ps.getContext(BeanContext.<jk>class</jk>);
+ * 	<jsm>assertTrue</jsm>(bc1 == bc2);
+ *
+ * 	<jc>// Set a property.</jc>
+ * 	ps.setProperty(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);
+ *
+ * 	<jc>// Get another one.  This will be different!</jc>
+ * 	bc2 = f.getContext(BeanContext.<jk>class</jk>);
+ * 	<jsm>assertFalse</jsm>(bc1 == bc2);
+ * </p>
+ *
+ * <h6 class='topic'>Session objects</h6>
+ * <p>
+ * Session objects are created through {@link Context} objects, typically through a <code>createContext()</code> method.<br>
+ * Unlike context objects, they are NOT reusable and NOT thread safe.<br>
+ * They are meant to be used one time and then thrown away.<br>
+ * They should NEVER need to use synchronization.
+ * <p>
+ * Session objects are also often used as scratchpads for information such as keeping track of call stack
+ * 	information to detect recursive loops when serializing beans.
+ */
+public final class PropertyStore {
+
+	// All configuration properties in this object.
+	// Keys are property prefixes (e.g. 'BeanContext').
+	// Values are maps containing properties for that specific prefix.
+	private Map<String,PropertyMap> properties = new ConcurrentSkipListMap<String,PropertyMap>();
+
+	// Context cache.
+	// This gets cleared every time any properties change on this object.
+	private final Map<Class<? extends Context>,Context> contexts = new ConcurrentHashMap<Class<? extends Context>,Context>();
+
+	// Global Context cache.
+	// Property stores that are the 'same' will use the same maps from this cache.
+	// 'same' means the context properties are all the same when converted to strings.
+	private static final ConcurrentHashMap<Integer, ConcurrentHashMap<Class<? extends Context>,Context>> globalContextCache = new ConcurrentHashMap<Integer, ConcurrentHashMap<Class<? extends Context>,Context>>();
+
+	private ReadWriteLock lock = new ReentrantReadWriteLock();
+	private Lock rl = lock.readLock(), wl = lock.writeLock();
+
+	// Classloader used to instantiate Class instances.
+	ClassLoader classLoader = ClassLoader.getSystemClassLoader();
+
+	// Parser to use to convert JSON strings to POJOs
+	ReaderParser defaultParser;
+
+	// Bean session for converting strings to POJOs.
+	private static BeanSession beanSession;
+
+	// Used to keep properties in alphabetical order regardless of whether
+	// they're not strings.
+	private static Comparator<Object> PROPERTY_COMPARATOR = new Comparator<Object>() {
+		@Override
+		public int compare(Object o1, Object o2) {
+			return unswap(o1).toString().compareTo(unswap(o2).toString());
+		}
+	};
+
+	/**
+	 * Create a new property store with default settings.
+	 *
+	 * @return A new property store with default settings.
+	 */
+	public static PropertyStore create() {
+		PropertyStore f = new PropertyStore();
+		BeanContext.loadDefaults(f);
+		return f;
+	}
+
+	/**
+	 * Create a new property store with settings copied from the specified store.
+	 *
+	 * @param copyFrom The existing store to copy properties from.
+	 * @return A new property store with default settings.
+	 */
+	public static PropertyStore create(PropertyStore copyFrom) {
+		return new PropertyStore().copyFrom(copyFrom);
+	}
+
+
+	PropertyStore() {}
+
+	/**
+	 * Copy constructor.
+	 *
+	 * @param copyFrom The store to copy properties from.
+	 */
+	private PropertyStore(PropertyStore copyFrom) {
+		copyFrom(copyFrom);
+	}
+
+	/**
+	 * Copies the properties from the specified store into this store.
+	 * <p>
+	 * Properties of type set/list/collection will be appended to the existing
+	 * properties if they already exist.
+	 *
+	 * @param ps The store to copy from.
+	 * @return This object (for method chaining).
+	 */
+	public PropertyStore copyFrom(PropertyStore ps) {
+		// TODO - Needs more testing.
+		for (Map.Entry<String,PropertyMap> e : ps.properties.entrySet())
+			this.properties.put(e.getKey(), new PropertyMap(this.properties.get(e.getKey()), e.getValue()));
+		this.classLoader = ps.classLoader;
+		this.defaultParser = ps.defaultParser;
+		return this;
+	}
+
+	/**
+	 * Creates a new store with the specified override properties applied to this store.
+	 *
+	 * @param overrideProperties The properties to apply to the copy of this store.
+	 * @return Either this unmodified store, or a new store with override properties applied.
+	 */
+	public PropertyStore create(Map<String,Object> overrideProperties) {
+		return new PropertyStore(this).setProperties(overrideProperties);
+	}
+
+	/**
+	 * Sets a configuration property value on this object.
+	 * <p>
+	 * A typical usage is to set or overwrite configuration values like so...
+	 * <p class='bcode'>
+	 * 	PropertyStore ps = PropertyStore.<jsm>create</jsm>();
+	 * 	ps.setProperty(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);
+	 * </p>
+	 * <p>
+	 * The possible class types of the value depend on the property type:
+	 * <p>
+	 * <table class='styled'>
+	 * 	<tr>
+	 * 		<th>Property type</th>
+	 * 		<th>Example</th>
+	 * 		<th>Allowed value type</th>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>Set <l>SIMPLE</l></td>
+	 * 		<td><js>"Foo.x"</js></td>
+	 * 		<td>Any object type.</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>Set <l>SET/LIST</l></td>
+	 * 		<td><js>"Foo.x.set"</js></td>
+	 * 		<td>Any collection or array of any objects, or a String containing a JSON array.</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>Add/Remove <l>SET/LIST</l></td>
+	 * 		<td><js>"Foo.x.set.add"</js></td>
+	 * 		<td>If a collection, adds or removes the entries in the collection.  Otherwise, adds/removes a single entry.</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>Set <l>MAP</l></td>
+	 * 		<td><js>"Foo.x.map"</js></td>
+	 * 		<td>A map, or a String containing a JSON object.  Entries overwrite existing map.</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td>Put <l>MAP</l></td>
+	 * 		<td><js>"Foo.x.map.put"</js></td>
+	 * 		<td>A map, or a String containing a JSON object.  Entries are added to existing map.</td>
+	 * 	</tr>
+	 * </table>
+	 *
+	 * @param name The configuration property name.<br>
+	 * If name ends with <l>.add</l>, then the specified value is added to the
+	 * 	existing property value as an entry in a SET or LIST property.<br>
+	 * If name ends with <l>.put</l>, then the specified value is added to the
+	 * 	existing property value as a key/value pair in a MAP property.<br>
+	 * If name ends with <l>.remove</l>, then the specified value is removed from the
+	 * 	existing property property value in a SET or LIST property.<br>
+	 *
+	 * @param value The new value.
+	 * If <jk>null</jk>, the property value is deleted.<br>
+	 * In general, the value type can be anything.<br>
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public PropertyStore setProperty(String name, Object value) {
+		String prefix = prefix(name);
+
+		if (name.endsWith(".add"))
+			return addToProperty(name.substring(0, name.lastIndexOf('.')), value);
+
+		if (name.endsWith(".put"))
+			return putToProperty(name.substring(0, name.lastIndexOf('.')), value);
+
+		if (name.endsWith(".remove"))
+			return removeFromProperty(name.substring(0, name.lastIndexOf('.')), value);
+
+		wl.lock();
+		try {
+			contexts.clear();
+			if (! properties.containsKey(prefix))
+				properties.put(prefix, new PropertyMap(prefix));
+			properties.get(prefix).set(name, value);
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Convenience method for setting multiple properties in one call.
+	 * <p>
+	 * This appends to any previous configuration properties set on this store.
+	 *
+	 * @param newProperties The new properties to set.
+	 * @return This object (for method chaining).
+	 */
+	public PropertyStore setProperties(Map<String,Object> newProperties) {
+		if (newProperties == null || newProperties.isEmpty())
+			return this;
+		wl.lock();
+		try {
+			contexts.clear();
+			for (Map.Entry<String,Object> e : newProperties.entrySet()) {
+				String name = e.getKey().toString();
+				Object value = e.getValue();
+				String prefix = prefix(name);
+				if (name.endsWith(".add"))
+					addToProperty(name.substring(0, name.lastIndexOf('.')), value);
+				else if (name.endsWith(".remove"))
+					removeFromProperty(name.substring(0, name.lastIndexOf('.')), value);
+				else {
+					if (! properties.containsKey(prefix))
+						properties.put(prefix, new PropertyMap(prefix));
+					properties.get(prefix).set(name, value);
+				}
+			}
+
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Adds several properties to this store.
+	 *
+	 * @param properties The properties to add to this store.
+	 * @return This object (for method chaining).
+	 */
+	@SuppressWarnings("hiding")
+	public PropertyStore addProperties(Map<String,Object> properties) {
+		if (properties != null)
+			for (Map.Entry<String,Object> e : properties.entrySet())
+				setProperty(e.getKey(), e.getValue());
+		return this;
+	}
+
+	/**
+	 * Adds a value to a SET property.
+	 *
+	 * @param name The property name.
+	 * @param value The new value to add to the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public PropertyStore addToProperty(String name, Object value) {
+		String prefix = prefix(name);
+		wl.lock();
+		try {
+			contexts.clear();
+			if (! properties.containsKey(prefix))
+				properties.put(prefix, new PropertyMap(prefix));
+			properties.get(prefix).addTo(name, value);
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property.
+	 *
+	 * @param name The property name.
+	 * @param key The property value map key.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public PropertyStore putToProperty(String name, Object key, Object value) {
+		String prefix = prefix(name);
+		wl.lock();
+		try {
+			contexts.clear();
+			if (! properties.containsKey(prefix))
+				properties.put(prefix, new PropertyMap(prefix));
+			properties.get(prefix).putTo(name, key, value);
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Adds or overwrites a value to a MAP property.
+	 *
+	 * @param name The property value.
+	 * @param value The property value map value.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a MAP property.
+	 */
+	public PropertyStore putToProperty(String name, Object value) {
+		String prefix = prefix(name);
+		wl.lock();
+		try {
+			contexts.clear();
+			if (! properties.containsKey(prefix))
+				properties.put(prefix, new PropertyMap(prefix));
+			properties.get(prefix).putTo(name, value);
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Removes a value from a SET property.
+	 *
+	 * @param name The property name.
+	 * @param value The property value in the SET property.
+	 * @return This object (for method chaining).
+	 * @throws ConfigException If property is not a SET property.
+	 */
+	public PropertyStore removeFromProperty(String name, Object value) {
+		String prefix = prefix(name);
+		wl.lock();
+		try {
+			contexts.clear();
+			if (properties.containsKey(prefix))
+				properties.get(prefix).removeFrom(name, value);
+		} finally {
+			wl.unlock();
+		}
+		return this;
+	}
+
+	/**
+	 * Returns an instance of the specified context initialized with the properties
+	 * 	in this store.
+	 * <p>
+	 * Multiple calls to this method for the same store class will return the same
+	 * 	cached value as long as the properties on this store are not touched.
+	 * <p>
+	 * As soon as any properties are modified on this store, all cached entries
+	 * 	are discarded and recreated as needed.
+	 *
+	 * @param c The context class to instantiate.
+	 * @return The context instance.
+	 */
+	@SuppressWarnings("unchecked")
+	public <T extends Context> T getContext(Class<T> c) {
+		rl.lock();
+		try {
+			try {
+				if (! contexts.containsKey(c)) {
+
+					// Try to get it from the global cache.
+					Integer key = hashCode();
+					if (! globalContextCache.containsKey(key))
+						globalContextCache.putIfAbsent(key, new ConcurrentHashMap<Class<? extends Context>,Context>());
+					ConcurrentHashMap<Class<? extends Context>, Context> cacheForThisConfig = globalContextCache.get(key);
+
+					if (! cacheForThisConfig.containsKey(c))
+						cacheForThisConfig.putIfAbsent(c, c.getConstructor(PropertyStore.class).newInstance(this));
+
+					contexts.put(c, cacheForThisConfig.get(c));
+				}
+				return (T)contexts.get(c);
+			} catch (Exception e) {
+				throw new ConfigException("Could not instantiate context class ''{0}''", className(c)).initCause(e);
+			}
+		} finally {
+			rl.unlock();
+		}
+	}
+
+	/**
+	 * Returns the configuration properties with the specified prefix.
+	 * <p>
+	 * For example, if <l>prefix</l> is <js>"BeanContext"</js>, then retrieves
+	 * 	all configuration properties that are prefixed with <js>"BeanContext."</js>.
+	 *
+	 * @param prefix The prefix of properties to retrieve.
+	 * @return The configuration properties with the specified prefix, never <jk>null</jk>.
+	 */
+	public PropertyMap getPropertyMap(String prefix) {
+		rl.lock();
+		try {
+			PropertyMap m = properties.get(prefix);
+			return m == null ? new PropertyMap(prefix) : m;
+		} finally {
+			rl.unlock();
+		}
+	}
+
+	/**
+	 * Specifies the classloader to use when resolving classes from strings.
+	 * <p>
+	 * Can be used for resolving class names when the classes being created are in a different
+	 * 	classloader from the Juneau code.
+	 * <p>
+	 * If <jk>null</jk>, the system classloader will be used to resolve classes.
+	 *
+	 * @param classLoader The new classloader.
+	 * @return This object (for method chaining).
+	 */
+	public PropertyStore setClassLoader(ClassLoader classLoader) {
+		this.classLoader = (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader);
+		return this;
+	}
+
+	/**
+	 * Specifies the parser to use to convert Strings to POJOs.
+	 * <p>
+	 * If <jk>null</jk>, {@link JsonParser#DEFAULT} will be used.
+	 *
+	 * @param defaultParser The new defaultParser.
+	 * @return This object (for method chaining).
+	 */
+	public PropertyStore setDefaultParser(ReaderParser defaultParser) {
+		this.defaultParser = defaultParser == null ? JsonParser.DEFAULT : defaultParser;
+		return this;
+	}
+
+	/**
+	 * Returns a property value converted to the specified type.
+	 *
+	 * @param name The full name of the property (e.g. <js>"BeanContext.sortProperties"</js>)
+	 * @param type The class type to convert the property value to.
+	 * @param def The default value if the property is not set.
+	 *
+	 * @return The property value.
+	 * @throws ConfigException If property has a value that cannot be converted to a boolean.
+	 */
+	public <T> T getProperty(String name, Class<T> type, T def) {
+		rl.lock();
+		try {
+			PropertyMap pm = getPropertyMap(prefix(name));
+			if (pm != null)
+				return pm.get(name, type, def);
+			String s = System.getProperty(name);
+			if ((! StringUtils.isEmpty(s)) && isBeanSessionAvailable())
+				return getBeanSession().convertToType(s, type);
+			return def;
+		} finally {
+			rl.unlock();
+		}
+	}
+
+	/**
+	 * Returns a property value converted to a {@link LinkedHashMap} with the specified
+	 * 	key and value types.
+	 *
+	 * @param name The full name of the property (e.g. <js>"BeanContext.sortProperties"</js>)
+	 * @param keyType The class type of the keys in the map.
+	 * @param valType The class type of the values in the map.
+	 * @param def The default value if the property is not set.
+	 *
+	 * @return The property value.
+	 * @throws ConfigException If property has a value that cannot be converted to a boolean.
+	 */
+	public <K,V> Map<K,V> getMap(String name, Class<K> keyType, Class<V> valType, Map<K,V> def) {
+		rl.lock();
+		try {
+			PropertyMap pm = getPropertyMap(prefix(name));
+			if (pm != null)
+				return pm.getMap(name, keyType, valType, def);
+			return def;
+		} finally {
+			rl.unlock();
+		}
+	}
+
+
+	//-------------------------------------------------------------------------------------
+	// Convenience methods.
+	//-------------------------------------------------------------------------------------
+
+	/**
+	 * Shortcut for calling <code>getContext(BeanContext.<jk>class</jk>);</code>.
+	 *
+	 * @return The bean context instance.
+	 */
+	public BeanContext getBeanContext() {
+		return getContext(BeanContext.class);
+	}
+
+	/**
+	 * Shortcut for calling <code>setProperty(<jsf>BEAN_notBeanClasses</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public PropertyStore setNotBeanClasses(Class<?>...classes) {
+		setProperty(BEAN_notBeanClasses, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>addToProperty(<jsf>BEAN_notBeanClasses</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @see PropertyStore#addToProperty(String,Object)
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#addToProperty(String, Object)
+	 * @see BeanContext#BEAN_notBeanClasses
+	 */
+	public PropertyStore addNotBeanClasses(Class<?>...classes) {
+		addToProperty(BEAN_notBeanClasses, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>setProperty(<jsf>BEAN_beanFilters</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public PropertyStore setBeanFilters(Class<?>...classes) {
+		setProperty(BEAN_beanFilters, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>addToProperty(<jsf>BEAN_beanFilters</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#addToProperty(String, Object)
+	 * @see BeanContext#BEAN_beanFilters
+	 */
+	public PropertyStore addBeanFilters(Class<?>...classes) {
+		addToProperty(BEAN_beanFilters, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>setProperty(<jsf>BEAN_pojoSwaps</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public PropertyStore setPojoSwaps(Class<?>...classes) {
+		setProperty(BEAN_pojoSwaps, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>addToProperty(<jsf>BEAN_pojoSwaps</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#addToProperty(String, Object)
+	 * @see BeanContext#BEAN_pojoSwaps
+	 */
+	public PropertyStore addPojoSwaps(Class<?>...classes) {
+		addToProperty(BEAN_pojoSwaps, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>setProperty(<jsf>BEAN_beanDictionary</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#setProperty(String, Object)
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public PropertyStore setBeanDictionary(Class<?>...classes) {
+		addToProperty(BEAN_beanDictionary, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>addToProperty(<jsf>BEAN_beanDictionary</jsf>, <jf>classes</jf>)</code>.
+	 *
+	 * @param classes The new setting value for the bean context.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#addToProperty(String, Object)
+	 * @see BeanContext#BEAN_beanDictionary
+	 */
+	public PropertyStore addToBeanDictionary(Class<?>...classes) {
+		addToProperty(BEAN_beanDictionary, classes);
+		return this;
+	}
+
+	/**
+	 * Shortcut for calling <code>putTo(<jsf>BEAN_implCLasses</jsf>, <jf>interfaceClass</jf>, <jf>implClass</jf>)</code>.
+	 *
+	 * @param interfaceClass The interface class.
+	 * @param implClass The implementation class.
+	 * @param <T> The class type of the interface.
+	 * @return This object (for method chaining).
+	 * @see PropertyStore#putToProperty(String, Object, Object)
+	 * @see BeanContext#BEAN_implClasses
+	 */
+	public <T> PropertyStore addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		putToProperty(BEAN_implClasses, interfaceClass, implClass);
+		return this;
+	}
+
+
+	//-------------------------------------------------------------------------------------
+	// Object methods.
+	//-------------------------------------------------------------------------------------
+
+	@Override /* Object */
+	public int hashCode() {
+		HashCode c = new HashCode();
+		for (PropertyMap m : properties.values())
+			c.add(m);
+		return c.get();
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Utility classes and methods.
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Hashcode generator that treats strings and primitive values the same.
+	 * (e.g. <code>123</code> and <js>"123"</js> result in the same hashcode.)
+	 */
+	private static class NormalizingHashCode extends HashCode {
+		@Override /* HashCode */
+		protected Object unswap(Object o) {
+			return PropertyStore.unswap(o);
+		}
+	}
+
+	/**
+	 * Contains all the properties for a particular property prefix (e.g. <js>'BeanContext'</js>)
+	 * <p>
+	 * Instances of this map are immutable from outside this class.
+	 * <p>
+	 * The {@link PropertyMap#hashCode()} and {@link PropertyMap#equals(Object)} methods
+	 * 	can be used to compare with other property maps.
+	 */
+	@SuppressWarnings("hiding")
+	public class PropertyMap {
+
+		private final Map<String,Property> map = new ConcurrentSkipListMap<String,Property>();
+		private volatile int hashCode = 0;
+		private final ReadWriteLock lock = new ReentrantReadWriteLock();
+		private final Lock rl = lock.readLock(), wl = lock.writeLock();
+		private final String prefix;
+
+		private PropertyMap(String prefix) {
+			this.prefix = prefix;
+			prefix = prefix + '.';
+			Properties p = System.getProperties();
+			for (Map.Entry<Object,Object> e : p.entrySet())
+				if (e.getKey().toString().startsWith(prefix))
+					set(e.getKey().toString(), e.getValue());
+		}
+
+		/**
+		 * Copy constructor.
+		 */
+		private PropertyMap(PropertyMap orig, PropertyMap apply) {
+			this.prefix = apply.prefix;
+			if (orig != null)
+				for (Map.Entry<String,Property> e : orig.map.entrySet())
+					this.map.put(e.getKey(), Property.create(e.getValue().name, e.getValue().value()));
+			for (Map.Entry<String,Property> e : apply.map.entrySet()) {
+				Property prev = this.map.get(e.getKey());
+				if (prev == null || "SIMPLE".equals(prev.type))
+					this.map.put(e.getKey(), Property.create(e.getValue().name, e.getValue().value()));
+				else {
+					if ("SET".equals(prev.type) || "LIST".equals(prev.type))
+						prev.add(e.getValue().value());
+					else if ("MAP".equals(prev.type))
+						prev.put(e.getValue().value());
+				}
+			}
+		}
+
+		/**
+		 * Returns the specified property as the specified class type.
+		 *
+		 * @param name The property name.
+		 * @param type The type of object to convert the value to.
+		 * @param def The default value if the specified property is not set.
+		 *
+		 * @return The property value.
+		 */
+		public <T> T get(String name, Class<T> type, T def) {
+			rl.lock();
+			try {
+				Property p = map.get(name);
+				if (p == null || type == null)
+					return def;
+				try {
+					if (! isBeanSessionAvailable())
+						return def;
+					return getBeanSession().convertToType(p.value, type);
+				} catch (InvalidDataConversionException e) {
+					throw new ConfigException("Could not retrieve property store property ''{0}''.  {1}", p.name, e.getMessage());
+				}
+			} finally {
+				rl.unlock();
+			}
+		}
+
+		/**
+		 * Returns the specified property as a map with the specified key and value types.
+		 * <p>
+		 * The map returned is an instance of {@link LinkedHashMap}.
+		 *
+		 * @param name The property name.
+		 * @param keyType The class type of the keys of the map.
+		 * @param valueType The class type of the values of the map.
+		 * @param def The default value if the specified property is not set.
+		 *
+		 * @return The property value.
+		 */
+		@SuppressWarnings("unchecked")
+		public <K,V> Map<K,V> getMap(String name, Class<K> keyType, Class<V> valueType, Map<K,V> def) {
+			rl.lock();
+			try {
+				Property p = map.get(name);
+				if (p == null || keyType == null || valueType == null)
+					return def;
+				try {
+					if (isBeanSessionAvailable()) {
+						BeanSession session = getBeanSession();
+						return (Map<K,V>)session.convertToType(p.value, session.getClassMeta(LinkedHashMap.class, keyType, valueType));
+					}
+					return def;
+				} catch (InvalidDataConversionException e) {
+					throw new ConfigException("Could not retrieve property store property ''{0}''.  {1}", p.name, e.getMessage());
+				}
+			} finally {
+				rl.unlock();
+			}
+		}
+
+		/**
+		 * Convenience method for returning all values in this property map as a simple map.
+		 * <p>
+		 * Primarily useful for debugging.
+		 *
+		 * @return A new {@link LinkedHashMap} with all values in this property map.
+		 */
+		public Map<String,Object> asMap() {
+			rl.lock();
+			try {
+				Map<String,Object> m = new LinkedHashMap<String,Object>();
+				for (Property p : map.values())
+					m.put(p.name, p.value);
+				return m;
+			} finally {
+				rl.unlock();
+			}
+		}
+
+		private void set(String name, Object value) {
+			wl.lock();
+			hashCode = 0;
+			try {
+				if (value == null)
+					map.remove(name);
+				else
+					map.put(name, Property.create(name, value));
+			} finally {
+				wl.unlock();
+			}
+		}
+
+		private void addTo(String name, Object value) {
+			wl.lock();
+			hashCode = 0;
+			try {
+				if (! map.containsKey(name))
+					map.put(name, Property.create(name, Collections.emptyList()));
+				map.get(name).add(value);
+			} finally {
+				wl.unlock();
+			}
+		}
+
+		private void putTo(String name, Object key, Object value) {
+			wl.lock();
+			hashCode = 0;
+			try {
+				if (! map.containsKey(name))
+					map.put(name, Property.create(name, Collections.emptyMap()));
+				map.get(name).put(key, value);
+			} finally {
+				wl.unlock();
+			}
+		}
+
+		private void putTo(String name, Object value) {
+			wl.lock();
+			hashCode = 0;
+			try {
+				if (! map.containsKey(name))
+					map.put(name, Property.create(name, Collections.emptyMap()));
+				map.get(name).put(value);
+			} finally {
+				wl.unlock();
+			}
+		}
+
+		private void removeFrom(String name, Object value) {
+			wl.lock();
+			hashCode = 0;
+			try {
+				if (map.containsKey(name))
+					map.get(name).remove(value);
+			} finally {
+				wl.unlock();
+			}
+		}
+
+		@Override
+		public int hashCode() {
+			rl.lock();
+			try {
+				if (hashCode == 0) {
+					HashCode c = new HashCode().add(prefix);
+					for (Property p : map.values())
+						c.add(p);
+					this.hashCode = c.get();
+				}
+				return hashCode;
+			} finally {
+				rl.unlock();
+			}
+		}
+
+		@Override
+		public boolean equals(Object o) {
+			rl.lock();
+			try {
+				if (o instanceof PropertyMap) {
+					PropertyMap m = (PropertyMap)o;
+					if (m.hashCode() != hashCode())
+						return false;
+					return this.map.equals(m.map);
+				}
+				return false;
+			} finally {
+				rl.unlock();
+			}
+		}
+
+		@Override
+		public String toString() {
+			return "PropertyMap(id="+System.identityHashCode(this)+")";
+		}
+	}
+
+	private abstract static class Property {
+		private final String name, type;
+		private final Object value;
+
+		private static Property create(String name, Object value) {
+			if (name.endsWith(".set"))
+				return new SetProperty(name, value);
+			else if (name.endsWith(".list"))
+				return new ListProperty(name, value);
+			else if (name.endsWith(".map"))
+				return new MapProperty(name, value);
+			return new SimpleProperty(name, value);
+		}
+
+		Property(String name, String type, Object value) {
+			this.name = name;
+			this.type = type;
+			this.value = value;
+		}
+
+		void add(Object val) {
+			throw new ConfigException("Cannot add value {0} ({1}) to property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
+		}
+
+		void remove(Object val) {
+			throw new ConfigException("Cannot remove value {0} ({1}) from property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
+		}
+
+		void put(Object val) {
+			throw new ConfigException("Cannot put value {0} ({1}) to property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
+		}
+
+		void put(Object key, Object val) {
+			throw new ConfigException("Cannot put value {0}({1})->{2}({3}) to property ''{4}'' ({5}).", JsonSerializer.DEFAULT_LAX.toString(key), ClassUtils.getReadableClassNameForObject(key), JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
+		}
+
+		protected Object value() {
+			return value;
+		}
+
+		@Override /* Object */
+		public int hashCode() {
+			HashCode c = new NormalizingHashCode().add(name);
+			if (value instanceof Map) {
+				for (Map.Entry<?,?> e : ((Map<?,?>)value).entrySet())
+					c.add(e.getKey()).add(e.getValue());
+			} else if (value instanceof Collection) {
+				for (Object o : (Collection<?>)value)
+					c.add(o);
+			} else {
+				c.add(value);
+			}
+			return c.get();
+		}
+
+		@Override
+		public String toString() {
+			return "Property(name="+name+",type="+type+")";
+		}
+	}
+
+	private static class SimpleProperty extends Property {
+
+		SimpleProperty(String name, Object value) {
+			super(name, "SIMPLE", value);
+		}
+	}
+
+	@SuppressWarnings({"unchecked"})
+	private static class SetProperty extends Property {
+		private final Set<Object> value;
+
+		private SetProperty(String name, Object value) {
+			super(name, "SET", new ConcurrentSkipListSet<Object>(PROPERTY_COMPARATOR));
+			this.value = (Set<Object>)value();
+			add(value);
+		}
+
+		@Override
+		void add(Object val) {
+			if (val.getClass().isArray())
+				for (int i = 0; i < Array.getLength(val); i++)
+					add(Array.get(val, i));
+			else if (val instanceof Collection)
+				for (Object o : (Collection<Object>)val)
+					add(o);
+			else {
+				if (val instanceof String) {
+					String s = val.toString();
+					if (s.startsWith("[") && s.endsWith("]")) {
+						try {
+							add(new ObjectList(s));
+							return;
+						} catch (Exception e) {}
+					}
+				}
+				for (Object o : value)
+					if (same(val, o))
+						return;
+				value.add(val);
+			}
+		}
+
+		@Override
+		void remove(Object val) {
+			if (val.getClass().isArray())
+				for (int i = 0; i < Array.getLength(val); i++)
+					remove(Array.get(val, i));
+			else if (val instanceof Collection)
+				for (Object o : (Collection<Object>)val)
+					remove(o);
+			else {
+				if (val instanceof String) {
+					String s = val.toString();
+					if (s.startsWith("[") && s.endsWith("]")) {
+						try {
+							remove(new ObjectList(s));
+							return;
+						} catch (Exception e) {}
+					}
+				}
+				for (Iterator<Object> i = value.iterator(); i.hasNext();)
+					if (same(i.next(), val))
+						i.remove();
+			}
+		}
+	}
+
+	@SuppressWarnings({"unchecked"})
+	private static class ListProperty extends Property {
+		private final LinkedList<Object> value;
+
+		private ListProperty(String name, Object value) {
+			super(name, "LIST", new LinkedList<Object>());
+			this.value = (LinkedList<Object>)value();
+			add(value);
+		}
+
+		@Override
+		void add(Object val) {
+			if (val.getClass().isArray()) {
+				for (int i = Array.getLength(val) - 1; i >= 0; i--)
+					add(Array.get(val, i));
+			} else if (val instanceof List) {
+				List<Object> l = (List<Object>)val;
+				for (ListIterator<Object> i = l.listIterator(l.size()); i.hasPrevious();)
+					add(i.previous());
+			} else if (val instanceof Collection) {
+				List<Object> l = new ArrayList<Object>((Collection<Object>)val);
+				for (ListIterator<Object> i = l.listIterator(l.size()); i.hasPrevious();)
+					add(i.previous());
+			} else {
+				String s = val.toString();
+				if (s.startsWith("[") && s.endsWith("]")) {
+					try {
+						add(new ObjectList(s));
+						return;
+					} catch (Exception e) {}
+				}
+				for (Iterator<Object> i = value.iterator(); i.hasNext(); )
+					if (same(val, i.next()))
+						i.remove();
+				value.addFirst(val);
+			}
+		}
+
+		@Override
+		void remove(Object val) {
+			if (val.getClass().isArray())
+				for (int i = 0; i < Array.getLength(val); i++)
+					remove(Array.get(val, i));
+			else if (val instanceof Collection)
+				for (Object o : (Collection<Object>)val)
+					remove(o);
+			else {
+				String s = val.toString();
+				if (s.startsWith("[") && s.endsWith("]")) {
+					try {
+						remove(new ObjectList(s));
+						return;
+					} catch (Exception e) {}
+				}
+				for (Iterator<Object> i = value.iterator(); i.hasNext();)
+					if (same(i.next(), val))
+						i.remove();
+			}
+		}
+	}
+
+	@SuppressWarnings({"unchecked","rawtypes"})
+	private static class MapProperty extends Property {
+		final Map<Object,Object> value;
+
+		MapProperty(String name, Object value) {
+			// ConcurrentSkipListMap doesn't support Map.Entry.remove(), so use TreeMap instead.
+			super(name, "MAP", Collections.synchronizedMap(new TreeMap<Object,Object>(PROPERTY_COMPARATOR)));
+			this.value = (Map<Object,Object>)value();
+			put(value);
+		}
+
+		@Override
+		void put(Object val) {
+			try {
+				if (isBeanSessionAvailable() && ! (val instanceof Map))
+					val = getBeanSession().convertToType(val, Map.class);
+				if (val instanceof Map) {
+					Map m = (Map)val;
+					for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
+						put(e.getKey(), e.getValue());
+					return;
+				}
+			} catch (Exception e) {}
+			super.put(val);
+		}
+
+		@Override
+		void put(Object key, Object val) {
+			// ConcurrentSkipListMap doesn't support Map.Entry.remove().
+			for (Map.Entry<Object,Object> e : value.entrySet()) {
+				if (same(e.getKey(), key)) {
+					e.setValue(val);
+					return;
+				}
+			}
+			value.put(key, val);
+		}
+	}
+
+	/**
+	 * Converts an object to a normalized form for comparison purposes.
+	 *
+	 * @param o The object to normalize.
+	 * @return The normalized object.
+	 */
+	private static final Object unswap(Object o) {
+		if (o instanceof Class)
+			return ((Class<?>)o).getName();
+		if (o instanceof Number || o instanceof Boolean)
+			return o.toString();
+		return o;
+	}
+
+	private static BeanSession getBeanSession() {
+		if (beanSession == null && BeanContext.DEFAULT != null)
+			beanSession = BeanContext.DEFAULT.createSession();
+		return beanSession;
+	}
+
+	/**
+	 * Returns true if a bean session is available.
+	 * Note that a bean session will not be available when constructing the BeanContext.DEFAULT context.
+	 * (it's a chicken-and-egg thing).
+	 */
+	private static boolean isBeanSessionAvailable() {
+		return getBeanSession() != null;
+	}
+
+	/*
+	 * Compares two objects for "string"-equality.
+	 * Basically mean both objects are equal if they're the same when converted to strings.
+	 */
+	@SuppressWarnings({ "rawtypes", "unchecked" })
+	private static boolean same(Object o1, Object o2) {
+		if (o1 == o2)
+			return true;
+		if (o1 instanceof Map) {
+			if (o2 instanceof Map) {
+				Map m1 = (Map)o1, m2 = (Map)o2;
+				if (m1.size() == m2.size()) {
+					Set<Map.Entry> s1 = m1.entrySet(), s2 = m2.entrySet();
+					for (Iterator<Map.Entry> i1 = s1.iterator(), i2 = s2.iterator(); i1.hasNext();) {
+						Map.Entry e1 = i1.next(), e2 = i2.next();
+						if (! same(e1.getKey(), e2.getKey()))
+							return false;
+						if (! same(e1.getValue(), e2.getValue()))
+							return false;
+					}
+					return true;
+				}
+			}
+			return false;
+		} else if (o1 instanceof Collection) {
+			if (o2 instanceof Collection) {
+				Collection c1 = (Collection)o1, c2 = (Collection)o2;
+				if (c1.size() == c2.size()) {
+					for (Iterator i1 = c1.iterator(), i2 = c2.iterator(); i1.hasNext();) {
+						if (! same(i1.next(), i2.next()))
+							return false;
+					}
+					return true;
+				}
+			}
+			return false;
+		} else {
+			return unswap(o1).equals(unswap(o2));
+		}
+	}
+
+	private String prefix(String name) {
+		if (name == null)
+			throw new ConfigException("Invalid property name specified: 'null'");
+		if (name.indexOf('.') == -1)
+			return "";
+		return name.substring(0, name.indexOf('.'));
+	}
+
+	private String className(Object o) {
+		if (o == null)
+			return null;
+		if (o instanceof Class)
+			return ClassUtils.getReadableClassName((Class<?>)o);
+		return ClassUtils.getReadableClassName(o.getClass());
+	}
+
+	@Override /* Object */
+	public String toString() {
+		rl.lock();
+		try {
+			ObjectMap m = new ObjectMap();
+			m.put("id", System.identityHashCode(this));
+			m.put("hashCode", hashCode());
+			m.put("properties.id", System.identityHashCode(properties));
+			m.put("contexts.id", System.identityHashCode(contexts));
+			m.put("properties", properties);
+			m.put("contexts", contexts);
+			return m.toString();
+		} finally {
+			rl.unlock();
+		}
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/Session.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/Session.java b/juneau-core/src/main/java/org/apache/juneau/Session.java
index b870421..e0864e1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/Session.java
+++ b/juneau-core/src/main/java/org/apache/juneau/Session.java
@@ -26,7 +26,7 @@ import org.apache.juneau.serializer.*;
  * Serializers and parsers use session objects to retrieve config properties and to use it
  * 	as a scratchpad during serialize and parse actions.
  *
- * @see ContextFactory
+ * @see PropertyStore
  */
 public abstract class Session {
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java b/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
index 18897a1..1a4a5d5 100644
--- a/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
+++ b/juneau-core/src/main/java/org/apache/juneau/annotation/Pojo.java
@@ -75,8 +75,8 @@ public @interface Pojo {
 	 * <p>
 	 * Note that using this annotation is functionally equivalent to adding swaps to the serializers and parsers:
 	 * <p class='bcode'>
-	 * 	WriterSerializer s = <jk>new</jk> JsonSerializer.addPojoSwaps(BSwap.<jk>class</jk>);
-	 * 	ReaderParser p = <jk>new</jk> JsonParser.addPojoSwaps(BSwap.<jk>class</jk>);
+	 * 	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(BSwap.<jk>class</jk>).build();
+	 * 	ReaderParser p = <jk>new</jk> JsonParserBuilder().pojoSwaps(BSwap.<jk>class</jk>).build();
 	 * </p>
 	 */
 	Class<?> swap() default Null.class;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParser.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParser.java
new file mode 100644
index 0000000..753e85c
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParser.java
@@ -0,0 +1,60 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * TODO - Work in progress.  CSV parser.
+ */
+@Consumes("text/csv")
+public class CsvParser extends ReaderParser {
+
+	/** Default parser, all default settings.*/
+	public static final CsvParser DEFAULT = new CsvParser(PropertyStore.create());
+
+	
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public CsvParser(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public CsvParserBuilder builder() {
+		return new CsvParserBuilder(propertyStore);
+	}
+
+	@SuppressWarnings("unused")
+	private <T> T parseAnything(ParserSession session, ClassMeta<T> eType, ParserReader r, Object outer, BeanPropertyMeta pMeta) throws Exception {
+		throw new NoSuchMethodException("Not implemented.");
+	}
+
+	//--------------------------------------------------------------------------------
+	// Entry point methods
+	//--------------------------------------------------------------------------------
+
+	@Override /* Parser */
+	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
+		CsvParserSession s = (CsvParserSession)session;
+		ParserReader r = s.getReader();
+		if (r == null)
+			return null;
+		T o = parseAnything(s, type, r, s.getOuter(), null);
+		return o;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
new file mode 100644
index 0000000..a8d1fb1
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserBuilder.java
@@ -0,0 +1,456 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building instances of CSV parsers.
+ */
+public class CsvParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public CsvParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public CsvParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParser build() {
+		return new CsvParser(propertyStore);
+	}
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* ParserBuilder */
+	public CsvParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public CsvParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public CsvParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public CsvParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public CsvParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CsvParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public CsvParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserContext.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserContext.java
new file mode 100644
index 0000000..17c1c34
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserContext.java
@@ -0,0 +1,53 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Configurable properties on the {@link CsvParser} class.
+ * <p>
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
+ * <p>
+ * See {@link PropertyStore} for more information about context properties.
+ *
+ * <h5 class='section'>Inherited configurable properties:</h5>
+ * <ul class='javahierarchy'>
+ * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
+ * 	<ul>
+ * 		<li class='c'><a class="doclink" href="../parser/ParserContext.html#ConfigProperties">ParserContext</a> - Configurable properties common to all parsers.
+ * 	</ul>
+ * </ul>
+ */
+public final class CsvParserContext extends ParserContext {
+
+	/**
+	 * Constructor.
+	 * <p>
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
+	 *
+	 * @param ps The property store that created this context.
+	 */
+	public CsvParserContext(PropertyStore ps) {
+		super(ps);
+	}
+
+	@Override /* Context */
+	public ObjectMap asMap() {
+		return super.asMap()
+			.append("CsvParserContext", new ObjectMap()
+		);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserSession.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserSession.java
new file mode 100644
index 0000000..151b8b6
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvParserSession.java
@@ -0,0 +1,111 @@
+// ***************************************************************************************************************************
+// * 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.csv;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Session object that lives for the duration of a single use of {@link CsvParser}.
+ * <p>
+ * This class is NOT thread safe.  It is meant to be discarded after one-time use.
+ */
+public final class CsvParserSession extends ParserSession {
+
+	private ParserReader reader;
+
+	/**
+	 * Create a new session using properties specified in the context.
+	 *
+	 * @param ctx The context creating this session object.
+	 * The context contains all the configuration settings for this object.
+	 * @param input The input.  Can be any of the following types:
+	 * <ul>
+	 * 	<li><jk>null</jk>
+	 * 	<li>{@link Reader}
+	 * 	<li>{@link CharSequence}
+	 * 	<li>{@link InputStream} containing UTF-8 encoded text.
+	 * 	<li>{@link File} containing system encoded text.
+	 * </ul>
+	 * @param op The override properties.
+	 * These override any context properties defined in the context.
+	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param outer The outer object for instantiating top-level non-static inner classes.
+	 * @param locale The session locale.
+	 * If <jk>null</jk>, then the locale defined on the context is used.
+	 * @param timeZone The session timezone.
+	 * If <jk>null</jk>, then the timezone defined on the context is used.
+	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
+	 */
+	public CsvParserSession(CsvParserContext ctx, ObjectMap op, Object input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
+		super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
+	}
+
+	@Override /* ParserSession */
+	public ParserReader getReader() throws Exception {
+		if (reader == null) {
+			Object input = getInput();
+			if (input == null)
+				return null;
+			if (input instanceof CharSequence)
+				reader = new ParserReader((CharSequence)input);
+			else
+				reader = new ParserReader(super.getReader());
+		}
+		return reader;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified character is whitespace.
+	 * <p>
+	 * The definition of whitespace is different for strict vs lax mode.
+	 * Strict mode only interprets 0x20 (space), 0x09 (tab), 0x0A (line feed) and 0x0D (carriage return) as whitespace.
+	 * Lax mode uses {@link Character#isWhitespace(int)} to make the determination.
+	 *
+	 * @param cp The codepoint.
+	 * @return <jk>true</jk> if the specified character is whitespace.
+	 */
+	public final boolean isWhitespace(int cp) {
+		if (isStrict())
+			return cp <= 0x20 && (cp == 0x09 || cp == 0x0A || cp == 0x0D || cp == 0x20);
+		return Character.isWhitespace(cp);
+	}
+
+	/**
+	 * Returns <jk>true</jk> if the specified character is whitespace or '/'.
+	 *
+	 * @param cp The codepoint.
+	 * @return <jk>true</jk> if the specified character is whitespace or '/'.
+	 */
+	public final boolean isCommentOrWhitespace(int cp) {
+		if (cp == '/')
+			return true;
+		if (isStrict())
+			return cp <= 0x20 && (cp == 0x09 || cp == 0x0A || cp == 0x0D || cp == 0x20);
+		return Character.isWhitespace(cp);
+	}
+
+	@Override /* ParserSession */
+	public Map<String,Object> getLastLocation() {
+		Map<String,Object> m = super.getLastLocation();
+		if (reader != null) {
+			m.put("line", reader.getLine());
+			m.put("column", reader.getColumn());
+		}
+		return m;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java
index db04ea0..c2a21df 100644
--- a/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/csv/CsvSerializer.java
@@ -26,6 +26,23 @@ import org.apache.juneau.serializer.*;
 @SuppressWarnings({"rawtypes"})
 public final class CsvSerializer extends WriterSerializer {
 
+	/** Default serializer, all default settings.*/
+	public static final CsvSerializer DEFAULT = new CsvSerializer(PropertyStore.create());
+
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public CsvSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	public CsvSerializerBuilder builder() {
+		return new CsvSerializerBuilder(propertyStore);
+	}
+
 	//--------------------------------------------------------------------------------
 	// Entry point methods
 	//--------------------------------------------------------------------------------
@@ -65,7 +82,7 @@ public final class CsvSerializer extends WriterSerializer {
 		}
 	}
 
-	private void append(Writer w, Object o) throws IOException {
+	private static void append(Writer w, Object o) throws IOException {
 		if (o == null)
 			w.append("null");
 		else {
@@ -82,18 +99,4 @@ public final class CsvSerializer extends WriterSerializer {
 				w.append(s);
 		}
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Serializer */
-	public CsvSerializer clone() {
-		try {
-			return (CsvSerializer)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen.
-		}
-	}
 }


[07/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
new file mode 100644
index 0000000..6cdf163
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializerBuilder.java
@@ -0,0 +1,570 @@
+// ***************************************************************************************************************************
+// * 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.xml;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Builder class for building instances of XML Schema serializers.
+ */
+public class XmlSchemaSerializerBuilder extends XmlSerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public XmlSchemaSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public XmlSchemaSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializer build() {
+		return new XmlSchemaSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder enableNamespaces(boolean value) {
+		super.enableNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder ns() {
+		super.ns();
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder autoDetectNamespaces(boolean value) {
+		super.autoDetectNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder addNamespaceUrisToRoot(boolean value) {
+		super.addNamespaceUrisToRoot(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder defaultNamespace(String value) {
+		super.defaultNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder xsNamespace(Namespace value) {
+		super.xsNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public XmlSchemaSerializerBuilder namespaces(Namespace...values) {
+		super.namespaces(values);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSchemaSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> XmlSchemaSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSchemaSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
index 3091056..da39582 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializer.java
@@ -12,10 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.xml;
 
-import static org.apache.juneau.xml.XmlSerializerContext.*;
-import static org.apache.juneau.xml.annotation.XmlFormat.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
 import static org.apache.juneau.xml.XmlSerializer.ContentResult.*;
 import static org.apache.juneau.xml.XmlSerializer.JsonType.*;
+import static org.apache.juneau.xml.XmlSerializerContext.*;
+import static org.apache.juneau.xml.annotation.XmlFormat.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -125,64 +126,128 @@ import org.apache.juneau.xml.annotation.*;
 public class XmlSerializer extends WriterSerializer {
 
 	/** Default serializer without namespaces. */
-	public static final XmlSerializer DEFAULT = new XmlSerializer().lock();
+	public static final XmlSerializer DEFAULT = new XmlSerializer(PropertyStore.create());
 
 	/** Default serializer without namespaces, with single quotes. */
-	public static final XmlSerializer DEFAULT_SQ = new XmlSerializer.Sq().lock();
+	public static final XmlSerializer DEFAULT_SQ = new Sq(PropertyStore.create());
 
 	/** Default serializer without namespaces, with single quotes, whitespace added. */
-	public static final XmlSerializer DEFAULT_SQ_READABLE = new XmlSerializer.SqReadable().lock();
+	public static final XmlSerializer DEFAULT_SQ_READABLE = new SqReadable(PropertyStore.create());
 
 	/** Default serializer, all default settings. */
-	public static final XmlSerializer DEFAULT_NS = new XmlSerializer.Ns().lock();
+	public static final XmlSerializer DEFAULT_NS = new Ns(PropertyStore.create());
 
 	/** Default serializer, single quotes. */
-	public static final XmlSerializer DEFAULT_NS_SQ = new XmlSerializer.NsSq().lock();
+	public static final XmlSerializer DEFAULT_NS_SQ = new NsSq(PropertyStore.create());
 
 	/** Default serializer, single quotes, whitespace added. */
-	public static final XmlSerializer DEFAULT_NS_SQ_READABLE = new XmlSerializer.NsSqReadable().lock();
+	public static final XmlSerializer DEFAULT_NS_SQ_READABLE = new NsSqReadable(PropertyStore.create());
+
 
 	/** Default serializer, single quotes. */
 	public static class Sq extends XmlSerializer {
-		/** Constructor */
-		public Sq() {
-			setQuoteChar('\'');
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Sq(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_quoteChar, '\'');
 		}
 	}
 
 	/** Default serializer, single quotes, whitespace added. */
-	public static class SqReadable extends Sq {
-		/** Constructor */
-		public SqReadable() {
-			setUseWhitespace(true);
+	public static class SqReadable extends XmlSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public SqReadable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_quoteChar, '\'').append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
 	/** Default serializer without namespaces. */
 	@Produces(value="text/xml+simple",contentType="text/xml")
 	public static class Ns extends XmlSerializer {
-		/** Constructor */
-		public Ns() {
-			setEnableNamespaces(true);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Ns(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(XML_enableNamespaces, true);
 		}
 	}
 
 	/** Default serializer without namespaces, single quotes. */
-	public static class NsSq extends Ns {
-		/** Constructor */
-		public NsSq() {
-			setQuoteChar('\'');
+	public static class NsSq extends XmlSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public NsSq(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(XML_enableNamespaces, true).append(SERIALIZER_quoteChar, '\'');
 		}
 	}
 
 	/** Default serializer without namespaces, single quotes, with whitespace. */
-	public static class NsSqReadable extends NsSq {
-		/** Constructor */
-		public NsSqReadable() {
-			setUseWhitespace(true);
+	public static class NsSqReadable extends XmlSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public NsSqReadable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(XML_enableNamespaces, true).append(SERIALIZER_quoteChar, '\'').append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
+
+	private final XmlSerializerContext ctx;
+	private volatile XmlSchemaSerializer schemaSerializer;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public XmlSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(XmlSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public XmlSerializerBuilder builder() {
+		return new XmlSerializerBuilder(propertyStore);
+	}
+
 	/**
 	 * Recursively searches for the XML namespaces on the specified POJO and adds them to the serializer context object.
 	 *
@@ -717,8 +782,9 @@ public class XmlSerializer extends WriterSerializer {
 	 * @return The schema serializer.
 	 */
 	public XmlSerializer getSchemaSerializer() {
-		XmlSchemaSerializer s = new XmlSchemaSerializer(getContextFactory());
-		return s;
+		if (schemaSerializer == null)
+			schemaSerializer = new XmlSchemaSerializer(propertyStore, getOverrideProperties());
+		return schemaSerializer;
 	}
 
 	static enum JsonType {
@@ -767,677 +833,6 @@ public class XmlSerializer extends WriterSerializer {
 
 	@Override /* Serializer */
 	public XmlSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Enable support for XML namespaces.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.enableNamespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If not enabled, XML output will not contain any namespaces regardless of any other settings.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_enableNamespaces</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_enableNamespaces
-	 */
-	public XmlSerializer setEnableNamespaces(boolean value) throws LockedException {
-		return setProperty(XML_enableNamespaces, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Auto-detect namespace usage.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.autoDetectNamespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Detect namespace usage before serialization.
-	 * <p>
-	 * Used in conjunction with {@link XmlSerializerContext#XML_addNamespaceUrisToRoot} to reduce
-	 * the list of namespace URLs appended to the root element to only those
-	 * that will be used in the resulting document.
-	 * <p>
-	 * If enabled, then the data structure will first be crawled looking for
-	 * namespaces that will be encountered before the root element is
-	 * serialized.
-	 * <p>
-	 * This setting is ignored if {@link XmlSerializerContext#XML_enableNamespaces} is not enabled.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>Auto-detection of namespaces can be costly performance-wise.
-	 * 		In high-performance environments, it's recommended that namespace detection be
-	 * 		disabled, and that namespaces be manually defined through the {@link XmlSerializerContext#XML_namespaces} property.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_autoDetectNamespaces</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_autoDetectNamespaces
-	 */
-	public XmlSerializer setAutoDetectNamespaces(boolean value) throws LockedException {
-		return setProperty(XML_autoDetectNamespaces, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add namespace URLs to the root element.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.addNamespaceUrisToRoot"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Use this setting to add {@code xmlns:x} attributes to the root
-	 * element for the default and all mapped namespaces.
-	 * <p>
-	 * This setting is ignored if {@link XmlSerializerContext#XML_enableNamespaces} is not enabled.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_addNamespaceUrisToRoot</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_addNamespaceUrisToRoot
-	 */
-	public XmlSerializer setAddNamespaceUrisToRoot(boolean value) throws LockedException {
-		return setProperty(XML_addNamespaceUrisToRoot, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default namespace.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.defaultNamespace"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"{juneau:'http://www.apache.org/2013/Juneau'}"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specifies the default namespace URI for this document.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_defaultNamespace</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_defaultNamespace
-	 */
-	public XmlSerializer setDefaultNamespace(String value) throws LockedException {
-		return setProperty(XML_defaultNamespace, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XMLSchema namespace.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.xsNamespace"</js>
-	 * 	<li><b>Data type:</b> {@link Namespace}
-	 * 	<li><b>Default:</b> <code>{name:<js>'xs'</js>,uri:<js>'http://www.w3.org/2001/XMLSchema'</js>}</code>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specifies the namespace for the <code>XMLSchema</code> namespace, used by the schema generated
-	 * by the {@link XmlSchemaSerializer} class.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_xsNamespace</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_xsNamespace
-	 */
-	public XmlSerializer setXsNamespace(Namespace value) throws LockedException {
-		return setProperty(XML_xsNamespace, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default namespaces.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlSerializer.namespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Set&lt;{@link Namespace}&gt;</code>
-	 * 	<li><b>Default:</b> empty set
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * The default list of namespaces associated with this serializer.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_namespaces</jsf>, values)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlSerializerContext#XML_namespaces
-	 */
-	public XmlSerializer setNamespaces(Namespace...values) throws LockedException {
-		return setProperty(XML_namespaces, values);
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public XmlSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public XmlSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public XmlSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public XmlSerializer clone() {
-		try {
-			XmlSerializer c = (XmlSerializer)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen.
-		}
+		return new XmlSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
new file mode 100644
index 0000000..d9f9a53
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerBuilder.java
@@ -0,0 +1,717 @@
+// ***************************************************************************************************************************
+// * 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.xml;
+
+import static org.apache.juneau.xml.XmlSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of XML serializers.
+ */
+public class XmlSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public XmlSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public XmlSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializer build() {
+		return new XmlSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Enable support for XML namespaces.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.enableNamespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If not enabled, XML output will not contain any namespaces regardless of any other settings.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_enableNamespaces</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_enableNamespaces
+	 */
+	public XmlSerializerBuilder enableNamespaces(boolean value) {
+		return property(XML_enableNamespaces, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>setEnableNamespaces(<jk>true</jk>)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public XmlSerializerBuilder ns() {
+		return enableNamespaces(true);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Auto-detect namespace usage.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.autoDetectNamespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Detect namespace usage before serialization.
+	 * <p>
+	 * Used in conjunction with {@link XmlSerializerContext#XML_addNamespaceUrisToRoot} to reduce
+	 * the list of namespace URLs appended to the root element to only those
+	 * that will be used in the resulting document.
+	 * <p>
+	 * If enabled, then the data structure will first be crawled looking for
+	 * namespaces that will be encountered before the root element is
+	 * serialized.
+	 * <p>
+	 * This setting is ignored if {@link XmlSerializerContext#XML_enableNamespaces} is not enabled.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>Auto-detection of namespaces can be costly performance-wise.
+	 * 		In high-performance environments, it's recommended that namespace detection be
+	 * 		disabled, and that namespaces be manually defined through the {@link XmlSerializerContext#XML_namespaces} property.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_autoDetectNamespaces</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_autoDetectNamespaces
+	 */
+	public XmlSerializerBuilder autoDetectNamespaces(boolean value) {
+		return property(XML_autoDetectNamespaces, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add namespace URLs to the root element.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.addNamespaceUrisToRoot"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Use this setting to add {@code xmlns:x} attributes to the root
+	 * element for the default and all mapped namespaces.
+	 * <p>
+	 * This setting is ignored if {@link XmlSerializerContext#XML_enableNamespaces} is not enabled.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_addNamespaceUrisToRoot</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_addNamespaceUrisToRoot
+	 */
+	public XmlSerializerBuilder addNamespaceUrisToRoot(boolean value) {
+		return property(XML_addNamespaceUrisToRoot, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default namespace.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.defaultNamespace"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"{juneau:'http://www.apache.org/2013/Juneau'}"</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specifies the default namespace URI for this document.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_defaultNamespace</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_defaultNamespace
+	 */
+	public XmlSerializerBuilder defaultNamespace(String value) {
+		return property(XML_defaultNamespace, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XMLSchema namespace.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.xsNamespace"</js>
+	 * 	<li><b>Data type:</b> {@link Namespace}
+	 * 	<li><b>Default:</b> <code>{name:<js>'xs'</js>,uri:<js>'http://www.w3.org/2001/XMLSchema'</js>}</code>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specifies the namespace for the <code>XMLSchema</code> namespace, used by the schema generated
+	 * by the {@link XmlSchemaSerializer} class.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_xsNamespace</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_xsNamespace
+	 */
+	public XmlSerializerBuilder xsNamespace(Namespace value) {
+		return property(XML_xsNamespace, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default namespaces.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlSerializer.namespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Set&lt;{@link Namespace}&gt;</code>
+	 * 	<li><b>Default:</b> empty set
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * The default list of namespaces associated with this serializer.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_namespaces</jsf>, values)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlSerializerContext#XML_namespaces
+	 */
+	public XmlSerializerBuilder namespaces(Namespace...values) {
+		return property(XML_namespaces, values);
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public XmlSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> XmlSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
index cac3b8a..a431fc6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.serializer.*;
 /**
  * Configurable properties on the {@link XmlSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -174,19 +174,19 @@ public class XmlSerializerContext extends SerializerContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public XmlSerializerContext(ContextFactory cf) {
-		super(cf);
-		autoDetectNamespaces = cf.getProperty(XML_autoDetectNamespaces, boolean.class, true);
-		enableNamespaces = cf.getProperty(XML_enableNamespaces, boolean.class, false);
-		addNamespaceUrlsToRoot = cf.getProperty(XML_addNamespaceUrisToRoot, boolean.class, false);
-		defaultNamespace = cf.getProperty(XML_defaultNamespace, String.class, "{juneau:'http://www.apache.org/2013/Juneau'}");
-		xsNamespace = cf.getProperty(XML_xsNamespace, Namespace.class, new Namespace("xs", "http://www.w3.org/2001/XMLSchema"));
-		namespaces = cf.getProperty(XML_namespaces, Namespace[].class, new Namespace[0]);
-		addBeanTypeProperties = cf.getProperty(XML_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	public XmlSerializerContext(PropertyStore ps) {
+		super(ps);
+		autoDetectNamespaces = ps.getProperty(XML_autoDetectNamespaces, boolean.class, true);
+		enableNamespaces = ps.getProperty(XML_enableNamespaces, boolean.class, false);
+		addNamespaceUrlsToRoot = ps.getProperty(XML_addNamespaceUrisToRoot, boolean.class, false);
+		defaultNamespace = ps.getProperty(XML_defaultNamespace, String.class, "{juneau:'http://www.apache.org/2013/Juneau'}");
+		xsNamespace = ps.getProperty(XML_xsNamespace, Namespace.class, new Namespace("xs", "http://www.w3.org/2001/XMLSchema"));
+		namespaces = ps.getProperty(XML_namespaces, Namespace[].class, new Namespace[0]);
+		addBeanTypeProperties = ps.getProperty(XML_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
index 36c8a03..824b01e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSerializerSession.java
@@ -53,7 +53,7 @@ public class XmlSerializerSession extends SerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/package.html b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
index 5b91afe..4d9d595 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/package.html
@@ -237,10 +237,11 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new serializer with readable output, no namespaces yet.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>)
-		.setEnableNamespaces(<jk>false</jk>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder()
+		.ws()  <jc>// or .useWhitespace(true)</jc>  
+		.sq()  <jc>// or .quoteChar('\'')</jc>
+		.ns()  <jc>// or .enableNamespaces(false)</jc>
+		.build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>);
@@ -253,8 +254,10 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new serializer with readable output, no namespaces yet, but use cloning method.</jc>
-	XmlSerializer s = XmlSerializer.<jsf>DEFAULT_SQ_READABLE</jsf>.clone()
-		.setEnableNamespaces(<jk>false</jk>);
+	XmlSerializer s = XmlSerializer.<jsf>DEFAULT_SQ_READABLE</jsf>
+		.builder()
+		.ns()
+		.build();
 	</p>
 	<p>
 		The code above produces the following output:
@@ -1983,10 +1986,7 @@
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output, this time with namespaces enabled.</jc>
 	<jc>// Note that this is identical to XmlSerializer.DEFAULT_NS_SQ_READABLE.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setEnableNamespaces(<jk>true</jk>)
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().ns().ws().sq().build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>);
@@ -2072,11 +2072,12 @@
 				all the elements do not need to be prefixed:
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output, this time with namespaces enabled.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>)
-		.setEnableNamespaces(<jk>true</jk>)
-		.setDefaultNamespaceUri(<js>"http://www.apache.org/person/"</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder()
+		.ws()
+		.sq()
+		.ns()
+		.defaultNamespaceUri(<js>"http://www.apache.org/person/"</js>)
+		.build();
 		</p>
 		<p>
 			This produces the following equivalent where the elements don't need prefixes since they're already in the default document namespace:
@@ -2106,11 +2107,12 @@
 			</p>
 			<p class='bcode'>
 	<jc>// Create a new serializer with readable output, this time with namespaces enabled.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>)
-		.setAutoDetectNamespaces(<jk>false</jk>)
-		.setNamespaces(<js>"{per:'http://www.apache.org/person/'}"</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder()
+		.ws()
+		.sq()
+		.autoDetectNamespaces(<jk>false</jk>)
+		.namespaces(<js>"{per:'http://www.apache.org/person/'}"</js>)
+		.build();
 			</p>
 		</div>
 		
@@ -2240,9 +2242,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().ws().sq().build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
@@ -2353,11 +2353,12 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setEnableNamespaces(<jk>true</jk>)
-		.setAddNamespaceUrisToRoot(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder()
+		.ws()
+		.ns()
+		.sq()
+		.addNamespaceUrisToRoot(<jk>true</jk>)
+		.build();
 
 	<jc>// Create the equivalent schema serializer.</jc>
 	XmlSchemaSerializer ss = s.getSchemaSerializer();
@@ -2655,11 +2656,12 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>)
-		.setEnableNamespaces(<jk>false</jk>)
-		.setDetectRecursions(<jk>true</jk>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder()
+		.ws()
+		.sq()
+		.ns()
+		.detectRecursions(<jk>true</jk>)
+		.build();
 
 	<jc>// Create a recursive loop.</jc>
 	A a = <jk>new</jk> A();
@@ -2735,10 +2737,7 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer()
-		.setEnableNamespaces(<jk>true</jk>)
-		.setUseIndentation(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().ws().sq().ns().build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
@@ -3191,7 +3190,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a client to handle XML requests and responses.</jc>
-	RestClient client = <jk>new</jk> RestClient(XmlSerializer.<jk>class</jk>, XmlParser.<jk>class</jk>);
+	RestClient client = <jk>new</jk> RestClientBuilder(XmlSerializer.<jk>class</jk>, XmlParser.<jk>class</jk>).build();
 		</p>
 		<p>
 			The client handles all content negotiation based on the registered serializers and parsers.


[19/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
new file mode 100644
index 0000000..3e68801
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserBuilder.java
@@ -0,0 +1,457 @@
+// ***************************************************************************************************************************
+// * 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.msgpack;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building instances of MessagePack parsers.
+ */
+public class MsgPackParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public MsgPackParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public MsgPackParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParser build() {
+		return new MsgPackParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* ParserBuilder */
+	public MsgPackParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public MsgPackParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public MsgPackParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public MsgPackParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public MsgPackParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> MsgPackParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
index 267305f..d8406ac 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.parser.*;
 /**
  * Configurable properties on the {@link MsgPackParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -36,18 +36,18 @@ public final class MsgPackParserContext extends ParserContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public MsgPackParserContext(ContextFactory cf) {
-		super(cf);
+	public MsgPackParserContext(PropertyStore ps) {
+		super(ps);
 	}
 
 	@Override /* Context */
 	public ObjectMap asMap() {
 		return super.asMap()
 			.append("MsgPackParserContext", new ObjectMap()
-			);
+		);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
index 6829b17..24a40e7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackParserSession.java
@@ -17,7 +17,6 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.MediaType;
 import org.apache.juneau.parser.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
index 123155d..9834195 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializer.java
@@ -42,7 +42,24 @@ import org.apache.juneau.transform.*;
 public class MsgPackSerializer extends OutputStreamSerializer {
 
 	/** Default serializer, all default settings.*/
-	public static final MsgPackSerializer DEFAULT = new MsgPackSerializer().lock();
+	public static final MsgPackSerializer DEFAULT = new MsgPackSerializer(PropertyStore.create());
+
+
+	private final MsgPackSerializerContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public MsgPackSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(MsgPackSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public MsgPackSerializerBuilder builder() {
+		return new MsgPackSerializerBuilder(propertyStore);
+	}
 
 	/**
 	 * Workhorse method. Determines the type of object, and then calls the
@@ -194,7 +211,7 @@ public class MsgPackSerializer extends OutputStreamSerializer {
 
 	@Override /* Serializer */
 	public MsgPackSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new MsgPackSerializerSession(getContext(MsgPackSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new MsgPackSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* Serializer */
@@ -202,492 +219,4 @@ public class MsgPackSerializer extends OutputStreamSerializer {
 		MsgPackSerializerSession s = (MsgPackSerializerSession)session;
 		serializeAnything(s, s.getOutputStream(), o, null, "root", null);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	@Override /* Serializer */
-	public MsgPackSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public MsgPackSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public MsgPackSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public MsgPackSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public MsgPackSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public MsgPackSerializer clone() {
-		try {
-			MsgPackSerializer c = (MsgPackSerializer)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
new file mode 100644
index 0000000..de0fb45
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerBuilder.java
@@ -0,0 +1,528 @@
+// ***************************************************************************************************************************
+// * 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.msgpack;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Builder class for building instances of MessagePack serializers.
+ */
+public class MsgPackSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public MsgPackSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public MsgPackSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializer build() {
+		return new MsgPackSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public MsgPackSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> MsgPackSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public MsgPackSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
index e74a041..6f6a75d 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerContext.java
@@ -18,10 +18,10 @@ import org.apache.juneau.serializer.*;
 /**
  * Configurable properties on the {@link MsgPackSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -58,13 +58,13 @@ public final class MsgPackSerializerContext extends SerializerContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public MsgPackSerializerContext(ContextFactory cf) {
-		super(cf);
-		addBeanTypeProperties = cf.getProperty(MSGPACK_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	public MsgPackSerializerContext(PropertyStore ps) {
+		super(ps);
+		addBeanTypeProperties = ps.getProperty(MSGPACK_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
index c91a11d..43f5324 100644
--- a/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/msgpack/MsgPackSerializerSession.java
@@ -18,7 +18,6 @@ import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.MediaType;
 import org.apache.juneau.json.*;
 import org.apache.juneau.serializer.*;
 
@@ -40,7 +39,7 @@ public final class MsgPackSerializerSession extends SerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getOutputStream()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/package.html b/juneau-core/src/main/java/org/apache/juneau/package.html
index 8f80569..5200d49 100644
--- a/juneau-core/src/main/java/org/apache/juneau/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/package.html
@@ -148,17 +148,14 @@
 	p = beanContext.newBean(Person.<jk>class</jk>);
 		</p>
 		<p>
-			There are 3 ways to get an instance of a {@link org.apache.juneau.BeanContext}:
+			There are 2 ways to get an instance of a {@link org.apache.juneau.BeanContext}:
 		</p>
 		<p class='bcode'>
 	<jc>// Use one of the default bean contexts.</jc>
 	BeanContext beanContext = BeanContext.<jsf>DEFAULT</jsf>;
 	
-	<jc>// Create a context from scratch with your own settings.</jc>
-	beanContext = <jk>new</jk> BeanContext().addPojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
-	
-	<jc>// Clone and modify an existing context.</jc>
-	beanContext = BeanContext.<jsf>DEFAULT</jsf>.clone().addPojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
+	<jc>// Use the PropertyStore class.</jc>
+	beanContext = <jk>new</jk> PropertyStore().pojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>).getBeanContext();
 		</p>
 		<p>
 			The {@link org.apache.juneau.BeanContext} class is a highly-customizable class.  

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java b/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
index f24609a..84a9279 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/InputStreamParser.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.parser;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 
 /**
@@ -33,6 +34,14 @@ import org.apache.juneau.annotation.*;
  */
 public abstract class InputStreamParser extends Parser {
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	protected InputStreamParser(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
 	@Override /* Parser */
 	public boolean isReaderParser() {
 		return false;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
index dab1bf0..53ec4c6 100644
--- a/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/parser/Parser.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.parser;
 
-import static org.apache.juneau.parser.ParserContext.*;
 import static org.apache.juneau.internal.StringUtils.*;
 
 import java.io.*;
@@ -23,8 +22,6 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.parser.ParseException;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.transforms.*;
 import org.apache.juneau.utils.*;
@@ -133,14 +130,18 @@ import org.apache.juneau.utils.*;
  * Passing in <jk>null</jk> or <code>Object.<jk>class</jk></code> typically signifies that it's up to the parser
  * 	to determine what object type is being parsed parsed based on the rules above.
  */
-public abstract class Parser extends CoreApi {
+public abstract class Parser extends CoreObject {
 
-	/** General serializer properties currently set on this serializer. */
+	/** General parser properties currently set on this parser. */
 	private final List<ParserListener> listeners = new LinkedList<ParserListener>();
 	private final MediaType[] mediaTypes;
+	private final ParserContext ctx;
 
 	// Hidden constructor to force subclass from InputStreamParser or ReaderParser.
-	Parser() {
+	Parser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(ParserContext.class);
+
 		Consumes c = ReflectionUtils.getAnnotation(Consumes.class, getClass());
 		if (c == null)
 			throw new RuntimeException(MessageFormat.format("Class ''{0}'' is missing the @Consumes annotation", getClass().getName()));
@@ -152,6 +153,10 @@ public abstract class Parser extends CoreApi {
 		}
 	}
 
+	@Override /* CoreObject */
+	public ParserBuilder builder() {
+		return new ParserBuilder(propertyStore);
+	}
 
 	//--------------------------------------------------------------------------------
 	// Abstract methods
@@ -331,7 +336,7 @@ public abstract class Parser extends CoreApi {
 	 *
 	 * @param input The input.  See {@link #parse(Object, ClassMeta)} for supported input types.
 	 * @param op Optional additional properties.
-	 * @param javaMethod Java method that invoked this serializer.
+	 * @param javaMethod Java method that invoked this parser.
 	 * When using the REST API, this is the Java method invoked by the REST call.
 	 * Can be used to access annotations defined on the method or class.
 	 * @param outer The outer object for instantiating top-level non-static inner classes.
@@ -343,7 +348,7 @@ public abstract class Parser extends CoreApi {
 	 * @return The new session.
 	 */
 	public ParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new ParserSession(getContext(ParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new ParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	/**
@@ -512,11 +517,9 @@ public abstract class Parser extends CoreApi {
 	 * Adds a {@link ParserListener} to this parser to listen for parse events.
 	 *
 	 * @param listener The listener to associate with this parser.
-	 * @throws LockedException If {@link #lock()} was called on this object.
 	 * @return This object (for method chaining).
 	 */
-	public Parser addListener(ParserListener listener) throws LockedException {
-		checkLock();
+	public Parser addListener(ParserListener listener) {
 		this.listeners.add(listener);
 		return this;
 	}
@@ -648,535 +651,4 @@ public abstract class Parser extends CoreApi {
 	public MediaType getPrimaryMediaType() {
 		return mediaTypes == null || mediaTypes.length == 0 ? null : mediaTypes[0];
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Trim parsed strings.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Parser.trimStrings"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>PARSER_trimStrings</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_trimStrings
-	 */
-	public Parser setTrimStrings(boolean value) throws LockedException {
-		return setProperty(PARSER_trimStrings, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Strict mode.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Parser.strict"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, strict mode for the parser is enabled.
-	 * <p>
-	 * Strict mode can mean different things for different parsers.
-	 * <p>
-	 * <table class='styled'>
-	 * 	<tr><th>Parser class</th><th>Strict behavior</th></tr>
-	 * 	<tr>
-	 * 		<td>All reader-based parsers</td>
-	 * 		<td>
-	 * 			When enabled, throws {@link ParseException ParseExceptions} on malformed charset input.
-	 * 			Otherwise, malformed input is ignored.
-	 * 		</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>{@link JsonParser}</td>
-	 * 		<td>
-	 * 			When enabled, throws exceptions on the following invalid JSON syntax:
-	 * 			<ul>
-	 * 				<li>Unquoted attributes.
-	 * 				<li>Missing attribute values.
-	 * 				<li>Concatenated strings.
-	 * 				<li>Javascript comments.
-	 * 				<li>Numbers and booleans when Strings are expected.
-	 * 				<li>Numbers valid in Java but not JSON (e.g. octal notation, etc...)
-	 * 			</ul>
-	 * 		</td>
-	 * 	</tr>
-	 * </table>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>PARSER_strict</jsf>,value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_strict
-	 */
-	public Parser setStrict(boolean value) throws LockedException {
-		return setProperty(PARSER_strict, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Input stream charset.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Parser.inputStreamCharset"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"UTF-8"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * The character set to use for converting <code>InputStreams</code> and byte arrays to readers.
-	 * <p>
-	 * Used when passing in input streams and byte arrays to {@link Parser#parse(Object, Class)}.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>PARSER_inputStreamCharset</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_inputStreamCharset
-	 */
-	public Parser setInputStreamCharset(String value) throws LockedException {
-		return setProperty(PARSER_inputStreamCharset, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  File charset.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Parser.fileCharset"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"default"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * The character set to use for reading <code>Files</code> from the file system.
-	 * <p>
-	 * Used when passing in files to {@link Parser#parse(Object, Class)}.
-	 * <p>
-	 * <js>"default"</js> can be used to indicate the JVM default file system charset.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>PARSER_fileCharset</jsf>,value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see ParserContext#PARSER_fileCharset
-	 */
-	public Parser setFileCharset(String value) throws LockedException {
-		return setProperty(PARSER_fileCharset, value);
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Parser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public Parser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public Parser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public Parser clone() throws CloneNotSupportedException {
-		Parser c = (Parser)super.clone();
-		return c;
-	}
 }


[27/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java b/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
deleted file mode 100644
index 6dcde7b..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/ContextFactory.java
+++ /dev/null
@@ -1,1344 +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;
-
-import static org.apache.juneau.BeanContext.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-import java.util.concurrent.*;
-import java.util.concurrent.locks.*;
-
-import org.apache.juneau.internal.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.parser.*;
-
-/**
- * A factory for instantiating {@link Context} objects.
- * <p>
- * The hierarchy of these objects are...
- * <ul class='spaced-list'>
- * 	<li>{@link ContextFactory} - A thread-safe, modifiable context property store.<br>
- * 		Used to create {@link Context} objects.
- * 	<li>{@link Context} - A reusable, cachable, thread-safe, read-only context with configuration properties copied from the factory.<br>
- * 		Often used to create {@link Session} objects.
- * 	<li>{@link Session} - A one-time-use non-thread-safe object.<br>
- * 		Used by serializers and parsers to retrieve context properties and to be used as scratchpads.
- * </ul>
- *
- * <h6 class='topic'>ContextFactory objects</h6>
- * <p>
- * Context factories can be thought of as consisting of the following:
- * <ul class='spaced-list'>
- * 	<li>A <code>Map&lt;String,Object&gt;</code> of context properties.
- * 	<li>A <code>Map&lt;Class,Context&gt;</code> of context instances.
- * </ul>
- * <p>
- * Context factories are used to create and cache {@link Context} objects using the {@link #getContext(Class)} method.
- * <p>
- * As a general rule, {@link ContextFactory} objects are 'slow'.<br>
- * Setting and retrieving properties on a factory can involve relatively slow data conversion and synchronization.<br>
- * However, the {@link #getContext(Class)} method is fast, and will return cached context objects if the context properties have not changed.
- * <p>
- * Context factories can be used to store context properties for a variety of contexts.<br>
- * For example, a single factory can store context properties for the JSON serializer, XML serializer, HTML serializer
- * 	etc... and can thus be used to retrieve context objects for those serializers.<br>
- * <p>
- * Other notes:
- * <ul class='spaced-list'>
- * 	<li>Context factories can be locked using the {@link #lock()} method.<br>
- * 		This prevents the context properties from being further modified.
- * 	<li>Context factories can be cloned using the {@link #clone} method.<br>
- * 		This will return a new unlocked factory with the same context properties.
- * </ul>
- *
- * <h6 class='topic'>Context properties</h6>
- * <p>
- * Context properties are 'settings' for serializers and parsers.<br>
- * For example, the {@link BeanContext#BEAN_sortProperties} context property defines whether
- * 	bean properties should be serialized in alphabetical order.
- * <p>
- * Each {@link Context} object should contain the context properties that apply to it as static
- * 	fields (e.g {@link BeanContext#BEAN_sortProperties}).
- * <p>
- * Context properties can be of the following types:
- * <ul class='spaced-list'>
- * 	<li><l>SIMPLE</l> - A simple property.<br>
- * 		Examples include:  booleans, integers, Strings, Classes, etc...<br>
- * 		<br>
- * 		An example of this would be the {@link BeanContext#BEAN_sortProperties} property.<br>
- * 		It's name is simply <js>"BeanContext.sortProperties"</js>.
- * 
- * 	<li><l>SET</l> - A sorted set of objects.<br>
- * 	These are denoted by appending <js>".set"</js> to the property name.<br>
- * 		Objects can be of any type, even complex types.<br>
- * 		Sorted sets use tree sets to maintain the value in alphabetical order.<br>
- * 		<br>
- * 		For example, the {@link BeanContext#BEAN_notBeanClasses} property is used to store classes that should not be treated like beans.<br>
- * 		It's name is <js>"BeanContext.notBeanClasses.set"</js>.
- *
- * 	<li><l>LIST</l> - A list of unique objects.<br>
- * 		These are denoted by appending <js>".list"</js> to the property name.<br>
- * 		Objects can be of any type, even complex types.<br>
- * 		Use lists if the ordering of the values in the set is important (similar to how the order of entries in a classpath is important).<br>
- * 		<br>
- * 		For example, the {@link BeanContext#BEAN_beanFilters} property is used to store bean filters.<br>
- * 		It's name is <js>"BeanContext.transforms.list"</js>.
- *
- * 	<li><l>MAP</l> - A sorted map of key-value pairs.<br>
- * 		These are denoted by appending <js>".map"</js> to the property name.<br>
- * 		Keys can be any type directly convertable to and from Strings.
- * 		Values can be of any type, even complex types.<br>
- * 		<br>
- * 		For example, the {@link BeanContext#BEAN_implClasses} property is used to specify the names of implementation classes for interfaces.<br>
- * 		It's name is <js>"BeanContext.implClasses.map"</js>.<br>
- * </ul>
- * <p>
- * All context properties are set using the {@link #setProperty(String, Object)} method.
- * <p>
- * Default values for context properties can be specified globally as system properties.<br>
- * Example: <code>System.<jsm>setProperty</jsm>(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);</code>
- * <p>
- * SET and LIST properties can be added to using the {@link #addToProperty(String, Object)} method and removed from using the {@link #removeFromProperty(String, Object)} method.
- * <p>
- * SET and LIST properties can also be added to and removed from by appending <js>".add"</js> or <js>".remove"</js> to the property name and using the {@link #setProperty(String, Object)} method.
- * <p>
- * The following shows the two different ways to append to a set or list property:
- * <p class='bcode'>
- * 	Config config = <jk>new</jk> Config().set(<js>"BeanContext.notBeanClasses.set"</js>, Collections.<jsm>emptySet</jsm>());
- *
- * 	<jc>// Append to set property using addTo().</jc>
- * 	config.addTo(<js>"BeanContext.notBeanClasses.set"</js>, MyNotBeanClass.<jk>class</jk>);
- *
- * 	<jc>// Append to set property using set().</jc>
- * 	config.set(<js>"BeanContext.notBeanClasses.set.add"</js>, MyNotBeanClass.<jk>class</jk>);
- * </p>
- * <p>
- * Lists are appended to the beginning of the set so that behavior can be overridden.<br>
- * <p>
- * For sample, the following code shows the order in which POJO swaps are applied.<br>
- * In this case, we want F3 and F4 to appear at the beginning of the set so that they
- * 	take precedence over F1 and F2....
- * <p class='bcode'>
- * 	<jc>// Result will be F3,F4,F1,F2</jc>
- * 	config.addTo(<js>"BeanContext.transforms.list"</js>, Arrays.<jsm>asList</jsm>(F1.<jk>class</jk>, F2.<jk>class</jk>));
- * 	config.addTo(<js>"BeanContext.transforms.list"</js>, Arrays.<jsm>asList</jsm>(F3.<jk>class</jk>,F4.<jk>class</jk>));
- * </p>
- * <p>
- * SET and LIST properties can also be set and manipulated using JSON strings.
- * <p class='bcode'>
- * 	ContextFactory f = ContextFactory.<jsm>create</jsm>();
- *
- * 	<jc>// Set SET value using JSON array.
- * 	f.set(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass1']"</js>);
- *
- * 	<jc>// Add to SET using simple string.
- * 	f.addTo(<js>"BeanContext.notBeanClasses.set"</js>, <js>"com.my.MyNotBeanClass2"</js>);
- *
- * 	<jc>// Add an array of values as a JSON array..
- * 	f.addTo(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass3']"</js>);
- *
- * 	<jc>// Remove an array of values as a JSON array..
- * 	f.removeFrom(<js>"BeanContext.notBeanClasses.set"</js>, <js>"['com.my.MyNotBeanClass3']"</js>);
- * </p>
- * <p>
- * MAP properties can be added to using the {@link #putToProperty(String, Object, Object)} and {@link #putToProperty(String, Object)} methods.<br>
- * MAP property entries can be removed by setting the value to <jk>null</jk> (e.g. <code>config.putTo(<js>"BEAN_implClasses"</js>, MyNotBeanClass.<jk>class</jk>, <jk>null</jk>);</code>.<br>
- * MAP properties can also be added to by appending <js>".put"</js> to the property name and using the {@link #setProperty(String, Object)} method.<br>
- * <p>
- * The following shows the two different ways to append to a set property:
- * <p class='bcode'>
- * 	ContextFactory f = ContextFactory.<jsm>create</jsm>().set(<js>"BeanContext.implClasses.map"</js>, Collections.<jsm>emptyMap</jsm>());
- *
- * 	<jc>// Append to map property using putTo().</jc>
- * 	f.putTo(<js>"BeanContext.implClasses.map"</js>, MyInterface.<jk>class</jk>, MyInterfaceImpl.<jk>class</jk>);
- *
- * 	<jc>// Append to map property using set().</jc>
- * 	Map m = <jk>new</jk> HashMap(){{put(MyInterface.<jk>class</jk>,MyInterfaceImpl.<jk>class</jk>)}};
- * 	f.set(<js>"BeanContext.implClasses.map.put"</js>, m);
- * </p>
- * <p>
- * MAP properties can also be set and manipulated using JSON strings.
- * <p class='bcode'>
- * 	ContextFactory f = ContextFactory.<jsm>create</jsm>();
- *
- * 	<jc>// Set MAP value using JSON object.</jc>
- * 	f.set(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface1':'com.my.MyInterfaceImpl1'}"</js>);
- *
- * 	<jc>// Add to MAP using JSON object.</jc>
- * 	f.putTo(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface2':'com.my.MyInterfaceImpl2'}"</js>);
- *
- * 	<jc>// Remove from MAP using JSON object.</jc>
- * 	f.putTo(<js>"BeanContext.implClasses.map"</js>, <js>"{'com.my.MyInterface2':null}"</js>);
- * </p>
- * <p>
- * Context properties are retrieved from this factory using the following 3 methods:
- * <ul class='spaced-list'>
- * 	<li>{@link #getProperty(String, Class, Object)} - Retrieve a SIMPLE or SET property converted to the specified class type.
- * 	<li>{@link #getMap(String, Class, Class, Map)} - Retrieve a MAP property with keys/values converted to the specified class types.
- * 	<li>{@link #getPropertyMap(String)} - Retrieve a map of all context properties with the specified prefix (e.g. <js>"BeanContext"</js> for {@link BeanContext} properties).
- * </ul>
- * <p>
- * As a general rule, only {@link Context} objects will use these read methods.
- *
- * <h6 class='topic'>Context objects</h6>
- * <p>
- * A Context object can be thought of as unmodifiable snapshot of a factory.<br>
- * They should be 'fast' by avoiding synchronization by using final fields whenever possible.<br>
- * However, they MUST be thread safe.
- * <p>
- * Context objects are created using the {@link #getContext(Class)} method.<br>
- * As long as the properties on a factory have not been modified, the factory will return a cached copy
- * 	of a context.
- * <p class='bcode'>
- * 	ContextFactory f = ContextFactory.<jsm>create</jsm>();
- *
- * 	<jc>// Get BeanContext with default factory settings.</jc>
- * 	BeanContext bc = f.getContext(BeanContext.<jk>class</jk>);
- *
- * 	<jc>// Get another one.  This will be the same one.</jc>
- * 	BeanContext bc2 = f.getContext(BeanContext.<jk>class</jk>);
- * 	<jsm>assertTrue</jsm>(bc1 == bc2);
- *
- * 	<jc>// Set a property.</jc>
- * 	f.set(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);
- *
- * 	<jc>// Get another one.  This will be different!</jc>
- * 	bc2 = f.getContext(BeanContext.<jk>class</jk>);
- * 	<jsm>assertFalse</jsm>(bc1 == bc2);
- * </p>
- *
- * <h6 class='topic'>Session objects</h6>
- * <p>
- * Session objects are created through {@link Context} objects, typically through a <code>createContext()</code> method.<br>
- * Unlike context objects, they are NOT reusable and NOT thread safe.<br>
- * They are meant to be used one time and then thrown away.<br>
- * They should NEVER need to use synchronization.
- * <p>
- * Session objects are also often used as scratchpads for information such as keeping track of call stack
- * 	information to detect recursive loops when serializing beans.
- */
-public final class ContextFactory extends Lockable {
-
-	// All configuration properties in this object.
-	// Keys are property prefixes (e.g. 'BeanContext').
-	// Values are maps containing properties for that specific prefix.
-	private Map<String,PropertyMap> properties = new ConcurrentSkipListMap<String,PropertyMap>();
-
-	// Context cache.
-	// This gets cleared every time any properties change on this object.
-	private final Map<Class<? extends Context>,Context> contexts = new ConcurrentHashMap<Class<? extends Context>,Context>();
-
-	// Global Context cache.
-	// Context factories that are the 'same' will use the same maps from this cache.
-	// 'same' means the context properties are all the same when converted to strings.
-	private static final ConcurrentHashMap<Integer, ConcurrentHashMap<Class<? extends Context>,Context>> globalContextCache = new ConcurrentHashMap<Integer, ConcurrentHashMap<Class<? extends Context>,Context>>();
-
-	private ReadWriteLock lock = new ReentrantReadWriteLock();
-	private Lock rl = lock.readLock(), wl = lock.writeLock();
-
-	// Classloader used to instantiate Class instances.
-	ClassLoader classLoader = ClassLoader.getSystemClassLoader();
-
-	// Parser to use to convert JSON strings to POJOs
-	ReaderParser defaultParser;
-
-	// Bean session for converting strings to POJOs.
-	private static BeanSession beanSession;
-
-	// Used to keep properties in alphabetical order regardless of whether
-	// they're not strings.
-	private static Comparator<Object> PROPERTY_COMPARATOR = new Comparator<Object>() {
-		@Override
-		public int compare(Object o1, Object o2) {
-			return unswap(o1).toString().compareTo(unswap(o2).toString());
-		}
-	};
-
-	/**
-	 * Create a new context factory with default settings.
-	 *
-	 * @return A new context factory with default settings.
-	 */
-	public static ContextFactory create() {
-		ContextFactory f = new ContextFactory();
-		BeanContext.loadDefaults(f);
-		return f;
-	}
-
-	/**
-	 * Create a new context factory with settings copied from the specified factory.
-	 *
-	 * @param copyFrom The existing factory to copy properties from.
-	 * @return A new context factory with default settings.
-	 */
-	public static ContextFactory create(ContextFactory copyFrom) {
-		return new ContextFactory().copyFrom(copyFrom);
-	}
-
-
-	ContextFactory() {}
-
-	/**
-	 * Copy constructor.
-	 *
-	 * @param copyFrom The factory to copy properties from.
-	 */
-	public ContextFactory(ContextFactory copyFrom) {
-		copyFrom(copyFrom);
-	}
-
-	/**
-	 * Copies the properties from the specified factory into this factory.
-	 *
-	 * @param cf The factory to copy from.
-	 * @return This object (for method chaining).
-	 */
-	public ContextFactory copyFrom(ContextFactory cf) {
-		for (Map.Entry<String,PropertyMap> e : cf.properties.entrySet())
-			this.properties.put(e.getKey(), new PropertyMap(e.getValue()));
-		this.classLoader = cf.classLoader;
-		this.defaultParser = cf.defaultParser;
-		return this;
-	}
-
-	/**
-	 * Sets a configuration property value on this object.
-	 * <p>
-	 * A typical usage is to set or overwrite configuration values like so...
-	 * <p class='bcode'>
-	 * 	ContextFactory g = ContextFactory.<jsm>create</jsm>();
-	 * 	f.setProperty(<jsf>BEAN_sortProperties</jsf>, <jk>true</jk>);
-	 * </p>
-	 * <p>
-	 * The possible class types of the value depend on the property type:
-	 * <p>
-	 * <table class='styled'>
-	 * 	<tr>
-	 * 		<th>Property type</th>
-	 * 		<th>Example</th>
-	 * 		<th>Allowed value type</th>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>Set <l>SIMPLE</l></td>
-	 * 		<td><js>"Foo.x"</js></td>
-	 * 		<td>Any object type.</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>Set <l>SET/LIST</l></td>
-	 * 		<td><js>"Foo.x.set"</js></td>
-	 * 		<td>Any collection or array of any objects, or a String containing a JSON array.</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>Add/Remove <l>SET/LIST</l></td>
-	 * 		<td><js>"Foo.x.set.add"</js></td>
-	 * 		<td>If a collection, adds or removes the entries in the collection.  Otherwise, adds/removes a single entry.</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>Set <l>MAP</l></td>
-	 * 		<td><js>"Foo.x.map"</js></td>
-	 * 		<td>A map, or a String containing a JSON object.  Entries overwrite existing map.</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td>Put <l>MAP</l></td>
-	 * 		<td><js>"Foo.x.map.put"</js></td>
-	 * 		<td>A map, or a String containing a JSON object.  Entries are added to existing map.</td>
-	 * 	</tr>
-	 * </table>
-	 *
-	 * @param name The configuration property name.<br>
-	 * If name ends with <l>.add</l>, then the specified value is added to the
-	 * 	existing property value as an entry in a SET or LIST property.<br>
-	 * If name ends with <l>.put</l>, then the specified value is added to the
-	 * 	existing property value as a key/value pair in a MAP property.<br>
-	 * If name ends with <l>.remove</l>, then the specified value is removed from the
-	 * 	existing property property value in a SET or LIST property.<br>
-	 *
-	 * @param value The new value.
-	 * If <jk>null</jk>, the property value is deleted.<br>
-	 * In general, the value type can be anything.<br>
-	 *
-	 * @return This object (for method chaining).
-	 */
-	public ContextFactory setProperty(String name, Object value) {
-		String prefix = prefix(name);
-
-		if (name.endsWith(".add"))
-			return addToProperty(name.substring(0, name.lastIndexOf('.')), value);
-
-		if (name.endsWith(".put"))
-			return putToProperty(name.substring(0, name.lastIndexOf('.')), value);
-
-		if (name.endsWith(".remove"))
-			return removeFromProperty(name.substring(0, name.lastIndexOf('.')), value);
-
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			if (! properties.containsKey(prefix))
-				properties.put(prefix, new PropertyMap(prefix));
-			properties.get(prefix).set(name, value);
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Convenience method for setting multiple properties in one call.
-	 * <p>
-	 * This appends to any previous configuration properties set on this config.
-	 *
-	 * @param newProperties The new properties to set.
-	 * @return This object (for method chaining).
-	 */
-	@SuppressWarnings({ "unchecked", "rawtypes" })
-	public ContextFactory setProperties(Map newProperties) {
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			for (Map.Entry e : (Set<Map.Entry>)newProperties.entrySet()) {
-				String name = e.getKey().toString();
-				Object value = e.getValue();
-				String prefix = prefix(name);
-				if (name.endsWith(".add"))
-					addToProperty(name.substring(0, name.lastIndexOf('.')), value);
-				else if (name.endsWith(".remove"))
-					removeFromProperty(name.substring(0, name.lastIndexOf('.')), value);
-				else {
-					if (! properties.containsKey(prefix))
-						properties.put(prefix, new PropertyMap(prefix));
-					properties.get(prefix).set(name, value);
-				}
-			}
-
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Adds a value to a SET property.
-	 *
-	 * @param name The property name.
-	 * @param value The new value to add to the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 */
-	public ContextFactory addToProperty(String name, Object value) {
-		String prefix = prefix(name);
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			if (! properties.containsKey(prefix))
-				properties.put(prefix, new PropertyMap(prefix));
-			properties.get(prefix).addTo(name, value);
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Adds or overwrites a value to a MAP property.
-	 *
-	 * @param name The property name.
-	 * @param key The property value map key.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 */
-	public ContextFactory putToProperty(String name, Object key, Object value) {
-		String prefix = prefix(name);
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			if (! properties.containsKey(prefix))
-				properties.put(prefix, new PropertyMap(prefix));
-			properties.get(prefix).putTo(name, key, value);
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Adds or overwrites a value to a MAP property.
-	 *
-	 * @param name The property value.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 */
-	public ContextFactory putToProperty(String name, Object value) {
-		String prefix = prefix(name);
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			if (! properties.containsKey(prefix))
-				properties.put(prefix, new PropertyMap(prefix));
-			properties.get(prefix).putTo(name, value);
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Removes a value from a SET property.
-	 *
-	 * @param name The property name.
-	 * @param value The property value in the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 */
-	public ContextFactory removeFromProperty(String name, Object value) {
-		String prefix = prefix(name);
-		wl.lock();
-		try {
-			checkLock();
-			contexts.clear();
-			if (properties.containsKey(prefix))
-				properties.get(prefix).removeFrom(name, value);
-		} finally {
-			wl.unlock();
-		}
-		return this;
-	}
-
-	/**
-	 * Returns an instance of the specified context initialized with the properties
-	 * 	in this config.
-	 * <p>
-	 * Multiple calls to this method for the same config class will return the same
-	 * 	cached value as long as the config properties on this config are not touched.
-	 * <p>
-	 * As soon as any properties are modified on this config, all cached entries
-	 * 	are discarded and recreated as needed.
-	 *
-	 * @param c The context class to instantiate.
-	 * @return The context instance.
-	 */
-	@SuppressWarnings("unchecked")
-	public <T extends Context> T getContext(Class<T> c) {
-		rl.lock();
-		try {
-			try {
-				if (! contexts.containsKey(c)) {
-
-					// Try to get it from the global cache.
-					Integer key = hashCode();
-					if (! globalContextCache.containsKey(key))
-						globalContextCache.putIfAbsent(key, new ConcurrentHashMap<Class<? extends Context>,Context>());
-					ConcurrentHashMap<Class<? extends Context>, Context> cacheForThisConfig = globalContextCache.get(key);
-
-					if (! cacheForThisConfig.containsKey(c))
-						cacheForThisConfig.putIfAbsent(c, c.getConstructor(ContextFactory.class).newInstance(this));
-
-					contexts.put(c, cacheForThisConfig.get(c));
-				}
-				return (T)contexts.get(c);
-			} catch (Exception e) {
-				throw new ConfigException("Could not instantiate config class ''{0}''", className(c)).initCause(e);
-			}
-		} finally {
-			rl.unlock();
-		}
-	}
-
-	/**
-	 * Returns the configuration properties with the specified prefix.
-	 * <p>
-	 * For example, if <l>prefix</l> is <js>"BeanContext"</js>, then retrieves
-	 * 	all configuration properties that are prefixed with <js>"BeanContext."</js>.
-	 *
-	 * @param prefix The prefix of properties to retrieve.
-	 * @return The configuration properties with the specified prefix, never <jk>null</jk>.
-	 */
-	public PropertyMap getPropertyMap(String prefix) {
-		rl.lock();
-		try {
-			PropertyMap m = properties.get(prefix);
-			return m == null ? new PropertyMap(prefix) : m;
-		} finally {
-			rl.unlock();
-		}
-	}
-
-	/**
-	 * Specifies the classloader to use when resolving classes from strings.
-	 * <p>
-	 * Can be used for resolving class names when the classes being created are in a different
-	 * 	classloader from the Juneau code.
-	 * <p>
-	 * If <jk>null</jk>, the system classloader will be used to resolve classes.
-	 *
-	 * @param classLoader The new classloader.
-	 * @throws LockedException If {@link #lock()} was called on this object.
-	 * @return This object (for method chaining).
-	 */
-	public ContextFactory setClassLoader(ClassLoader classLoader) {
-		checkLock();
-		this.classLoader = (classLoader == null ? ClassLoader.getSystemClassLoader() : classLoader);
-		return this;
-	}
-
-	/**
-	 * Specifies the parser to use to convert Strings to POJOs.
-	 * <p>
-	 * If <jk>null</jk>, {@link JsonParser#DEFAULT} will be used.
-	 *
-	 * @param defaultParser The new defaultParser.
-	 * @throws LockedException If {@link #lock()} was called on this object.
-	 * @return This object (for method chaining).
-	 */
-	public ContextFactory setDefaultParser(ReaderParser defaultParser) {
-		checkLock();
-		this.defaultParser = defaultParser == null ? JsonParser.DEFAULT : defaultParser;
-		return this;
-	}
-
-	/**
-	 * Returns a property value converted to the specified type.
-	 *
-	 * @param name The full name of the property (e.g. <js>"BeanContext.sortProperties"</js>)
-	 * @param type The class type to convert the property value to.
-	 * @param def The default value if the property is not set.
-	 *
-	 * @return The property value.
-	 * @throws ConfigException If property has a value that cannot be converted to a boolean.
-	 */
-	public <T> T getProperty(String name, Class<T> type, T def) {
-		rl.lock();
-		try {
-			PropertyMap pm = getPropertyMap(prefix(name));
-			if (pm != null)
-				return pm.get(name, type, def);
-			String s = System.getProperty(name);
-			if ((! StringUtils.isEmpty(s)) && isBeanSessionAvailable())
-				return getBeanSession().convertToType(s, type);
-			return def;
-		} finally {
-			rl.unlock();
-		}
-	}
-
-	/**
-	 * Returns a property value converted to a {@link LinkedHashMap} with the specified
-	 * 	key and value types.
-	 *
-	 * @param name The full name of the property (e.g. <js>"BeanContext.sortProperties"</js>)
-	 * @param keyType The class type of the keys in the map.
-	 * @param valType The class type of the values in the map.
-	 * @param def The default value if the property is not set.
-	 *
-	 * @return The property value.
-	 * @throws ConfigException If property has a value that cannot be converted to a boolean.
-	 */
-	public <K,V> Map<K,V> getMap(String name, Class<K> keyType, Class<V> valType, Map<K,V> def) {
-		rl.lock();
-		try {
-			PropertyMap pm = getPropertyMap(prefix(name));
-			if (pm != null)
-				return pm.getMap(name, keyType, valType, def);
-			return def;
-		} finally {
-			rl.unlock();
-		}
-	}
-
-
-	//-------------------------------------------------------------------------------------
-	// Convenience methods.
-	//-------------------------------------------------------------------------------------
-
-	/**
-	 * Shortcut for calling <code>getContext(BeanContext.<jk>class</jk>);</code>.
-	 *
-	 * @return The bean context instance.
-	 */
-	public BeanContext getBeanContext() {
-		return getContext(BeanContext.class);
-	}
-
-	/**
-	 * Shortcut for calling <code>addTo(<jsf>BEAN_notBeanClasses</jsf>, <jf>classes</jf>)</code>.
-	 *
-	 * @see ContextFactory#addToProperty(String,Object)
-	 * @param classes The new setting value for the bean context.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#addToProperty(String, Object)
-	 * @see BeanContext#BEAN_notBeanClasses
-	 */
-	public ContextFactory addNotBeanClasses(Class<?>...classes) throws LockedException {
-		checkLock();
-		addToProperty(BEAN_notBeanClasses, classes);
-		return this;
-	}
-
-	/**
-	 * Shortcut for calling <code>addTo(<jsf>BEAN_beanFilters</jsf>, <jf>classes</jf>)</code>.
-	 *
-	 * @param classes The new setting value for the bean context.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#addToProperty(String, Object)
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public ContextFactory addBeanFilters(Class<?>...classes) throws LockedException {
-		checkLock();
-		addToProperty(BEAN_beanFilters, classes);
-		return this;
-	}
-
-	/**
-	 * Shortcut for calling <code>addTo(<jsf>BEAN_pojoSwaps</jsf>, <jf>classes</jf>)</code>.
-	 *
-	 * @param classes The new setting value for the bean context.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#addToProperty(String, Object)
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public ContextFactory addPojoSwaps(Class<?>...classes) throws LockedException {
-		checkLock();
-		addToProperty(BEAN_pojoSwaps, classes);
-		return this;
-	}
-
-	/**
-	 * Shortcut for calling <code>addTo(<jsf>BEAN_beanDictionary</jsf>, <jf>classes</jf>)</code>.
-	 *
-	 * @param classes The new setting value for the bean context.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#addToProperty(String, Object)
-	 * @see BeanContext#BEAN_beanDictionary
-	 */
-	public ContextFactory addToBeanDictionary(Class<?>...classes) throws LockedException {
-		checkLock();
-		addToProperty(BEAN_beanDictionary, classes);
-		return this;
-	}
-
-	/**
-	 * Shortcut for calling <code>putTo(<jsf>BEAN_implCLasses</jsf>, <jf>interfaceClass</jf>, <jf>implClass</jf>)</code>.
-	 *
-	 * @param interfaceClass The interface class.
-	 * @param implClass The implementation class.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @param <T> The class type of the interface.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#putToProperty(String, Object, Object)
-	 * @see BeanContext#BEAN_implClasses
-	 */
-	public <T> ContextFactory addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		checkLock();
-		putToProperty(BEAN_implClasses, interfaceClass, implClass);
-		return this;
-	}
-
-
-	//-------------------------------------------------------------------------------------
-	// Object methods.
-	//-------------------------------------------------------------------------------------
-
-	@Override /* Object */
-	public int hashCode() {
-		HashCode c = new HashCode();
-		for (PropertyMap m : properties.values())
-			c.add(m);
-		return c.get();
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Utility classes and methods.
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * Hashcode generator that treats strings and primitive values the same.
-	 * (e.g. <code>123</code> and <js>"123"</js> result in the same hashcode.)
-	 */
-	private static class NormalizingHashCode extends HashCode {
-		@Override /* HashCode */
-		protected Object unswap(Object o) {
-			return ContextFactory.unswap(o);
-		}
-	}
-
-	/**
-	 * Contains all the properties for a particular property prefix (e.g. <js>'BeanContext'</js>)
-	 * <p>
-	 * Instances of this map are immutable from outside this class.
-	 * <p>
-	 * The {@link PropertyMap#hashCode()} and {@link PropertyMap#equals(Object)} methods
-	 * 	can be used to compare with other property maps.
-	 */
-	@SuppressWarnings("hiding")
-	public class PropertyMap {
-
-		private final Map<String,Property> map = new ConcurrentSkipListMap<String,Property>();
-		private volatile int hashCode = 0;
-		private final ReadWriteLock lock = new ReentrantReadWriteLock();
-		private final Lock rl = lock.readLock(), wl = lock.writeLock();
-		private final String prefix;
-
-		private PropertyMap(String prefix) {
-			this.prefix = prefix;
-			prefix = prefix + '.';
-			Properties p = System.getProperties();
-			for (Map.Entry<Object,Object> e : p.entrySet())
-				if (e.getKey().toString().startsWith(prefix))
-					set(e.getKey().toString(), e.getValue());
-		}
-
-		/**
-		 * Copy constructor.
-		 */
-		private PropertyMap(PropertyMap orig) {
-			this.prefix = orig.prefix;
-			for (Map.Entry<String,Property> e : orig.map.entrySet())
-				this.map.put(e.getKey(), Property.create(e.getValue().name, e.getValue().value()));
-		}
-
-		/**
-		 * Returns the specified property as the specified class type.
-		 *
-		 * @param name The property name.
-		 * @param type The type of object to convert the value to.
-		 * @param def The default value if the specified property is not set.
-		 *
-		 * @return The property value.
-		 */
-		public <T> T get(String name, Class<T> type, T def) {
-			rl.lock();
-			try {
-				Property p = map.get(name);
-				if (p == null || type == null)
-					return def;
-				try {
-					if (! isBeanSessionAvailable())
-						return def;
-					return getBeanSession().convertToType(p.value, type);
-				} catch (InvalidDataConversionException e) {
-					throw new ConfigException("Could not retrieve config property ''{0}''.  {1}", p.name, e.getMessage());
-				}
-			} finally {
-				rl.unlock();
-			}
-		}
-
-		/**
-		 * Returns the specified property as a map with the specified key and value types.
-		 * <p>
-		 * The map returned is an instance of {@link LinkedHashMap}.
-		 *
-		 * @param name The property name.
-		 * @param keyType The class type of the keys of the map.
-		 * @param valueType The class type of the values of the map.
-		 * @param def The default value if the specified property is not set.
-		 *
-		 * @return The property value.
-		 */
-		@SuppressWarnings("unchecked")
-		public <K,V> Map<K,V> getMap(String name, Class<K> keyType, Class<V> valueType, Map<K,V> def) {
-			rl.lock();
-			try {
-				Property p = map.get(name);
-				if (p == null || keyType == null || valueType == null)
-					return def;
-				try {
-					if (isBeanSessionAvailable()) {
-						BeanSession session = getBeanSession();
-						return (Map<K,V>)session.convertToType(p.value, session.getClassMeta(LinkedHashMap.class, keyType, valueType));
-					}
-					return def;
-				} catch (InvalidDataConversionException e) {
-					throw new ConfigException("Could not retrieve config property ''{0}''.  {1}", p.name, e.getMessage());
-				}
-			} finally {
-				rl.unlock();
-			}
-		}
-
-		/**
-		 * Convenience method for returning all values in this property map as a simple map.
-		 * <p>
-		 * Primarily useful for debugging.
-		 *
-		 * @return A new {@link LinkedHashMap} with all values in this property map.
-		 */
-		public Map<String,Object> asMap() {
-			rl.lock();
-			try {
-				Map<String,Object> m = new LinkedHashMap<String,Object>();
-				for (Property p : map.values())
-					m.put(p.name, p.value);
-				return m;
-			} finally {
-				rl.unlock();
-			}
-		}
-
-		private void set(String name, Object value) {
-			wl.lock();
-			hashCode = 0;
-			try {
-				if (value == null)
-					map.remove(name);
-				else
-					map.put(name, Property.create(name, value));
-			} finally {
-				wl.unlock();
-			}
-		}
-
-		private void addTo(String name, Object value) {
-			wl.lock();
-			hashCode = 0;
-			try {
-				if (! map.containsKey(name))
-					map.put(name, Property.create(name, Collections.emptyList()));
-				map.get(name).add(value);
-			} finally {
-				wl.unlock();
-			}
-		}
-
-		private void putTo(String name, Object key, Object value) {
-			wl.lock();
-			hashCode = 0;
-			try {
-				if (! map.containsKey(name))
-					map.put(name, Property.create(name, Collections.emptyMap()));
-				map.get(name).put(key, value);
-			} finally {
-				wl.unlock();
-			}
-		}
-
-		private void putTo(String name, Object value) {
-			wl.lock();
-			hashCode = 0;
-			try {
-				if (! map.containsKey(name))
-					map.put(name, Property.create(name, Collections.emptyMap()));
-				map.get(name).put(value);
-			} finally {
-				wl.unlock();
-			}
-		}
-
-		private void removeFrom(String name, Object value) {
-			wl.lock();
-			hashCode = 0;
-			try {
-				if (map.containsKey(name))
-					map.get(name).remove(value);
-			} finally {
-				wl.unlock();
-			}
-		}
-
-		@Override
-		public int hashCode() {
-			rl.lock();
-			try {
-				if (hashCode == 0) {
-					HashCode c = new HashCode().add(prefix);
-					for (Property p : map.values())
-						c.add(p);
-					this.hashCode = c.get();
-				}
-				return hashCode;
-			} finally {
-				rl.unlock();
-			}
-		}
-
-		@Override
-		public boolean equals(Object o) {
-			rl.lock();
-			try {
-				if (o instanceof PropertyMap) {
-					PropertyMap m = (PropertyMap)o;
-					if (m.hashCode() != hashCode())
-						return false;
-					return this.map.equals(m.map);
-				}
-				return false;
-			} finally {
-				rl.unlock();
-			}
-		}
-
-		@Override
-		public String toString() {
-			return "PropertyMap(id="+System.identityHashCode(this)+")";
-		}
-	}
-
-	private abstract static class Property {
-		private final String name, type;
-		private final Object value;
-
-		private static Property create(String name, Object value) {
-			if (name.endsWith(".set"))
-				return new SetProperty(name, value);
-			else if (name.endsWith(".list"))
-				return new ListProperty(name, value);
-			else if (name.endsWith(".map"))
-				return new MapProperty(name, value);
-			return new SimpleProperty(name, value);
-		}
-
-		Property(String name, String type, Object value) {
-			this.name = name;
-			this.type = type;
-			this.value = value;
-		}
-
-		void add(Object val) {
-			throw new ConfigException("Cannot add value {0} ({1}) to property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
-		}
-
-		void remove(Object val) {
-			throw new ConfigException("Cannot remove value {0} ({1}) from property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
-		}
-
-		void put(Object val) {
-			throw new ConfigException("Cannot put value {0} ({1}) to property ''{2}'' ({3}).", JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
-		}
-
-		void put(Object key, Object val) {
-			throw new ConfigException("Cannot put value {0}({1})->{2}({3}) to property ''{4}'' ({5}).", JsonSerializer.DEFAULT_LAX.toString(key), ClassUtils.getReadableClassNameForObject(key), JsonSerializer.DEFAULT_LAX.toString(val), ClassUtils.getReadableClassNameForObject(val), name, type);
-		}
-
-		protected Object value() {
-			return value;
-		}
-
-		@Override /* Object */
-		public int hashCode() {
-			HashCode c = new NormalizingHashCode().add(name);
-			if (value instanceof Map) {
-				for (Map.Entry<?,?> e : ((Map<?,?>)value).entrySet())
-					c.add(e.getKey()).add(e.getValue());
-			} else if (value instanceof Collection) {
-				for (Object o : (Collection<?>)value)
-					c.add(o);
-			} else {
-				c.add(value);
-			}
-			return c.get();
-		}
-
-		@Override
-		public String toString() {
-			return "Property(name="+name+",type="+type+")";
-		}
-	}
-
-	private static class SimpleProperty extends Property {
-
-		SimpleProperty(String name, Object value) {
-			super(name, "SIMPLE", value);
-		}
-	}
-
-	@SuppressWarnings({"unchecked"})
-	private static class SetProperty extends Property {
-		private final Set<Object> value;
-
-		private SetProperty(String name, Object value) {
-			super(name, "SET", new ConcurrentSkipListSet<Object>(PROPERTY_COMPARATOR));
-			this.value = (Set<Object>)value();
-			add(value);
-		}
-
-		@Override
-		void add(Object val) {
-			if (val.getClass().isArray())
-				for (int i = 0; i < Array.getLength(val); i++)
-					add(Array.get(val, i));
-			else if (val instanceof Collection)
-				for (Object o : (Collection<Object>)val)
-					add(o);
-			else {
-				if (val instanceof String) {
-					String s = val.toString();
-					if (s.startsWith("[") && s.endsWith("]")) {
-						try {
-							add(new ObjectList(s));
-							return;
-						} catch (Exception e) {}
-					}
-				}
-				for (Object o : value)
-					if (same(val, o))
-						return;
-				value.add(val);
-			}
-		}
-
-		@Override
-		void remove(Object val) {
-			if (val.getClass().isArray())
-				for (int i = 0; i < Array.getLength(val); i++)
-					remove(Array.get(val, i));
-			else if (val instanceof Collection)
-				for (Object o : (Collection<Object>)val)
-					remove(o);
-			else {
-				if (val instanceof String) {
-					String s = val.toString();
-					if (s.startsWith("[") && s.endsWith("]")) {
-						try {
-							remove(new ObjectList(s));
-							return;
-						} catch (Exception e) {}
-					}
-				}
-				for (Iterator<Object> i = value.iterator(); i.hasNext();)
-					if (same(i.next(), val))
-						i.remove();
-			}
-		}
-	}
-
-	@SuppressWarnings({"unchecked"})
-	private static class ListProperty extends Property {
-		private final LinkedList<Object> value;
-
-		private ListProperty(String name, Object value) {
-			super(name, "LIST", new LinkedList<Object>());
-			this.value = (LinkedList<Object>)value();
-			add(value);
-		}
-
-		@Override
-		void add(Object val) {
-			if (val.getClass().isArray()) {
-				for (int i = Array.getLength(val) - 1; i >= 0; i--)
-					add(Array.get(val, i));
-			} else if (val instanceof List) {
-				List<Object> l = (List<Object>)val;
-				for (ListIterator<Object> i = l.listIterator(l.size()); i.hasPrevious();)
-					add(i.previous());
-			} else if (val instanceof Collection) {
-				List<Object> l = new ArrayList<Object>((Collection<Object>)val);
-				for (ListIterator<Object> i = l.listIterator(l.size()); i.hasPrevious();)
-					add(i.previous());
-			} else {
-				String s = val.toString();
-				if (s.startsWith("[") && s.endsWith("]")) {
-					try {
-						add(new ObjectList(s));
-						return;
-					} catch (Exception e) {}
-				}
-				for (Iterator<Object> i = value.iterator(); i.hasNext(); )
-					if (same(val, i.next()))
-						i.remove();
-				value.addFirst(val);
-			}
-		}
-
-		@Override
-		void remove(Object val) {
-			if (val.getClass().isArray())
-				for (int i = 0; i < Array.getLength(val); i++)
-					remove(Array.get(val, i));
-			else if (val instanceof Collection)
-				for (Object o : (Collection<Object>)val)
-					remove(o);
-			else {
-				String s = val.toString();
-				if (s.startsWith("[") && s.endsWith("]")) {
-					try {
-						remove(new ObjectList(s));
-						return;
-					} catch (Exception e) {}
-				}
-				for (Iterator<Object> i = value.iterator(); i.hasNext();)
-					if (same(i.next(), val))
-						i.remove();
-			}
-		}
-	}
-
-	@SuppressWarnings({"unchecked","rawtypes"})
-	private static class MapProperty extends Property {
-		final Map<Object,Object> value;
-
-		MapProperty(String name, Object value) {
-			// ConcurrentSkipListMap doesn't support Map.Entry.remove(), so use TreeMap instead.
-			super(name, "MAP", Collections.synchronizedMap(new TreeMap<Object,Object>(PROPERTY_COMPARATOR)));
-			this.value = (Map<Object,Object>)value();
-			put(value);
-		}
-
-		@Override
-		void put(Object val) {
-			try {
-				if (isBeanSessionAvailable() && ! (val instanceof Map))
-					val = getBeanSession().convertToType(val, Map.class);
-				if (val instanceof Map) {
-					Map m = (Map)val;
-					for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-						put(e.getKey(), e.getValue());
-					return;
-				}
-			} catch (Exception e) {}
-			super.put(val);
-		}
-
-		@Override
-		void put(Object key, Object val) {
-			// ConcurrentSkipListMap doesn't support Map.Entry.remove().
-			for (Map.Entry<Object,Object> e : value.entrySet()) {
-				if (same(e.getKey(), key)) {
-					e.setValue(val);
-					return;
-				}
-			}
-			value.put(key, val);
-		}
-	}
-
-	/**
-	 * Converts an object to a normalized form for comparison purposes.
-	 *
-	 * @param o The object to normalize.
-	 * @return The normalized object.
-	 */
-	private static final Object unswap(Object o) {
-		if (o instanceof Class)
-			return ((Class<?>)o).getName();
-		if (o instanceof Number || o instanceof Boolean)
-			return o.toString();
-		return o;
-	}
-
-	private static BeanSession getBeanSession() {
-		if (beanSession == null && BeanContext.DEFAULT != null)
-			beanSession = BeanContext.DEFAULT.createSession();
-		return beanSession;
-	}
-
-	/**
-	 * Returns true if a bean session is available.
-	 * Note that a bean session will not be available when constructing the BeanContext.DEFAULT context.
-	 * (it's a chicken-and-egg thing).
-	 */
-	private static boolean isBeanSessionAvailable() {
-		return getBeanSession() != null;
-	}
-
-	/*
-	 * Compares two objects for "string"-equality.
-	 * Basically mean both objects are equal if they're the same when converted to strings.
-	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private static boolean same(Object o1, Object o2) {
-		if (o1 == o2)
-			return true;
-		if (o1 instanceof Map) {
-			if (o2 instanceof Map) {
-				Map m1 = (Map)o1, m2 = (Map)o2;
-				if (m1.size() == m2.size()) {
-					Set<Map.Entry> s1 = m1.entrySet(), s2 = m2.entrySet();
-					for (Iterator<Map.Entry> i1 = s1.iterator(), i2 = s2.iterator(); i1.hasNext();) {
-						Map.Entry e1 = i1.next(), e2 = i2.next();
-						if (! same(e1.getKey(), e2.getKey()))
-							return false;
-						if (! same(e1.getValue(), e2.getValue()))
-							return false;
-					}
-					return true;
-				}
-			}
-			return false;
-		} else if (o1 instanceof Collection) {
-			if (o2 instanceof Collection) {
-				Collection c1 = (Collection)o1, c2 = (Collection)o2;
-				if (c1.size() == c2.size()) {
-					for (Iterator i1 = c1.iterator(), i2 = c2.iterator(); i1.hasNext();) {
-						if (! same(i1.next(), i2.next()))
-							return false;
-					}
-					return true;
-				}
-			}
-			return false;
-		} else {
-			return unswap(o1).equals(unswap(o2));
-		}
-	}
-
-	private String prefix(String name) {
-		if (name == null)
-			throw new ConfigException("Invalid property name specified: 'null'");
-		if (name.indexOf('.') == -1)
-			return "";
-		return name.substring(0, name.indexOf('.'));
-	}
-
-	private String className(Object o) {
-		if (o == null)
-			return null;
-		if (o instanceof Class)
-			return ClassUtils.getReadableClassName((Class<?>)o);
-		return ClassUtils.getReadableClassName(o.getClass());
-	}
-
-	@Override /* Object */
-	public String toString() {
-		rl.lock();
-		try {
-			ObjectMap m = new ObjectMap();
-			m.put("id", System.identityHashCode(this));
-			m.put("hashCode", hashCode());
-			m.put("properties.id", System.identityHashCode(properties));
-			m.put("contexts.id", System.identityHashCode(contexts));
-			m.put("properties", properties);
-			m.put("contexts", contexts);
-			return m.toString();
-		} finally {
-			rl.unlock();
-		}
-	}
-
-	/**
-	 * Creates an unlocked clone of this object.
-	 *
-	 * @throws CloneNotSupportedException If class cannot be cloned.
-	 */
-	@Override /* Object */
-	public ContextFactory clone() throws CloneNotSupportedException {
-		rl.lock();
-		try {
-			return new ContextFactory(this);
-		} finally {
-			rl.unlock();
-		}
-	}
-}



[10/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
deleted file mode 100644
index 948d92b..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParser.java
+++ /dev/null
@@ -1,1191 +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.urlencoding;
-
-import static org.apache.juneau.urlencoding.UonParserContext.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.internal.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.transform.*;
-
-/**
- * Parses UON (a notation for URL-encoded query parameter values) text into POJO models.
- *
- * <h5 class='section'>Media types:</h5>
- * <p>
- * Handles <code>Content-Type</code> types: <code>text/uon</code>
- *
- * <h5 class='section'>Description:</h5>
- * <p>
- * This parser uses a state machine, which makes it very fast and efficient.
- *
- * <h5 class='section'>Configurable properties:</h5>
- * <p>
- * This class has the following properties associated with it:
- * <ul>
- * 	<li>{@link UonParserContext}
- * 	<li>{@link ParserContext}
- * 	<li>{@link BeanContext}
- * </ul>
- */
-@SuppressWarnings({ "rawtypes", "unchecked" })
-@Consumes("text/uon")
-public class UonParser extends ReaderParser {
-
-	/** Reusable instance of {@link UonParser}, all default settings. */
-	public static final UonParser DEFAULT = new UonParser().lock();
-
-	/** Reusable instance of {@link UonParser.Decoding}. */
-	public static final UonParser DEFAULT_DECODING = new Decoding().lock();
-
-	// Characters that need to be preceeded with an escape character.
-	private static final AsciiSet escapedChars = new AsciiSet("~'\u0001\u0002");
-
-	private static final char AMP='\u0001', EQ='\u0002';  // Flags set in reader to denote & and = characters.
-
-	/**
-	 * Equivalent to <code><jk>new</jk> UrlEncodingParser().setProperty(UonParserContext.<jsf>UON_decodeChars</jsf>,<jk>true</jk>);</code>.
-	 */
-	public static class Decoding extends UonParser {
-		/** Constructor */
-		public Decoding() {
-			setDecodeChars(true);
-		}
-	}
-
-	/**
-	 * Workhorse method.
-	 *
-	 * @param session The parser context for this parse.
-	 * @param eType The class type being parsed, or <jk>null</jk> if unknown.
-	 * @param r The reader being parsed.
-	 * @param outer The outer object (for constructing nested inner classes).
-	 * @param isUrlParamValue If <jk>true</jk>, then we're parsing a top-level URL-encoded value which is treated a bit different than the default case.
-	 * @param pMeta The current bean property being parsed.
-	 * @return The parsed object.
-	 * @throws Exception
-	 */
-	protected <T> T parseAnything(UonParserSession session, ClassMeta<T> eType, ParserReader r, Object outer, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws Exception {
-
-		if (eType == null)
-			eType = (ClassMeta<T>)object();
-		PojoSwap<T,Object> transform = (PojoSwap<T,Object>)eType.getPojoSwap();
-		ClassMeta<?> sType = eType.getSerializedClassMeta();
-
-		Object o = null;
-
-		int c = r.peekSkipWs();
-
-		if (c == -1 || c == AMP) {
-			// If parameter is blank and it's an array or collection, return an empty list.
-			if (sType.isCollectionOrArray())
-				o = sType.newInstance();
-			else if (sType.isString() || sType.isObject())
-				o = "";
-			else if (sType.isPrimitive())
-				o = sType.getPrimitiveDefault();
-			// Otherwise, leave null.
-		} else if (sType.isObject()) {
-			if (c == '(') {
-				ObjectMap m = new ObjectMap(session);
-				parseIntoMap(session, r, m, string(), object(), pMeta);
-				o = session.cast(m, pMeta, eType);
-			} else if (c == '@') {
-				Collection l = new ObjectList(session);
-				o = parseIntoCollection(session, r, l, sType.getElementType(), isUrlParamValue, pMeta);
-			} else {
-				String s = parseString(session, r, isUrlParamValue);
-				if (c != '\'') {
-					if ("true".equals(s) || "false".equals(s))
-						o = Boolean.valueOf(s);
-					else if (StringUtils.isNumeric(s))
-						o = StringUtils.parseNumber(s, Number.class);
-					else
-						o = s;
-				} else {
-					o = s;
-				}
-			}
-		} else if (sType.isBoolean()) {
-			o = parseBoolean(session, r);
-		} else if (sType.isCharSequence()) {
-			o = parseString(session, r, isUrlParamValue);
-		} else if (sType.isChar()) {
-			String s = parseString(session, r, isUrlParamValue);
-			o = s == null ? null : s.charAt(0);
-		} else if (sType.isNumber()) {
-			o = parseNumber(session, r, (Class<? extends Number>)sType.getInnerClass());
-		} else if (sType.isMap()) {
-			Map m = (sType.canCreateNewInstance(outer) ? (Map)sType.newInstance(outer) : new ObjectMap(session));
-			o = parseIntoMap(session, r, m, sType.getKeyType(), sType.getValueType(), pMeta);
-		} else if (sType.isCollection()) {
-			if (c == '(') {
-				ObjectMap m = new ObjectMap(session);
-				parseIntoMap(session, r, m, string(), object(), pMeta);
-				// Handle case where it's a collection, but serialized as a map with a _type or _value key.
-				if (m.containsKey(session.getBeanTypePropertyName()))
-					o = session.cast(m, pMeta, eType);
-				// Handle case where it's a collection, but only a single value was specified.
-				else {
-					Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance(outer) : new ObjectList(session));
-					l.add(m.cast(sType.getElementType()));
-					o = l;
-				}
-			} else {
-				Collection l = (sType.canCreateNewInstance(outer) ? (Collection)sType.newInstance(outer) : new ObjectList(session));
-				o = parseIntoCollection(session, r, l, sType.getElementType(), isUrlParamValue, pMeta);
-			}
-		} else if (sType.canCreateNewBean(outer)) {
-			BeanMap m = session.newBeanMap(outer, sType.getInnerClass());
-			m = parseIntoBeanMap(session, r, m);
-			o = m == null ? null : m.getBean();
-		} else if (sType.canCreateNewInstanceFromString(outer)) {
-			String s = parseString(session, r, isUrlParamValue);
-			if (s != null)
-				o = sType.newInstanceFromString(outer, s);
-		} else if (sType.canCreateNewInstanceFromNumber(outer)) {
-			o = sType.newInstanceFromNumber(session, outer, parseNumber(session, r, sType.getNewInstanceFromNumberClass()));
-		} else if (sType.isArray()) {
-			if (c == '(') {
-				ObjectMap m = new ObjectMap(session);
-				parseIntoMap(session, r, m, string(), object(), pMeta);
-				// Handle case where it's an array, but serialized as a map with a _type or _value key.
-				if (m.containsKey(session.getBeanTypePropertyName()))
-					o = session.cast(m, pMeta, eType);
-				// Handle case where it's an array, but only a single value was specified.
-				else {
-					ArrayList l = new ArrayList(1);
-					l.add(m.cast(sType.getElementType()));
-					o = session.toArray(sType, l);
-				}
-			} else {
-				ArrayList l = (ArrayList)parseIntoCollection(session, r, new ArrayList(), sType.getElementType(), isUrlParamValue, pMeta);
-				o = session.toArray(sType, l);
-			}
-		} else if (c == '(') {
-			// It could be a non-bean with _type attribute.
-			ObjectMap m = new ObjectMap(session);
-			parseIntoMap(session, r, m, string(), object(), pMeta);
-			if (m.containsKey(session.getBeanTypePropertyName()))
-				o = session.cast(m, pMeta, eType);
-			else
-				throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
-		} else {
-			throw new ParseException(session, "Class ''{0}'' could not be instantiated.  Reason: ''{1}''", sType.getInnerClass().getName(), sType.getNotABeanReason());
-		}
-
-		if (transform != null && o != null)
-			o = transform.unswap(session, o, eType);
-
-		if (outer != null)
-			setParent(eType, o, outer);
-
-		return (T)o;
-	}
-
-	private <K,V> Map<K,V> parseIntoMap(UonParserSession session, ParserReader r, Map<K,V> m, ClassMeta<K> keyType, ClassMeta<V> valueType, BeanPropertyMeta pMeta) throws Exception {
-
-		if (keyType == null)
-			keyType = (ClassMeta<K>)string();
-
-		int c = r.read();
-		if (c == -1 || c == AMP)
-			return null;
-		if (c == 'n')
-			return (Map<K,V>)parseNull(session, r);
-		if (c != '(')
-			throw new ParseException(session, "Expected '(' at beginning of object.");
-
-		final int S1=1; // Looking for attrName start.
-		final int S2=2; // Found attrName end, looking for =.
-		final int S3=3; // Found =, looking for valStart.
-		final int S4=4; // Looking for , or )
-		boolean isInEscape = false;
-
-		int state = S1;
-		K currAttr = null;
-		while (c != -1 && c != AMP) {
-			c = r.read();
-			if (! isInEscape) {
-				if (state == S1) {
-					if (c == ')')
-						return m;
-					if (Character.isWhitespace(c))
-						skipSpace(r);
-					else {
-						r.unread();
-						Object attr = parseAttr(session, r, session.isDecodeChars());
-						currAttr = attr == null ? null : convertAttrToType(session, m, session.trim(attr.toString()), keyType);
-						state = S2;
-						c = 0; // Avoid isInEscape if c was '\'
-					}
-				} else if (state == S2) {
-					if (c == EQ || c == '=')
-						state = S3;
-					else if (c == -1 || c == ',' || c == ')' || c == AMP) {
-						if (currAttr == null) {
-							// Value was '%00'
-							r.unread();
-							return null;
-						}
-						m.put(currAttr, null);
-						if (c == ')' || c == -1 || c == AMP)
-							return m;
-						state = S1;
-					}
-				} else if (state == S3) {
-					if (c == -1 || c == ',' || c == ')' || c == AMP) {
-						V value = convertAttrToType(session, m, "", valueType);
-						m.put(currAttr, value);
-						if (c == -1 || c == ')' || c == AMP)
-							return m;
-						state = S1;
-					} else  {
-						V value = parseAnything(session, valueType, r.unread(), m, false, pMeta);
-						setName(valueType, value, currAttr);
-						m.put(currAttr, value);
-						state = S4;
-						c = 0; // Avoid isInEscape if c was '\'
-					}
-				} else if (state == S4) {
-					if (c == ',')
-						state = S1;
-					else if (c == ')' || c == -1 || c == AMP) {
-						return m;
-					}
-				}
-			}
-			isInEscape = isInEscape(c, r, isInEscape);
-		}
-		if (state == S1)
-			throw new ParseException(session, "Could not find attribute name on object.");
-		if (state == S2)
-			throw new ParseException(session, "Could not find '=' following attribute name on object.");
-		if (state == S3)
-			throw new ParseException(session, "Dangling '=' found in object entry");
-		if (state == S4)
-			throw new ParseException(session, "Could not find ')' marking end of object.");
-
-		return null; // Unreachable.
-	}
-
-	private <E> Collection<E> parseIntoCollection(UonParserSession session, ParserReader r, Collection<E> l, ClassMeta<E> elementType, boolean isUrlParamValue, BeanPropertyMeta pMeta) throws Exception {
-
-		int c = r.readSkipWs();
-		if (c == -1 || c == AMP)
-			return null;
-		if (c == 'n')
-			return (Collection<E>)parseNull(session, r);
-
-		// If we're parsing a top-level parameter, we're allowed to have comma-delimited lists outside parenthesis (e.g. "&foo=1,2,3&bar=a,b,c")
-		// This is not allowed at lower levels since we use comma's as end delimiters.
-		boolean isInParens = (c == '@');
-		if (! isInParens) {
-			if (isUrlParamValue)
-				r.unread();
-			else
-				throw new ParseException(session, "Could not find '(' marking beginning of collection.");
-		} else {
-			r.read();
-		}
-
-		if (isInParens) {
-			final int S1=1; // Looking for starting of first entry.
-			final int S2=2; // Looking for starting of subsequent entries.
-			final int S3=3; // Looking for , or ) after first entry.
-
-			int state = S1;
-			while (c != -1 && c != AMP) {
-				c = r.read();
-				if (state == S1 || state == S2) {
-					if (c == ')') {
-						if (state == S2) {
-							l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
-							r.read();
-						}
-						return l;
-					} else if (Character.isWhitespace(c)) {
-						skipSpace(r);
-					} else {
-						l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
-						state = S3;
-					}
-				} else if (state == S3) {
-					if (c == ',') {
-						state = S2;
-					} else if (c == ')') {
-						return l;
-					}
-				}
-			}
-			if (state == S1 || state == S2)
-				throw new ParseException(session, "Could not find start of entry in array.");
-			if (state == S3)
-				throw new ParseException(session, "Could not find end of entry in array.");
-
-		} else {
-			final int S1=1; // Looking for starting of entry.
-			final int S2=2; // Looking for , or & or END after first entry.
-
-			int state = S1;
-			while (c != -1 && c != AMP) {
-				c = r.read();
-				if (state == S1) {
-					if (Character.isWhitespace(c)) {
-						skipSpace(r);
-					} else {
-						l.add(parseAnything(session, elementType, r.unread(), l, false, pMeta));
-						state = S2;
-					}
-				} else if (state == S2) {
-					if (c == ',') {
-						state = S1;
-					} else if (Character.isWhitespace(c)) {
-						skipSpace(r);
-					} else if (c == AMP || c == -1) {
-						r.unread();
-						return l;
-					}
-				}
-			}
-		}
-
-		return null;  // Unreachable.
-	}
-
-	private <T> BeanMap<T> parseIntoBeanMap(UonParserSession session, ParserReader r, BeanMap<T> m) throws Exception {
-
-		int c = r.readSkipWs();
-		if (c == -1 || c == AMP)
-			return null;
-		if (c == 'n')
-			return (BeanMap<T>)parseNull(session, r);
-		if (c != '(')
-			throw new ParseException(session, "Expected '(' at beginning of object.");
-
-		final int S1=1; // Looking for attrName start.
-		final int S2=2; // Found attrName end, looking for =.
-		final int S3=3; // Found =, looking for valStart.
-		final int S4=4; // Looking for , or }
-		boolean isInEscape = false;
-
-		int state = S1;
-		String currAttr = "";
-		int currAttrLine = -1, currAttrCol = -1;
-		while (c != -1 && c != AMP) {
-			c = r.read();
-			if (! isInEscape) {
-				if (state == S1) {
-					if (c == ')' || c == -1 || c == AMP) {
-						return m;
-					}
-					if (Character.isWhitespace(c))
-						skipSpace(r);
-					else {
-						r.unread();
-						currAttrLine= r.getLine();
-						currAttrCol = r.getColumn();
-						currAttr = parseAttrName(session, r, session.isDecodeChars());
-						if (currAttr == null)  // Value was '%00'
-							return null;
-						state = S2;
-					}
-				} else if (state == S2) {
-					if (c == EQ || c == '=')
-						state = S3;
-					else if (c == -1 || c == ',' || c == ')' || c == AMP) {
-						m.put(currAttr, null);
-						if (c == ')' || c == -1 || c == AMP)
-							return m;
-						state = S1;
-					}
-				} else if (state == S3) {
-					if (c == -1 || c == ',' || c == ')' || c == AMP) {
-						if (! currAttr.equals(session.getBeanTypePropertyName())) {
-							BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
-							if (pMeta == null) {
-								onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
-							} else {
-								Object value = session.convertToType("", pMeta.getClassMeta());
-								pMeta.set(m, value);
-							}
-						}
-						if (c == -1 || c == ')' || c == AMP)
-							return m;
-						state = S1;
-					} else {
-						if (! currAttr.equals(session.getBeanTypePropertyName())) {
-							BeanPropertyMeta pMeta = m.getPropertyMeta(currAttr);
-							if (pMeta == null) {
-								onUnknownProperty(session, currAttr, m, currAttrLine, currAttrCol);
-								parseAnything(session, object(), r.unread(), m.getBean(false), false, null); // Read content anyway to ignore it
-							} else {
-								session.setCurrentProperty(pMeta);
-								ClassMeta<?> cm = pMeta.getClassMeta();
-								Object value = parseAnything(session, cm, r.unread(), m.getBean(false), false, pMeta);
-								setName(cm, value, currAttr);
-								pMeta.set(m, value);
-								session.setCurrentProperty(null);
-							}
-						}
-						state = S4;
-					}
-				} else if (state == S4) {
-					if (c == ',')
-						state = S1;
-					else if (c == ')' || c == -1 || c == AMP) {
-						return m;
-					}
-				}
-			}
-			isInEscape = isInEscape(c, r, isInEscape);
-		}
-		if (state == S1)
-			throw new ParseException(session, "Could not find attribute name on object.");
-		if (state == S2)
-			throw new ParseException(session, "Could not find '=' following attribute name on object.");
-		if (state == S3)
-			throw new ParseException(session, "Could not find value following '=' on object.");
-		if (state == S4)
-			throw new ParseException(session, "Could not find ')' marking end of object.");
-
-		return null; // Unreachable.
-	}
-
-	Object parseNull(UonParserSession session, ParserReader r) throws Exception {
-		String s = parseString(session, r, false);
-		if ("ull".equals(s))
-			return null;
-		throw new ParseException(session, "Unexpected character sequence: ''{0}''", s);
-	}
-
-	Object parseAttr(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
-		Object attr;
-		attr = parseAttrName(session, r, encoded);
-		return attr;
-	}
-
-	String parseAttrName(UonParserSession session, ParserReader r, boolean encoded) throws Exception {
-
-		// If string is of form 'xxx', we're looking for ' at the end.
-		// Otherwise, we're looking for '&' or '=' or WS or -1 denoting the end of this string.
-
-		int c = r.peekSkipWs();
-		if (c == '\'')
-			return parsePString(session, r);
-
-		r.mark();
-		boolean isInEscape = false;
-		if (encoded) {
-			while (c != -1) {
-				c = r.read();
-				if (! isInEscape) {
-					if (c == AMP || c == EQ || c == -1 || Character.isWhitespace(c)) {
-						if (c != -1)
-							r.unread();
-						String s = r.getMarked();
-						return ("null".equals(s) ? null : s);
-					}
-				}
-				else if (c == AMP)
-					r.replace('&');
-				else if (c == EQ)
-					r.replace('=');
-				isInEscape = isInEscape(c, r, isInEscape);
-			}
-		} else {
-			while (c != -1) {
-				c = r.read();
-				if (! isInEscape) {
-					if (c == '=' || c == -1 || Character.isWhitespace(c)) {
-						if (c != -1)
-							r.unread();
-						String s = r.getMarked();
-						return ("null".equals(s) ? null : session.trim(s));
-					}
-				}
-				isInEscape = isInEscape(c, r, isInEscape);
-			}
-		}
-
-		// We should never get here.
-		throw new ParseException(session, "Unexpected condition.");
-	}
-
-
-	/**
-	 * Returns true if the next character in the stream is preceeded by an escape '~' character.
-	 * @param c The current character.
-	 * @param r The reader.
-	 * @param prevIsInEscape What the flag was last time.
-	 */
-	private static final boolean isInEscape(int c, ParserReader r, boolean prevIsInEscape) throws Exception {
-		if (c == '~' && ! prevIsInEscape) {
-			c = r.peek();
-			if (escapedChars.contains(c)) {
-				r.delete();
-				return true;
-			}
-		}
-		return false;
-	}
-
-	String parseString(UonParserSession session, ParserReader r, boolean isUrlParamValue) throws Exception {
-
-		// If string is of form 'xxx', we're looking for ' at the end.
-		// Otherwise, we're looking for ',' or ')' or -1 denoting the end of this string.
-
-		int c = r.peekSkipWs();
-		if (c == '\'')
-			return parsePString(session, r);
-
-		r.mark();
-		boolean isInEscape = false;
-		String s = null;
-		AsciiSet endChars = (isUrlParamValue ? endCharsParam : endCharsNormal);
-		while (c != -1) {
-			c = r.read();
-			if (! isInEscape) {
-				// If this is a URL parameter value, we're looking for:  &
-				// If not, we're looking for:  &,)
-				if (endChars.contains(c)) {
-					r.unread();
-					c = -1;
-				}
-			}
-			if (c == -1)
-				s = r.getMarked();
-			else if (c == EQ)
-				r.replace('=');
-			else if (Character.isWhitespace(c) && ! isUrlParamValue) {
-				s = r.getMarked(0, -1);
-				skipSpace(r);
-				c = -1;
-			}
-			isInEscape = isInEscape(c, r, isInEscape);
-		}
-
-		if (isUrlParamValue)
-			s = StringUtils.trim(s);
-
-		return ("null".equals(s) ? null : session.trim(s));
-	}
-
-	private static final AsciiSet endCharsParam = new AsciiSet(""+AMP), endCharsNormal = new AsciiSet(",)"+AMP);
-
-
-	/**
-	 * Parses a string of the form "'foo'"
-	 * All whitespace within parenthesis are preserved.
-	 */
-	static String parsePString(UonParserSession session, ParserReader r) throws Exception {
-
-		r.read(); // Skip first quote.
-		r.mark();
-		int c = 0;
-
-		boolean isInEscape = false;
-		while (c != -1) {
-			c = r.read();
-			if (! isInEscape) {
-				if (c == '\'')
-					return session.trim(r.getMarked(0, -1));
-			}
-			if (c == EQ)
-				r.replace('=');
-			isInEscape = isInEscape(c, r, isInEscape);
-		}
-		throw new ParseException(session, "Unmatched parenthesis");
-	}
-
-	private Boolean parseBoolean(UonParserSession session, ParserReader r) throws Exception {
-		String s = parseString(session, r, false);
-		if (s == null || s.equals("null"))
-			return null;
-		if (s.equals("true"))
-			return true;
-		if (s.equals("false"))
-			return false;
-		throw new ParseException(session, "Unrecognized syntax for boolean.  ''{0}''.", s);
-	}
-
-	private Number parseNumber(UonParserSession session, ParserReader r, Class<? extends Number> c) throws Exception {
-		String s = parseString(session, r, false);
-		if (s == null)
-			return null;
-		return StringUtils.parseNumber(s, c);
-	}
-
-	/*
-	 * Call this method after you've finished a parsing a string to make sure that if there's any
-	 * remainder in the input, that it consists only of whitespace and comments.
-	 */
-	private void validateEnd(UonParserSession session, ParserReader r) throws Exception {
-		while (true) {
-			int c = r.read();
-			if (c == -1)
-				return;
-			if (! Character.isWhitespace(c))
-				throw new ParseException(session, "Remainder after parse: ''{0}''.", (char)c);
-		}
-	}
-
-	private Object[] parseArgs(UonParserSession session, ParserReader r, ClassMeta<?>[] argTypes) throws Exception {
-
-		final int S1=1; // Looking for start of entry
-		final int S2=2; // Looking for , or )
-
-		Object[] o = new Object[argTypes.length];
-		int i = 0;
-
-		int c = r.readSkipWs();
-		if (c == -1 || c == AMP)
-			return null;
-		if (c != '@')
-			throw new ParseException(session, "Expected '@' at beginning of args array.");
-		c = r.read();
-
-		int state = S1;
-		while (c != -1 && c != AMP) {
-			c = r.read();
-			if (state == S1) {
-				if (c == ')')
-					return o;
-				o[i] = parseAnything(session, argTypes[i], r.unread(), session.getOuter(), false, null);
-				i++;
-				state = S2;
-			} else if (state == S2) {
-				if (c == ',') {
-					state = S1;
-				} else if (c == ')') {
-					return o;
-				}
-			}
-		}
-
-		throw new ParseException(session, "Did not find ')' at the end of args array.");
-	}
-
-	private static void skipSpace(ParserReader r) throws Exception {
-		int c = 0;
-		while ((c = r.read()) != -1) {
-			if (c <= 2 || ! Character.isWhitespace(c)) {
-				r.unread();
-				return;
-			}
-		}
-	}
-
-	UonParserSession createParameterSession(Object input) {
-		return new UonParserSession(getContext(UonParserContext.class), input);
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Entry point methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Parser */
-	public UonParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new UonParserSession(getContext(UonParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
-	}
-
-	@Override /* Parser */
-	protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
-		UonParserSession s = (UonParserSession)session;
-		UonReader r = s.getReader();
-		T o = parseAnything(s, type, r, s.getOuter(), true, null);
-		validateEnd(s, r);
-		return o;
-	}
-
-	@Override /* ReaderParser */
-	protected <K,V> Map<K,V> doParseIntoMap(ParserSession session, Map<K,V> m, Type keyType, Type valueType) throws Exception {
-		UonParserSession s = (UonParserSession)session;
-		UonReader r = s.getReader();
-		m = parseIntoMap(s, r, m, (ClassMeta<K>)session.getClassMeta(keyType), (ClassMeta<V>)session.getClassMeta(valueType), null);
-		validateEnd(s, r);
-		return m;
-	}
-
-	@Override /* ReaderParser */
-	protected <E> Collection<E> doParseIntoCollection(ParserSession session, Collection<E> c, Type elementType) throws Exception {
-		UonParserSession s = (UonParserSession)session;
-		UonReader r = s.getReader();
-		c = parseIntoCollection(s, r, c, (ClassMeta<E>)session.getClassMeta(elementType), false, null);
-		validateEnd(s, r);
-		return c;
-	}
-
-	@Override /* ReaderParser */
-	protected Object[] doParseArgs(ParserSession session, ClassMeta<?>[] argTypes) throws Exception {
-		UonParserSession s = (UonParserSession)session;
-		UonReader r = s.getReader();
-		Object[] a = parseArgs(s, r, argTypes);
-		return a;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b> Decode <js>"%xx"</js> sequences.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UonParser.decodeChars"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonParser}, <jk>true</jk> for {@link UrlEncodingParser}
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specify <jk>true</jk> if URI encoded characters should be decoded, <jk>false</jk>
-	 * 	if they've already been decoded before being passed to this parser.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>UON_decodeChars</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see UonParserContext#UON_decodeChars
-	 */
-	public UonParser setDecodeChars(boolean value) throws LockedException {
-		return setProperty(UON_decodeChars, value);
-	}
-
-	@Override /* Parser */
-	public UonParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UonParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UonParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UonParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public UonParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UonParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UonParser clone() {
-		try {
-			UonParser c = (UonParser)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
deleted file mode 100644
index 2cc5745..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserContext.java
+++ /dev/null
@@ -1,73 +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.urlencoding;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-
-/**
- * Configurable properties on the {@link UonParser} class.
- * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
- * <p>
- * See {@link ContextFactory} for more information about context properties.
- *
- * <h5 class='section'>Inherited configurable properties:</h5>
- * <ul class='javahierarchy'>
- * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
- * 	<ul>
- * 		<li class='c'><a class="doclink" href="../parser/ParserContext.html#ConfigProperties">ParserContext</a> - Configurable properties common to all parsers.
- * 	</ul>
- * </ul>
- */
-public class UonParserContext extends ParserContext {
-
-	/**
-	 * <b>Configuration property:</b> Decode <js>"%xx"</js> sequences.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UonParser.decodeChars"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonParser}, <jk>true</jk> for {@link UrlEncodingParser}
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specify <jk>true</jk> if URI encoded characters should be decoded, <jk>false</jk>
-	 * 	if they've already been decoded before being passed to this parser.
-	 */
-	public static final String UON_decodeChars = "UonParser.decodeChars";
-
-	final boolean
-		decodeChars;
-
-	/**
-	 * Constructor.
-	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
-	 *
-	 * @param cf The factory that created this context.
-	 */
-	public UonParserContext(ContextFactory cf) {
-		super(cf);
-		this.decodeChars = cf.getProperty(UON_decodeChars, boolean.class, false);
-	}
-
-	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
-			.append("UonParserContext", new ObjectMap()
-				.append("decodeChars", decodeChars)
-			);
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
deleted file mode 100644
index cea28dc..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonParserSession.java
+++ /dev/null
@@ -1,118 +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.urlencoding;
-
-import static org.apache.juneau.urlencoding.UonParserContext.*;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.parser.*;
-
-/**
- * Session object that lives for the duration of a single use of {@link UonParser}.
- * <p>
- * This class is NOT thread safe.  It is meant to be discarded after one-time use.
- */
-public class UonParserSession extends ParserSession {
-
-	private final boolean decodeChars;
-	private UonReader reader;
-
-	/**
-	 * Create a new session using properties specified in the context.
-	 *
-	 * @param ctx The context creating this session object.
-	 * 	he context contains all the configuration settings for this object.
-	 * @param input The input.  Can be any of the following types:
-	 * <ul>
-	 * 	<li><jk>null</jk>
-	 * 	<li>{@link Reader}
-	 * 	<li>{@link CharSequence}
-	 * 	<li>{@link InputStream} containing UTF-8 encoded text.
-	 * 	<li>{@link File} containing system encoded text.
-	 * </ul>
-	 * @param op The override properties.
-	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
-	 * @param outer The outer object for instantiating top-level non-static inner classes.
-	 * @param locale The session locale.
-	 * If <jk>null</jk>, then the locale defined on the context is used.
-	 * @param timeZone The session timezone.
-	 * If <jk>null</jk>, then the timezone defined on the context is used.
-	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
-	 */
-	public UonParserSession(UonParserContext ctx, ObjectMap op, Object input, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		super(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
-		if (op == null || op.isEmpty()) {
-			decodeChars = ctx.decodeChars;
-		} else {
-			decodeChars = op.getBoolean(UON_decodeChars, ctx.decodeChars);
-		}
-	}
-
-	/**
-	 * Create a specialized parser session for parsing URL parameters.
-	 * <p>
-	 * The main difference is that characters are never decoded, and the {@link UonParserContext#UON_decodeChars} property is always ignored.
-	 *
-	 * @param ctx The context to copy setting from.
-	 * @param input The input.  Can be any of the following types:
-	 * 	<ul>
-	 * 		<li><jk>null</jk>
-	 * 		<li>{@link Reader}
-	 * 		<li>{@link CharSequence} (e.g. {@link String})
-	 * 		<li>{@link InputStream} - Read as UTF-8 encoded character stream.
-	 * 		<li>{@link File} - Read as system-default encoded stream.
-	 * 	</ul>
-	 */
-	public UonParserSession(UonParserContext ctx, Object input) {
-		super(ctx, null, input, null, null, null, null, null);
-		decodeChars = false;
-	}
-
-	/**
-	 * Returns the {@link UonParserContext#UON_decodeChars} setting value for this session.
-	 *
-	 * @return The {@link UonParserContext#UON_decodeChars} setting value for this session.
-	 */
-	public final boolean isDecodeChars() {
-		return decodeChars;
-	}
-
-	@Override /* ParserSession */
-	public UonReader getReader() throws Exception {
-		if (reader == null) {
-			Object input = getInput();
-			if (input instanceof UonReader)
-				reader = (UonReader)input;
-			else if (input instanceof CharSequence)
-				reader = new UonReader((CharSequence)input, decodeChars);
-			else
-				reader = new UonReader(super.getReader(), decodeChars);
-		}
-		return reader;
-	}
-
-	@Override /* ParserSession */
-	public Map<String,Object> getLastLocation() {
-		Map<String,Object> m = super.getLastLocation();
-		if (reader != null) {
-			m.put("line", reader.getLine());
-			m.put("column", reader.getColumn());
-		}
-		return m;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonReader.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonReader.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonReader.java
deleted file mode 100644
index feb0557..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonReader.java
+++ /dev/null
@@ -1,195 +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.urlencoding;
-
-import java.io.*;
-
-import org.apache.juneau.parser.*;
-
-/**
- * Same functionality as {@link ParserReader} except automatically decoded <code>%xx</code> escape sequences.
- * <p>
- * Escape sequences are assumed to be encoded UTF-8.  Extended Unicode (&gt;\u10000) is supported.
- * <p>
- * If decoding is enabled, the following character replacements occur so that boundaries are not lost:
- * <ul>
- * 	<li><js>'&amp;'</js> -&gt; <js>'\u0001'</js>
- * 	<li><js>'='</js> -&gt; <js>'\u0002'</js>
- * </ul>
- */
-public final class UonReader extends ParserReader {
-
-	private final boolean decodeChars;
-	private final char[] buff;
-	private int iCurrent, iEnd;
-
-	/**
-	 * Constructor for input from a {@link CharSequence}.
-	 *
-	 * @param in The character sequence being read from.
-	 * @param decodeChars If <jk>true</jk>, decode <code>%xx</code> escape sequences.
-	 */
-	public UonReader(CharSequence in, boolean decodeChars) {
-		super(in);
-		this.decodeChars = decodeChars;
-		if (in == null || ! decodeChars)
-			this.buff = new char[0];
-		else
-			this.buff = new char[in.length() < 1024 ? in.length() : 1024];
-	}
-
-	/**
-	 * Constructor for input from a {@link Reader}).
-	 *
-	 * @param r The Reader being wrapped.
-	 * @param decodeChars If <jk>true</jk>, decode <code>%xx</code> escape sequences.
-	 */
-	public UonReader(Reader r, boolean decodeChars) {
-		super(r);
-		this.decodeChars = decodeChars;
-		this.buff = new char[1024];
-	}
-
-	@Override /* Reader */
-	public final int read(char[] cbuf, int off, int len) throws IOException {
-
-		if (! decodeChars)
-			return super.read(cbuf, off, len);
-
-		// Copy any remainder to the beginning of the buffer.
-		int remainder = iEnd - iCurrent;
-		if (remainder > 0)
-			System.arraycopy(buff, iCurrent, buff, 0, remainder);
-		iCurrent = 0;
-
-		int expected = buff.length - remainder;
-
-		int x = super.read(buff, remainder, expected);
-		if (x == -1 && remainder == 0)
-			return -1;
-
-		iEnd = remainder + (x == -1 ? 0 : x);
-
-		int i = 0;
-		while (i < len) {
-			if (iCurrent >= iEnd)
-				return i;
-			char c = buff[iCurrent++];
-			if (c == '+') {
-				cbuf[off + i++] = ' ';
-			} else if (c == '&') {
-				cbuf[off + i++] = '\u0001';
-			} else if (c == '=') {
-				cbuf[off + i++] = '\u0002';
-			} else if (c != '%') {
-				cbuf[off + i++] = c;
-			} else {
-				int iMark = iCurrent-1;  // Keep track of current position.
-
-				// Stop if there aren't at least two more characters following '%' in the buffer,
-				// or there aren't at least two more positions open in cbuf to handle double-char chars.
-				if (iMark+2 >= iEnd || i+2 > len) {
-					iCurrent--;
-					return i;
-				}
-
-				int b0 = readEncodedByte();
-				int cx;
-
-				// 0xxxxxxx
-				if (b0 < 128) {
-					cx = b0;
-
-				// 10xxxxxx
-				} else if (b0 < 192) {
-					throw new IOException("Invalid hex value for first escape pattern in UTF-8 sequence:  " + b0);
-
-				// 110xxxxx	10xxxxxx
-				// 11000000(192) - 11011111(223)
-				} else if (b0 < 224) {
-					cx = readUTF8(b0-192, 1);
-					if (cx == -1) {
-						iCurrent = iMark;
-						return i;
-					}
-
-				// 1110xxxx	10xxxxxx	10xxxxxx
-				// 11100000(224) - 11101111(239)
-				} else if (b0 < 240) {
-					cx = readUTF8(b0-224, 2);
-					if (cx == -1) {
-						iCurrent = iMark;
-						return i;
-					}
-
-				// 11110xxx	10xxxxxx	10xxxxxx	10xxxxxx
-				// 11110000(240) - 11110111(247)
-				} else if (b0 < 248) {
-					cx = readUTF8(b0-240, 3);
-					if (cx == -1) {
-						iCurrent = iMark;
-						return i;
-					}
-
-				} else
-					throw new IOException("Invalid hex value for first escape pattern in UTF-8 sequence:  " + b0);
-
-				if (cx < 0x10000)
-					cbuf[off + i++] = (char)cx;
-				else {
-					cx -= 0x10000;
-					cbuf[off + i++] = (char)(0xd800 + (cx >> 10));
-					cbuf[off + i++] = (char)(0xdc00 + (cx & 0x3ff));
-				}
-			}
-		}
-		return i;
-	}
-
-	private final int readUTF8(int n, final int numBytes) throws IOException {
-		if (iCurrent + numBytes*3 > iEnd)
-			return -1;
-		for (int i = 0; i < numBytes; i++) {
-			n <<= 6;
-			n += readHex()-128;
-		}
-		return n;
-	}
-
-	private final int readHex() throws IOException {
-		int c = buff[iCurrent++];
-		if (c != '%')
-			throw new IOException("Did not find expected '%' character in UTF-8 sequence.");
-		return readEncodedByte();
-	}
-
-	private final int readEncodedByte() throws IOException {
-		if (iEnd <= iCurrent + 1)
-			throw new IOException("Incomplete trailing escape pattern");
-		int h = buff[iCurrent++];
-		int l = buff[iCurrent++];
-		h = fromHexChar(h);
-		l = fromHexChar(l);
-		return (h << 4) + l;
-	}
-
-	private final int fromHexChar(int c) throws IOException {
-		if (c >= '0' && c <= '9')
-			return c - '0';
-		if (c >= 'a' && c <= 'f')
-			return 10 + c - 'a';
-		if (c >= 'A' && c <= 'F')
-			return 10 + c - 'A';
-		throw new IOException("Invalid hex character '"+c+"' found in escape pattern.");
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
deleted file mode 100644
index d5ca9e7..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializer.java
+++ /dev/null
@@ -1,869 +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.urlencoding;
-
-import static org.apache.juneau.urlencoding.UonSerializerContext.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.transform.*;
-
-/**
- * Serializes POJO models to UON (a notation for URL-encoded query parameter values).
- *
- * <h5 class='section'>Media types:</h5>
- * <p>
- * Handles <code>Accept</code> types: <code>text/uon</code>
- * <p>
- * Produces <code>Content-Type</code> types: <code>text/uon</code>
- *
- * <h5 class='section'>Description:</h5>
- * <p>
- * This serializer provides several serialization options.  Typically, one of the predefined DEFAULT serializers will be sufficient.
- * However, custom serializers can be constructed to fine-tune behavior.
- *
- * <h5 class='section'>Configurable properties:</h5>
- * <p>
- * This class has the following properties associated with it:
- * <ul>
- * 	<li>{@link UonSerializerContext}
- * 	<li>{@link BeanContext}
- * </ul>
- * <p>
- * The following shows a sample object defined in Javascript:
- * </p>
- * <p class='bcode'>
- * 	{
- * 		id: 1,
- * 		name: <js>'John Smith'</js>,
- * 		uri: <js>'http://sample/addressBook/person/1'</js>,
- * 		addressBookUri: <js>'http://sample/addressBook'</js>,
- * 		birthDate: <js>'1946-08-12T00:00:00Z'</js>,
- * 		otherIds: <jk>null</jk>,
- * 		addresses: [
- * 			{
- * 				uri: <js>'http://sample/addressBook/address/1'</js>,
- * 				personUri: <js>'http://sample/addressBook/person/1'</js>,
- * 				id: 1,
- * 				street: <js>'100 Main Street'</js>,
- * 				city: <js>'Anywhereville'</js>,
- * 				state: <js>'NY'</js>,
- * 				zip: 12345,
- * 				isCurrent: <jk>true</jk>,
- * 			}
- * 		]
- * 	}
- * </p>
- * <p>
- * Using the "strict" syntax defined in this document, the equivalent
- * 	UON notation would be as follows:
- * </p>
- * <p class='bcode'>
- * 	(
- * 		<ua>id</ua>=<un>1</un>,
- * 		<ua>name</ua>=<us>'John+Smith'</us>,
- * 		<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,
- * 		<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
- * 		<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
- * 		<ua>otherIds</ua>=<uk>null</uk>,
- * 		<ua>addresses</ua>=@(
- * 			(
- * 				<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>,
- * 				<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>,
- * 				<ua>id</ua>=<un>1</un>,
- * 				<ua>street</ua>=<us>'100+Main+Street'</us>,
- * 				<ua>city</ua>=<us>Anywhereville</us>,
- * 				<ua>state</ua>=<us>NY</us>,
- * 				<ua>zip</ua>=<un>12345</un>,
- * 				<ua>isCurrent</ua>=<uk>true</uk>
- * 			)
- * 		)
- * 	)
- * </p>
- *
- * <h5 class='section'>Example:</h5>
- * <p class='bcode'>
- * 	<jc>// Serialize a Map</jc>
- * 	Map m = <jk>new</jk> ObjectMap(<js>"{a:'b',c:1,d:false,e:['f',1,false],g:{h:'i'}}"</js>);
- *
- * 	<jc>// Serialize to value equivalent to JSON.</jc>
- * 	<jc>// Produces "(a=b,c=1,d=false,e=@(f,1,false),g=(h=i))"</jc>
- * 	String s = UonSerializer.<jsf>DEFAULT</jsf>.serialize(s);
- *
- * 	<jc>// Serialize a bean</jc>
- * 	<jk>public class</jk> Person {
- * 		<jk>public</jk> Person(String s);
- * 		<jk>public</jk> String getName();
- * 		<jk>public int</jk> getAge();
- * 		<jk>public</jk> Address getAddress();
- * 		<jk>public boolean</jk> deceased;
- * 	}
- *
- * 	<jk>public class</jk> Address {
- * 		<jk>public</jk> String getStreet();
- * 		<jk>public</jk> String getCity();
- * 		<jk>public</jk> String getState();
- * 		<jk>public int</jk> getZip();
- * 	}
- *
- * 	Person p = <jk>new</jk> Person(<js>"John Doe"</js>, 23, <js>"123 Main St"</js>, <js>"Anywhere"</js>, <js>"NY"</js>, 12345, <jk>false</jk>);
- *
- * 	<jc>// Produces "(name='John Doe',age=23,address=(street='123 Main St',city=Anywhere,state=NY,zip=12345),deceased=false)"</jc>
- * 	String s = UonSerializer.<jsf>DEFAULT</jsf>.serialize(s);
- * </p>
- */
-@Produces("text/uon")
-public class UonSerializer extends WriterSerializer {
-
-	/** Reusable instance of {@link UonSerializer}, all default settings. */
-	public static final UonSerializer DEFAULT = new UonSerializer().lock();
-
-	/** Reusable instance of {@link UonSerializer.Readable}. */
-	public static final UonSerializer DEFAULT_READABLE = new Readable().lock();
-
-	/** Reusable instance of {@link UonSerializer.Encoding}. */
-	public static final UonSerializer DEFAULT_ENCODING = new Encoding().lock();
-
-	/**
-	 * Equivalent to <code><jk>new</jk> UonSerializer().setUseWhitespace(<jk>true</jk>).setUseIndentation(<jk>true</jk>);</code>.
-	 */
-	public static class Readable extends UonSerializer {
-		/** Constructor */
-		public Readable() {
-			setUseWhitespace(true);
-		}
-	}
-
-	/**
-	 * Equivalent to <code><jk>new</jk> UonSerializer().setEncodeChars(<jk>true</jk>);</code>.
-	 */
-	public static class Encoding extends UonSerializer {
-		/** Constructor */
-		public Encoding() {
-			setEncodeChars(true);
-		}
-	}
-
-	/**
-	 * Workhorse method. Determines the type of object, and then calls the
-	 * appropriate type-specific serialization method.
-	 * @param session The context that exist for the duration of a serialize.
-	 * @param out The writer to serialize to.
-	 * @param o The object being serialized.
-	 * @param eType The expected type of the object if this is a bean property.
-	 * @param attrName The bean property name if this is a bean property.  <jk>null</jk> if this isn't a bean property being serialized.
-	 * @param pMeta The bean property metadata.
-	 *
-	 * @return The same writer passed in.
-	 * @throws Exception
-	 */
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	protected SerializerWriter serializeAnything(UonSerializerSession session, UonWriter out, Object o, ClassMeta<?> eType,
-			String attrName, BeanPropertyMeta pMeta) throws Exception {
-
-		if (o == null) {
-			out.appendObject(null, false);
-			return out;
-		}
-
-		if (eType == null)
-			eType = object();
-
-		ClassMeta<?> aType;			// The actual type
-		ClassMeta<?> sType;			// The serialized type
-
-		aType = session.push(attrName, o, eType);
-		boolean isRecursion = aType == null;
-
-		// Handle recursion
-		if (aType == null) {
-			o = null;
-			aType = object();
-		}
-
-		sType = aType.getSerializedClassMeta();
-		String typeName = session.getBeanTypeName(eType, aType, pMeta);
-
-		// Swap if necessary
-		PojoSwap swap = aType.getPojoSwap();
-		if (swap != null) {
-			o = swap.swap(session, o);
-
-			// If the getSwapClass() method returns Object, we need to figure out
-			// the actual type now.
-			if (sType.isObject())
-				sType = session.getClassMetaForObject(o);
-		}
-
-		// '\0' characters are considered null.
-		if (o == null || (sType.isChar() && ((Character)o).charValue() == 0))
-			out.appendObject(null, false);
-		else if (sType.isBoolean())
-			out.appendBoolean(o);
-		else if (sType.isNumber())
-			out.appendNumber(o);
-		else if (sType.isBean())
-			serializeBeanMap(session, out, session.toBeanMap(o), typeName);
-		else if (sType.isUri() || (pMeta != null && pMeta.isUri()))
-			out.appendUri(o);
-		else if (sType.isMap()) {
-			if (o instanceof BeanMap)
-				serializeBeanMap(session, out, (BeanMap)o, typeName);
-			else
-				serializeMap(session, out, (Map)o, eType);
-		}
-		else if (sType.isCollection()) {
-			serializeCollection(session, out, (Collection) o, eType);
-		}
-		else if (sType.isArray()) {
-			serializeCollection(session, out, toList(sType.getInnerClass(), o), eType);
-		}
-		else {
-			out.appendObject(o, false);
-		}
-
-		if (! isRecursion)
-			session.pop();
-		return out;
-	}
-
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private SerializerWriter serializeMap(UonSerializerSession session, UonWriter out, Map m, ClassMeta<?> type) throws Exception {
-
-		m = session.sort(m);
-
-		ClassMeta<?> keyType = type.getKeyType(), valueType = type.getValueType();
-
-		int depth = session.getIndent();
-		out.append('(');
-
-		Iterator mapEntries = m.entrySet().iterator();
-
-		while (mapEntries.hasNext()) {
-			Map.Entry e = (Map.Entry) mapEntries.next();
-			Object value = e.getValue();
-			Object key = session.generalize(e.getKey(), keyType);
-			out.cr(depth).appendObject(key, false).append('=');
-			serializeAnything(session, out, value, valueType, (key == null ? null : session.toString(key)), null);
-			if (mapEntries.hasNext())
-				out.append(',');
-		}
-
-		if (m.size() > 0)
-			out.cr(depth-1);
-		out.append(')');
-
-		return out;
-	}
-
-	private SerializerWriter serializeBeanMap(UonSerializerSession session, UonWriter out, BeanMap<?> m, String typeName) throws Exception {
-		int depth = session.getIndent();
-
-		out.append('(');
-
-		boolean addComma = false;
-
-		for (BeanPropertyValue p : m.getValues(session.isTrimNulls(), typeName != null ? session.createBeanTypeNameProperty(m, typeName) : null)) {
-			BeanPropertyMeta pMeta = p.getMeta();
-			ClassMeta<?> cMeta = p.getClassMeta();
-
-			String key = p.getName();
-			Object value = p.getValue();
-			Throwable t = p.getThrown();
-			if (t != null)
-				session.addBeanGetterWarning(pMeta, t);
-
-			if (session.canIgnoreValue(cMeta, key, value))
-				continue;
-
-			if (addComma)
-				out.append(',');
-
-			out.cr(depth).appendObject(key, false).append('=');
-
-			serializeAnything(session, out, value, cMeta, key, pMeta);
-
-			addComma = true;
-		}
-
-		if (m.size() > 0)
-			out.cr(depth-1);
-		out.append(')');
-
-		return out;
-	}
-
-	@SuppressWarnings({ "rawtypes", "unchecked" })
-	private SerializerWriter serializeCollection(UonSerializerSession session, UonWriter out, Collection c, ClassMeta<?> type) throws Exception {
-
-		ClassMeta<?> elementType = type.getElementType();
-
-		c = session.sort(c);
-
-		out.append('@').append('(');
-
-		int depth = session.getIndent();
-
-		for (Iterator i = c.iterator(); i.hasNext();) {
-			out.cr(depth);
-			serializeAnything(session, out, i.next(), elementType, "<iterator>", null);
-			if (i.hasNext())
-				out.append(',');
-		}
-
-		if (c.size() > 0)
-			out.cr(depth-1);
-		out.append(')');
-
-		return out;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Entry point methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Serializer */
-	public UonSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new UonSerializerSession(getContext(UonSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
-	}
-
-	@Override /* Serializer */
-	protected void doSerialize(SerializerSession session, Object o) throws Exception {
-		UonSerializerSession s = (UonSerializerSession)session;
-		serializeAnything(s, s.getWriter(), o, null, "root", null);
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Encode non-valid URI characters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UonSerializer.encodeChars"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonSerializer}, <jk>true</jk> for {@link UrlEncodingSerializer}
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Encode non-valid URI characters with <js>"%xx"</js> constructs.
-	 * <p>
-	 * If <jk>true</jk>, non-valid URI characters will be converted to <js>"%xx"</js> sequences.
-	 * Set to <jk>false</jk> if parameter value is being passed to some other code that will already
-	 * 	perform URL-encoding of non-valid URI characters.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>UON_encodeChars</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see UonSerializerContext#UON_encodeChars
-	 */
-	public UonSerializer setEncodeChars(boolean value) throws LockedException {
-		return setProperty(UON_encodeChars, value);
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UonSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UonSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public UonSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UonSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UonSerializer clone() {
-		try {
-			UonSerializer c = (UonSerializer)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
-}


[26/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/CoreApi.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreApi.java b/juneau-core/src/main/java/org/apache/juneau/CoreApi.java
deleted file mode 100644
index f93b180..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/CoreApi.java
+++ /dev/null
@@ -1,1552 +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;
-
-import static org.apache.juneau.BeanContext.*;
-
-import java.beans.*;
-import java.io.*;
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.juneau.Visibility;
-import org.apache.juneau.annotation.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
-import org.apache.juneau.transform.*;
-
-/**
- * Common super class for all core-API serializers, parsers, and serializer/parser groups.
- *
- * <h5 class='section'>Description:</h5>
- * <p>
- * Maintains an inner {@link ContextFactory} instance that can be used by serializer and parser subclasses
- * 	to work with beans in a consistent way.
- * <p>
- * Provides several duplicate convenience methods from the {@link ContextFactory} class to set properties on that class from this class.
- * <p>
- * Also implements the {@link Lockable} interface to allow for easy locking and cloning.
- */
-public abstract class CoreApi extends Lockable {
-
-	private ContextFactory contextFactory = ContextFactory.create();
-	private BeanContext beanContext;
-
-	/**
-	 * Returns the {@link ContextFactory} object associated with this class.
-	 * <p>
-	 * The context factory stores all configuration properties for this class.
-	 * Adding/modifying properties on this factory will alter the behavior of this object.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>Calling the {@link ContextFactory#lock()} method on the returned object will prevent any further modifications to the configuration for this object
-	 * 		ANY ANY OTHERS THAT SHARE THE SAME FACTORY!.
-	 * 	<li>Calling the {@link #lock()} method on this class will only lock the configuration for this particular instance of the class.
-	 * </ul>
-	 *
-	 * @return The context factory associated with this object.
-	 */
-	public ContextFactory getContextFactory() {
-		return contextFactory;
-	}
-
-	/**
-	 * Returns the bean context to use for this class.
-	 *
-	 * @return The bean context object.
-	 */
-	public BeanContext getBeanContext() {
-		if (beanContext == null)
-			return contextFactory.getContext(BeanContext.class);
-		return beanContext;
-	}
-
-	/**
-	 * Creates a {@link Context} class instance of the specified type.
-	 * <p>
-	 * For example, to create an <code>HtmlSerializerContext</code> object that contains a read-only snapshot
-	 * of all the current settings in this object...
-	 * <p class='bcode'>
-	 * 	HtmlSerializerContext ctx = htmlParser.getContext(HtmlDocSerializerContext.<jk>class</jk>);
-	 * </p>
-	 *
-	 * @param contextClass The class instance to create.
-	 * @return A context class instance of the specified type.
-	 */
-	protected final <T extends Context> T getContext(Class<T> contextClass) {
-		return contextFactory.getContext(contextClass);
-	}
-
-	/**
-	 * Sets a configuration property on this object.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().setProperty(name, value);</code>.
-	 * </ul>
-	 *
-	 * @param name The property name.
-	 * @param value The property value.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object or {@link ContextFactory} object.
-	 * @see ContextFactory#setProperty(String, Object)
-	 */
-	public CoreApi setProperty(String name, Object value) throws LockedException {
-		checkLock();
-		contextFactory.setProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Sets multiple configuration properties on this object.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().setProperties(properties);</code>.
-	 * </ul>
-	 *
-	 * @param properties The properties to set on this class.
-	 * @return This class (for method chaining).
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 * @see ContextFactory#setProperties(java.util.Map)
-	 */
-	public CoreApi setProperties(ObjectMap properties) throws LockedException {
-		checkLock();
-		contextFactory.setProperties(properties);
-		return this;
-	}
-
-	/**
-	 * Adds a value to a SET property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().addToProperty(name, value);</code>.
-	 * </ul>
-	 *
-	 * @param name The property name.
-	 * @param value The new value to add to the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public CoreApi addToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		contextFactory.addToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Adds or overwrites a value to a MAP property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().putToProperty(name, key, value);</code>.
-	 * </ul>
-	 *
-	 * @param name The property name.
-	 * @param key The property value map key.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public CoreApi putToProperty(String name, Object key, Object value) throws LockedException {
-		checkLock();
-		contextFactory.putToProperty(name, key, value);
-		return this;
-	}
-
-	/**
-	 * Adds or overwrites a value to a MAP property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().putToProperty(name, value);</code>.
-	 * </ul>
-	 *
-	 * @param name The property value.
-	 * @param value The property value map value.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a MAP property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public CoreApi putToProperty(String name, Object value) throws LockedException {
-		checkLock();
-		contextFactory.putToProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Removes a value from a SET property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getContextFactory().removeFromProperty(name, value);</code>.
-	 * </ul>
-	 *
-	 * @param name The property name.
-	 * @param value The property value in the SET property.
-	 * @return This object (for method chaining).
-	 * @throws ConfigException If property is not a SET property.
-	 * @throws LockedException If {@link #lock()} has been called on this object.
-	 */
-	public CoreApi removeFromProperty(String name, Object value) throws LockedException {
-		checkLock();
-		contextFactory.removeFromProperty(name, value);
-		return this;
-	}
-
-	/**
-	 * Returns the universal <code>Object</code> metadata object.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getBeanContext().object();</code>.
-	 * </ul>
-	 *
-	 * @return The reusable {@link ClassMeta} for representing the {@link Object} class.
-	 */
-	public ClassMeta<Object> object() {
-		return getBeanContext().object();
-	}
-
-	/**
-	 * Returns the universal <code>String</code> metadata object.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>getBeanContext().string();</code>.
-	 * </ul>
-	 *
-	 * @return The reusable {@link ClassMeta} for representing the {@link String} class.
-	 */
-	public ClassMeta<String> string() {
-		return getBeanContext().string();
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Beans require no-arg constructors.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireDefaultConstructor"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, a Java class must implement a default no-arg constructor to be considered a bean.
-	 * Otherwise, the bean will be serialized as a string using the {@link #toString()} method.
-	 * <p>
-	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beansRequireDefaultConstructor</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireDefaultConstructor
-	 */
-	public CoreApi setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		return setProperty(BEAN_beansRequireDefaultConstructor, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Beans require {@link Serializable} interface.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSerializable"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, a Java class must implement the {@link Serializable} interface to be considered a bean.
-	 * Otherwise, the bean will be serialized as a string using the {@link #toString()} method.
-	 * <p>
-	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beansRequireSerializable</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSerializable
-	 */
-	public CoreApi setBeansRequireSerializable(boolean value) throws LockedException {
-		return setProperty(BEAN_beansRequireSerializable, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Beans require setters for getters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSettersForGetters"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, only getters that have equivalent setters will be considered as properties on a bean.
-	 * Otherwise, they will be ignored.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beansRequireSettersForGetters</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSettersForGetters
-	 */
-	public CoreApi setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		return setProperty(BEAN_beansRequireSettersForGetters, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Beans require at least one property.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beansRequireSomeProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, then a Java class must contain at least 1 property to be considered a bean.
-	 * Otherwise, the bean will be serialized as a string using the {@link #toString()} method.
-	 * <p>
-	 * The {@link Bean @Bean} annotation can be used on a class to override this setting when <jk>true</jk>.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beansRequireSomeProperties</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beansRequireSomeProperties
-	 */
-	public CoreApi setBeansRequireSomeProperties(boolean value) throws LockedException {
-		return setProperty(BEAN_beansRequireSomeProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  {@link BeanMap#put(String,Object) BeanMap.put()} method will return old property value.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanMapPutReturnsOldValue"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, then the {@link BeanMap#put(String,Object) BeanMap.put()} method will return old property values.
-	 * Otherwise, it returns <jk>null</jk>.
-	 * <p>
-	 * Disabled by default because it introduces a slight performance penalty.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanMapPutReturnsOldValue</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanMapPutReturnsOldValue
-	 */
-	public CoreApi setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		return setProperty(BEAN_beanMapPutReturnsOldValue, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for bean constructors with the specified minimum visibility.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanConstructorVisibility"</js>
-	 * 	<li><b>Data type:</b> {@link Visibility}
-	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Constructors not meeting this minimum visibility will be ignored.
-	 * For example, if the visibility is <code>PUBLIC</code> and the constructor is <jk>protected</jk>, then
-	 * 	the constructor will be ignored.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanConstructorVisibility</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanConstructorVisibility
-	 */
-	public CoreApi setBeanConstructorVisibility(Visibility value) throws LockedException {
-		return setProperty(BEAN_beanConstructorVisibility, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for bean classes with the specified minimum visibility.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanClassVisibility"</js>
-	 * 	<li><b>Data type:</b> {@link Visibility}
-	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Classes are not considered beans unless they meet the minimum visibility requirements.
-	 * For example, if the visibility is <code>PUBLIC</code> and the bean class is <jk>protected</jk>, then
-	 * 	the class will not be interpreted as a bean class.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanClassVisibility</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanClassVisibility
-	 */
-	public CoreApi setBeanClassVisibility(Visibility value) throws LockedException {
-		return setProperty(BEAN_beanClassVisibility, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for bean fields with the specified minimum visibility.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanFieldVisibility"</js>
-	 * 	<li><b>Data type:</b> {@link Visibility}
-	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Fields are not considered bean properties unless they meet the minimum visibility requirements.
-	 * For example, if the visibility is <code>PUBLIC</code> and the bean field is <jk>protected</jk>, then
-	 * 	the field will not be interpreted as a bean property.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanFieldVisibility</jsf>, value)</code>.
-	 * 	<li>Use {@link Visibility#NONE} to prevent bean fields from being interpreted as bean properties altogether.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFieldVisibility
-	 */
-	public CoreApi setBeanFieldVisibility(Visibility value) throws LockedException {
-		return setProperty(BEAN_beanFieldVisibility, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Look for bean methods with the specified minimum visibility.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.methodVisibility"</js>
-	 * 	<li><b>Data type:</b> {@link Visibility}
-	 * 	<li><b>Default:</b> {@link Visibility#PUBLIC}
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Methods are not considered bean getters/setters unless they meet the minimum visibility requirements.
-	 * For example, if the visibility is <code>PUBLIC</code> and the bean method is <jk>protected</jk>, then
-	 * 	the method will not be interpreted as a bean getter or setter.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_methodVisibility</jsf>, value)</code>.
-	 * 	<li>Use {@link Visibility#NONE} to prevent bean methods from being interpreted as bean properties altogether.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_methodVisibility
-	 */
-	public CoreApi setMethodVisibility(Visibility value) throws LockedException {
-		return setProperty(BEAN_methodVisibility, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Use Java {@link Introspector} for determining bean properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.useJavaBeanIntrospector"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Using the built-in Java bean introspector will not pick up fields or non-standard getters/setters.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_useJavaBeanIntrospector</jsf>, value)</code>.
-	 * 	<li>Most {@link Bean @Bean} annotations will be ignored if you enable this setting.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useJavaBeanIntrospector
-	 */
-	public CoreApi setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		return setProperty(BEAN_useJavaBeanIntrospector, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Use interface proxies.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.useInterfaceProxies"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, then interfaces will be instantiated as proxy classes through the use of an {@link InvocationHandler}
-	 * if there is no other way of instantiating them.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_useInterfaceProxies</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_useInterfaceProxies
-	 */
-	public CoreApi setUseInterfaceProxies(boolean value) throws LockedException {
-		return setProperty(BEAN_useInterfaceProxies, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore unknown properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreUnknownBeanProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, trying to set a value on a non-existent bean property will silently be ignored.
-	 * Otherwise, a {@code BeanRuntimeException} is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_ignoreUnknownBeanProperties</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownBeanProperties
-	 */
-	public CoreApi setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		return setProperty(BEAN_ignoreUnknownBeanProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore unknown properties with null values.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreUnknownNullBeanProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, trying to set a <jk>null</jk> value on a non-existent bean property will silently be ignored.
-	 * Otherwise, a {@code BeanRuntimeException} is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_ignoreUnknownNullBeanProperties</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreUnknownNullBeanProperties
-	 */
-	public CoreApi setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		return setProperty(BEAN_ignoreUnknownNullBeanProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore properties without setters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.ignorePropertiesWithoutSetters"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, trying to set a value on a bean property without a setter will silently be ignored.
-	 * Otherwise, a {@code BeanRuntimeException} is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_ignorePropertiesWithoutSetters</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignorePropertiesWithoutSetters
-	 */
-	public CoreApi setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		return setProperty(BEAN_ignorePropertiesWithoutSetters, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore invocation errors on getters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreInvocationExceptionsOnGetters"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, errors thrown when calling bean getter methods will silently be ignored.
-	 * Otherwise, a {@code BeanRuntimeException} is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_ignoreInvocationExceptionsOnGetters</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnGetters
-	 */
-	public CoreApi setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		return setProperty(BEAN_ignoreInvocationExceptionsOnGetters, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore invocation errors on setters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.ignoreInvocationExceptionsOnSetters"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, errors thrown when calling bean setter methods will silently be ignored.
-	 * Otherwise, a {@code BeanRuntimeException} is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_ignoreInvocationExceptionsOnSetters</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_ignoreInvocationExceptionsOnSetters
-	 */
-	public CoreApi setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		return setProperty(BEAN_ignoreInvocationExceptionsOnSetters, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Sort bean properties in alphabetical order.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.sortProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * When <jk>true</jk>, all bean properties will be serialized and access in alphabetical order.
-	 * Otherwise, the natural order of the bean properties is used which is dependent on the
-	 * 	JVM vendor.
-	 * On IBM JVMs, the bean properties are ordered based on their ordering in the Java file.
-	 * On Oracle JVMs, the bean properties are not ordered (which follows the offical JVM specs).
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_sortProperties</jsf>, value)</code>.
-	 * 	<li>This property is disabled by default so that IBM JVM users don't have to use {@link Bean @Bean} annotations
-	 * 		to force bean properties to be in a particular order and can just alter the order of the fields/methods
-	 * 		in the Java file.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_sortProperties
-	 */
-	public CoreApi setSortProperties(boolean value) throws LockedException {
-		return setProperty(BEAN_sortProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Packages whose classes should not be considered beans.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.notBeanPackages.set"</js>
-	 * 	<li><b>Data type:</b> <code>Set&lt;String&gt;</code>
-	 * 	<li><b>Default:</b>
-	 * 	<ul>
-	 * 		<li><code>java.lang</code>
-	 * 		<li><code>java.lang.annotation</code>
-	 * 		<li><code>java.lang.ref</code>
-	 * 		<li><code>java.lang.reflect</code>
-	 * 		<li><code>java.io</code>
-	 * 		<li><code>java.net</code>
-	 * 		<li><code>java.nio.*</code>
-	 * 		<li><code>java.util.*</code>
-	 * 	</ul>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * When specified, the current list of ignore packages are appended to.
-	 * <p>
-	 * Any classes within these packages will be serialized to strings using {@link Object#toString()}.
-	 * <p>
-	 * Note that you can specify prefix patterns to include all subpackages.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_notBeanPackages</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public CoreApi setNotBeanPackages(String...values) throws LockedException {
-		return setProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Packages whose classes should not be considered beans.
-	 * <p>
-	 * Same as {@link #setNotBeanPackages(String...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public CoreApi setNotBeanPackages(Collection<String> values) throws LockedException {
-		return setProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to packages whose classes should not be considered beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_notBeanPackages</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_notBeanPackages_add</jsf>, s)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages_add
-	 */
-	public CoreApi addNotBeanPackages(String...values) throws LockedException {
-		return addToProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to packages whose classes should not be considered beans.
-	 * <p>
-	 * Same as {@link #addNotBeanPackages(String...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public CoreApi addNotBeanPackages(Collection<String> values) throws LockedException {
-		return addToProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from packages whose classes should not be considered beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_notBeanPackages</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_notBeanPackages_remove</jsf>, s)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public CoreApi removeNotBeanPackages(String...values) throws LockedException {
-		return removeFromProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from packages whose classes should not be considered beans.
-	 * <p>
-	 * Same as {@link #removeNotBeanPackages(String...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 * @see BeanContext#BEAN_notBeanPackages_remove
-	 */
-	public CoreApi removeNotBeanPackages(Collection<String> values) throws LockedException {
-		return removeFromProperty(BEAN_notBeanPackages, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Classes to be excluded from consideration as being beans.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.notBeanClasses.set"</js>
-	 * 	<li><b>Data type:</b> <code>Set&lt;Class&gt;</code>
-	 * 	<li><b>Default:</b> empty set
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Not-bean classes are typically converted to <code>Strings</code> during serialization even if they
-	 * appear to be bean-like.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_notBeanClasses</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 */
-	public CoreApi setNotBeanClasses(Class<?>...values) throws LockedException {
-		return setProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Classes to be excluded from consideration as being beans.
-	 * <p>
-	 * Same as {@link #setNotBeanClasses(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanPackages
-	 */
-	public CoreApi setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		return setProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to classes that should not be considered beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_notBeanClasses</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_notBeanClasses_add</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public CoreApi addNotBeanClasses(Class<?>...values) throws LockedException {
-		return addToProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to classes that should not be considered beans.
-	 * <p>
-	 * Same as {@link #addNotBeanClasses(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_add
-	 */
-	public CoreApi addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		return addToProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from classes that should not be considered beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_notBeanClasses</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_notBeanClasses_remove</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public CoreApi removeNotBeanClasses(Class<?>...values) throws LockedException {
-		return removeFromProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from classes that should not be considered beans.
-	 * <p>
-	 * Same as {@link #removeNotBeanClasses(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_notBeanClasses
-	 * @see BeanContext#BEAN_notBeanClasses_remove
-	 */
-	public CoreApi removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		return removeFromProperty(BEAN_notBeanClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Bean filters to apply to beans.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanFilters.list"</js>
-	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
-	 * 	<li><b>Default:</b> empty list
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * This is a programmatic equivalent to the {@link Bean @Bean} annotation.
-	 * It's useful when you want to use the Bean annotation functionality, but you don't have the ability
-	 * 	to alter the bean classes.
-	 * <p>
-	 * There are two category of classes that can be passed in through this method:
-	 * <ul class='spaced-list'>
-	 * 	<li>Subclasses of {@link BeanFilterBuilder}.
-	 * 		These must have a public no-arg constructor.
-	 * 	<li>Bean interface classes.
-	 * 		A shortcut for defining a {@link InterfaceBeanFilterBuilder}.
-	 * 		Any subclasses of an interface class will only have properties defined on the interface.
-	 * 		All other bean properties will be ignored.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanFilters</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public CoreApi setBeanFilters(Class<?>...values) throws LockedException {
-		return setProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Bean filters to apply to beans.
-	 * <p>
-	 * Same as {@link #setBeanFilters(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 */
-	public CoreApi setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		return setProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to bean filters.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_beanFilters</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_beanFilters_add</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public CoreApi addBeanFilters(Class<?>...values) throws LockedException {
-		return addToProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to bean filters.
-	 * <p>
-	 * Same as {@link #addBeanFilters(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_add
-	 */
-	public CoreApi addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		return addToProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from bean filters.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_beanFilters</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_beanFilters_remove</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public CoreApi removeBeanFilters(Class<?>...values) throws LockedException {
-		return removeFromProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from bean filters.
-	 * <p>
-	 * Same as {@link #removeBeanFilters(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanFilters
-	 * @see BeanContext#BEAN_beanFilters_remove
-	 */
-	public CoreApi removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		return removeFromProperty(BEAN_beanFilters, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  POJO swaps to apply to Java objects.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.pojoSwaps.list"</js>
-	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
-	 * 	<li><b>Default:</b> empty list
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * There are two category of classes that can be passed in through this method:
-	 * <ul>
-	 * 	<li>Subclasses of {@link PojoSwap}.
-	 * 	<li>Surrogate classes.  A shortcut for defining a {@link SurrogateSwap}.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_pojoSwaps</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public CoreApi setPojoSwaps(Class<?>...values) throws LockedException {
-		return setProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  POJO swaps to apply to Java objects.
-	 * <p>
-	 * Same as {@link #setPojoSwaps(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 */
-	public CoreApi setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		return setProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to POJO swaps.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_pojoSwaps</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_pojoSwaps_add</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
-	 */
-	public CoreApi addPojoSwaps(Class<?>...values) throws LockedException {
-		return addToProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to POJO swaps.
-	 * <p>
-	 * Same as {@link #addPojoSwaps(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_add
-	 */
-	public CoreApi addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		return addToProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from POJO swaps.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_pojoSwaps</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_pojoSwaps_remove</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
-	 */
-	public CoreApi removePojoSwaps(Class<?>...values) throws LockedException {
-		return removeFromProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from POJO swaps.
-	 * <p>
-	 * Same as {@link #removePojoSwaps(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_pojoSwaps
-	 * @see BeanContext#BEAN_pojoSwaps_remove
-	 */
-	public CoreApi removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		return removeFromProperty(BEAN_pojoSwaps, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Implementation classes for interfaces and abstract classes.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.implClasses.map"</js>
-	 * 	<li><b>Data type:</b> <code>Map&lt;Class,Class&gt;</code>
-	 * 	<li><b>Default:</b> empty map
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * For interfaces and abstract classes this method can be used to specify an implementation
-	 * 	class for the interface/abstract class so that instances of the implementation
-	 * 	class are used when instantiated (e.g. during a parse).
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_implClasses</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 */
-	public CoreApi setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		return setProperty(BEAN_implClasses, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Implementation classes for interfaces and abstract classes.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>putToProperty(<jsf>BEAN_implClasses</jsf>, interfaceClass, implClass)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_implClasses_put</jsf>, interfaceClass, implClass)</code>.
-	 * </ul>
-	 *
-	 * @param interfaceClass The interface class.
-	 * @param implClass The implementation class.
-	 * @param <T> The class type of the interface.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_implClasses
-	 * @see BeanContext#BEAN_implClasses_put
-	 */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		return putToProperty(BEAN_implClasses, interfaceClass, implClass);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Bean lookup dictionary.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanDictionary.list"</js>
-	 * 	<li><b>Data type:</b> <code>List&lt;Class&gt;</code>
-	 * 	<li><b>Default:</b> empty list
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * This list can consist of the following class types:
-	 * <ul>
-	 * 	<li>Any bean class that specifies a value for {@link Bean#typeName() @Bean.typeName()}.
-	 * 	<li>Any subclass of {@link BeanDictionaryList} containing a collection of bean classes with type name annotations.
-	 * 	<li>Any subclass of {@link BeanDictionaryMap} containing a mapping of type names to classes without type name annotations.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanDictionary</jsf>, values)</code>.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 */
-	public CoreApi setBeanDictionary(Class<?>...values) throws LockedException {
-		return setProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Bean lookup dictionary.
-	 * <p>
-	 * Same as {@link #setBeanDictionary(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 */
-	public CoreApi setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		return setProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to bean dictionary.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>addToProperty(<jsf>BEAN_beanDictionary</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_beanDictionary_add</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public CoreApi addToBeanDictionary(Class<?>...values) throws LockedException {
-		return addToProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add to bean dictionary.
-	 * <p>
-	 * Same as {@link #addToBeanDictionary(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to add to this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_add
-	 */
-	public CoreApi addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		return addToProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from bean dictionary.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>removeFromProperty(<jsf>BEAN_beanDictionary</jsf>, values)</code>
-	 * 		or <code>setProperty(<jsf>BEAN_beanDictionary_remove</jsf>, c)</code>.
-	 * </ul>
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public CoreApi removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		return removeFromProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Remove from bean dictionary.
-	 * <p>
-	 * Same as {@link #removeFromBeanDictionary(Class...)} but using a <code>Collection</code>.
-	 *
-	 * @param values The values to remove from this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanDictionary
-	 * @see BeanContext#BEAN_beanDictionary_remove
-	 */
-	public CoreApi removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		return removeFromProperty(BEAN_beanDictionary, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Name to use for the bean type properties used to represent a bean type.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.beanTypePropertyName"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"_type"</js>
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_beanTypePropertyName</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_beanTypePropertyName
-	 */
-	public CoreApi setBeanTypePropertyName(String value) throws LockedException {
-		return setProperty(BEAN_beanTypePropertyName, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default parser to use when converting <code>Strings</code> to POJOs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.defaultParser"</js>
-	 * 	<li><b>Data type:</b> <code>Class</code>
-	 * 	<li><b>Default:</b> {@link JsonSerializer}
-	 * 	<li><b>Session-overridable:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * Used in the in the {@link BeanSession#convertToType(Object, Class)} method.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_defaultParser</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_defaultParser
-	 */
-	public CoreApi setDefaultParser(Class<?> value) throws LockedException {
-		return setProperty(BEAN_defaultParser, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Locale.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.locale"</js>
-	 * 	<li><b>Data type:</b> <code>Locale</code>
-	 * 	<li><b>Default:</b> <code>Locale.getDefault()</code>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_locale</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_locale
-	 */
-	public CoreApi setLocale(Locale value) throws LockedException {
-		return setProperty(BEAN_locale, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  TimeZone.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.timeZone"</js>
-	 * 	<li><b>Data type:</b> <code>TimeZone</code>
-	 * 	<li><b>Default:</b> <jk>null</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_timeZone</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_timeZone
-	 */
-	public CoreApi setTimeZone(TimeZone value) throws LockedException {
-		return setProperty(BEAN_timeZone, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Media type.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.mediaType"</js>
-	 * 	<li><b>Data type:</b> <code>MediaType</code>
-	 * 	<li><b>Default:</b> <jk>null</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specifies a default media type value for serializer and parser sessions.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_mediaType</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_mediaType
-	 */
-	public CoreApi setMediaType(MediaType value) throws LockedException {
-		return setProperty(BEAN_mediaType, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Debug mode.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"BeanContext.debug"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Enables the following additional information during serialization:
-	 * <ul class='spaced-list'>
-	 * 	<li>When bean getters throws exceptions, the exception includes the object stack information
-	 * 		in order to determine how that method was invoked.
-	 * 	<li>Enables {@link SerializerContext#SERIALIZER_detectRecursions}.
-	 * </ul>
-	 * <p>
-	 * Enables the following additional information during parsing:
-	 * <ul class='spaced-list'>
-	 * 	<li>When bean setters throws exceptions, the exception includes the object stack information
-	 * 		in order to determine how that method was invoked.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>BEAN_debug</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see BeanContext#BEAN_debug
-	 */
-	public CoreApi setDebug(boolean value) throws LockedException {
-		return setProperty(BEAN_debug, value);
-	}
-
-	/**
-	 * Sets the classloader used for created classes from class strings.
-	 *
-	 * @param classLoader The new classloader.
-	 * @throws LockedException If {@link ContextFactory#lock()} was called on this class or the bean context.
-	 * @return This object (for method chaining).
-	 * @see ContextFactory#setClassLoader(ClassLoader)
-	 */
-	public CoreApi setClassLoader(ClassLoader classLoader) throws LockedException {
-		checkLock();
-		contextFactory.setClassLoader(classLoader);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Lockable */
-	protected void checkLock() {
-		super.checkLock();
-		beanContext = null;
-	}
-
-	@Override /* Lockable */
-	public CoreApi lock() {
-		try {
-			super.lock();
-			contextFactory = contextFactory.clone();
-			contextFactory.lock();
-			beanContext = contextFactory.getContext(BeanContext.class);
-			return this;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e);
-		}
-	}
-
-	@Override /* Lockable */
-	public CoreApi clone() throws CloneNotSupportedException {
-		CoreApi c = (CoreApi)super.clone();
-		c.contextFactory = ContextFactory.create(contextFactory);
-		c.beanContext = null;
-		return c;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/CoreObject.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/CoreObject.java b/juneau-core/src/main/java/org/apache/juneau/CoreObject.java
new file mode 100644
index 0000000..774c894
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/CoreObject.java
@@ -0,0 +1,114 @@
+// ***************************************************************************************************************************
+// * 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;
+
+/**
+ * Common super class for all serializers, parsers, and serializer/parser groups.
+ */
+public abstract class CoreObject {
+
+	private final BeanContext beanContext;
+
+	/** A snapshot of all the modifiable settings for this object + override properties. */
+	protected final PropertyStore propertyStore;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	protected CoreObject(PropertyStore propertyStore) {
+		this.propertyStore = propertyStore.create(getOverrideProperties());
+		this.beanContext = createContext(BeanContext.class);
+	}
+
+	/**
+	 * Creates a new builder class for this object so that a new object can be created
+	 * that expands upon the current object's settings.
+	 *
+	 * @return A new builder.
+	 */
+	public CoreObjectBuilder builder() {
+		throw new NoSuchMethodError();
+	}
+
+	/**
+	 * Method used by subclasses to override context factory properties for just this
+	 * instance without modifying the context factory itself.
+	 * <p>
+	 * Subclasses can call this parent method to append to override properties defined
+	 * higher in the parent chain.
+	 *
+	 * @return The override properties.  Never <jk>null</jk>.
+	 */
+	protected ObjectMap getOverrideProperties() {
+		return new ObjectMap();
+	}
+
+	/**
+	 * Returns a copy of the context factory passed in to the constructor with
+	 * any override properties applied from the {@link #getOverrideProperties()}.
+	 *
+	 * @return The context factory on this class.
+	 * Multiple calls to this method returns the same factory.
+	 */
+	public PropertyStore createPropertyStore() {
+		return PropertyStore.create(propertyStore);
+	}
+
+	/**
+	 * Creates a read-only context object of the specified type using the context
+	 * factory on this class.
+	 *
+	 * @param c The context class to create.
+	 * @return The new context object.
+	 */
+	protected <T extends Context> T createContext(Class<T> c) {
+		return propertyStore.getContext(c);
+	}
+
+	/**
+	 * Returns the bean context to use for this class.
+	 * @return The bean context object.
+	 */
+	public BeanContext getBeanContext() {
+		return beanContext;
+	}
+
+	/**
+	 * Returns the universal <code>Object</code> metadata object.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>getBeanContext().object();</code>.
+	 * </ul>
+	 *
+	 * @return The reusable {@link ClassMeta} for representing the {@link Object} class.
+	 */
+	public ClassMeta<Object> object() {
+		return getBeanContext().object();
+	}
+
+	/**
+	 * Returns the universal <code>String</code> metadata object.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>getBeanContext().string();</code>.
+	 * </ul>
+	 *
+	 * @return The reusable {@link ClassMeta} for representing the {@link String} class.
+	 */
+	public ClassMeta<String> string() {
+		return getBeanContext().string();
+	}
+}


[30/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
index d99f5ff..a13df15 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanMapsTest.java
@@ -19,7 +19,7 @@ import java.util.*;
 
 import javax.xml.datatype.*;
 
-import org.apache.juneau.BeanDictionaryMap;
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.json.annotation.*;
@@ -36,7 +36,7 @@ import org.junit.*;
 @SuppressWarnings({"unchecked","serial","javadoc"})
 public class RoundTripBeanMapsTest extends RoundTripTest {
 
-	public RoundTripBeanMapsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripBeanMapsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -219,14 +219,14 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	//====================================================================================================
 	@Test
 	public void testSubTypesUsingAnnotation() throws Exception {
-		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
+		JsonSerializer js = new JsonSerializerBuilder().simple().pojoSwaps(XMLGregorianCalendarSwap.class).build();
 
 		// Skip validation-only tests
 		if (isValidationOnly())
 			return;
 
-		Serializer s = getSerializer().clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
-		Parser p = getParser().clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
+		Serializer s = getSerializer().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+		Parser p = getParser().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
 
 		B1 b1 = B1.create();
 		Object r = s.serialize(b1);
@@ -292,14 +292,14 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	//====================================================================================================
 	@Test
 	public void testSubTypesUsingBeanFilter() throws Exception {
-		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
+		JsonSerializer js = new JsonSerializerBuilder().simple().pojoSwaps(XMLGregorianCalendarSwap.class).build();
 
 		// Skip validation-only tests
 		if (isValidationOnly())
 			return;
 
-		Serializer s = getSerializer().clone().addBeanFilters(CFilter.class).addPojoSwaps(XMLGregorianCalendarSwap.class);
-		Parser p = getParser().clone().addBeanFilters(CFilter.class).addPojoSwaps(XMLGregorianCalendarSwap.class);
+		Serializer s = getSerializer().builder().beanFilters(CFilter.class).pojoSwaps(XMLGregorianCalendarSwap.class).build();
+		Parser p = getParser().builder().beanFilters(CFilter.class).pojoSwaps(XMLGregorianCalendarSwap.class).build();
 
 		C1 c1 = C1.create();
 		Object r = s.serialize(c1);
@@ -357,7 +357,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	public static class CFilter extends BeanFilterBuilder {
 		public CFilter() {
 			super(C.class);
-			addToBeanDictionary(CFilterDictionaryMap.class);
+			beanDictionary(CFilterDictionaryMap.class);
 		}
 	}
 
@@ -420,8 +420,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 		if (isValidationOnly())
 			return;
 
-		Serializer s = getSerializer().clone().addBeanFilters(CAFilter.class);
-		Parser p = getParser().clone().addBeanFilters(CAFilter.class);
+		Serializer s = getSerializer().builder().beanFilters(CAFilter.class).build();
+		Parser p = getParser().builder().beanFilters(CAFilter.class).build();
 
 		CA1 c1 = CA1.create();
 		Object r = s.serialize(c1);
@@ -452,7 +452,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	public static class CAFilter extends BeanFilterBuilder {
 		public CAFilter() {
 			super(CA.class);
-			addToBeanDictionary(CAFilterDictionaryMap.class);
+			beanDictionary(CAFilterDictionaryMap.class);
 		}
 	}
 
@@ -498,14 +498,14 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	//====================================================================================================
 	@Test
 	public void testPropertiesUsingBeanFilter() throws Exception {
-		JsonSerializer js = JsonSerializer.DEFAULT_LAX.clone().addBeanFilters(D2Filter.class);
+		JsonSerializer js = new JsonSerializerBuilder().simple().beanFilters(D2Filter.class).build();
 
 		// Skip validation-only tests
 		if (isValidationOnly())
 			return;
 
-		Serializer s = getSerializer().clone().addBeanFilters(D2Filter.class);
-		Parser p = getParser().clone().addBeanFilters(D2Filter.class);
+		Serializer s = getSerializer().builder().beanFilters(D2Filter.class).build();
+		Parser p = getParser().builder().beanFilters(D2Filter.class).build();
 
 		D2 d = new D2().init();
 		Object r = s.serialize(d);
@@ -526,7 +526,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	public static class D2Filter extends BeanFilterBuilder {
 		public D2Filter() {
 			super(D2.class);
-			setProperties("f3,f2");
+			properties("f3,f2");
 		}
 	}
 
@@ -568,8 +568,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 		if (isValidationOnly())
 			return;
 
-		Serializer s = getSerializer().clone().addBeanFilters(E2Filter.class);
-		Parser p = getParser().clone().addBeanFilters(E2Filter.class);
+		Serializer s = getSerializer().builder().beanFilters(E2Filter.class).build();
+		Parser p = getParser().builder().beanFilters(E2Filter.class).build();
 
 		E2 e = new E2().init();
 		Object r = s.serialize(e);
@@ -589,7 +589,7 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	public static class E2Filter extends BeanFilterBuilder {
 		public E2Filter() {
 			super(E2.class);
-			setExcludeProperties("f2");
+			excludeProperties("f2");
 		}
 	}
 
@@ -630,8 +630,8 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 	//====================================================================================================
 	@Test
 	public void testInterfaceClassUsingBeanFilter() throws Exception {
-		Serializer s;
-		Parser p;
+		SerializerBuilder s = getSerializer().builder();
+		ParserBuilder p = getParser() == null ? null : getParser().builder();
 		FB2 t;
 		Object r;
 
@@ -640,30 +640,30 @@ public class RoundTripBeanMapsTest extends RoundTripTest {
 			return;
 
 		// --- BeanFilter defined on parent class ---
-		s = getSerializer().clone().addBeanFilters(FB1Filter.class);
-		p = getParser().clone().addBeanFilters(FB1Filter.class);
+		s.beanFilters(FB1Filter.class);
+		p.beanFilters(FB1Filter.class);
 
 		t = new FB2().init();
-		r = s.serialize(t);
-		t = p.parse(r, FB2.class);
+		r = s.build().serialize(t);
+		t = p.build().parse(r, FB2.class);
 		assertObjectEquals("{f1:'f1'}", t);
 
 		// --- BeanFilter defined on child class class ---
-		s = getSerializer().clone().addBeanFilters(FB2Filter.class);
-		p = getParser().clone().addBeanFilters(FB2Filter.class);
+		s.beanFilters(FB2Filter.class);
+		p.beanFilters(FB2Filter.class);
 
 		t = new FB2().init();
-		r = s.serialize(t);
-		t = p.parse(r, FB2.class);
+		r = s.build().serialize(t);
+		t = p.build().parse(r, FB2.class);
 		assertObjectEquals("{f1:'f1'}", t);
 
 		// --- BeanFilter defined as plain class ---
-		s = getSerializer().clone().addBeanFilters(FB1.class);
-		p = getParser().clone().addBeanFilters(FB1.class);
+		s.beanFilters(FB1.class);
+		p.beanFilters(FB1.class);
 
 		t = new FB2().init();
-		r = s.serialize(t);
-		t = p.parse(r, FB2.class);
+		r = s.build().serialize(t);
+		t = p.build().parse(r, FB2.class);
 		assertObjectEquals("{f1:'f1'}", t);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
index 654bbb4..4dcba43 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripClassesTest.java
@@ -28,7 +28,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripClassesTest extends RoundTripTest {
 
-	public RoundTripClassesTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripClassesTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
index 2c41ce2..d7b749c 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripDTOsTest.java
@@ -26,7 +26,7 @@ import org.junit.*;
 @SuppressWarnings({"javadoc"})
 public class RoundTripDTOsTest extends RoundTripTest {
 
-	public RoundTripDTOsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripDTOsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
index 972a786..ae98392 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripEnumTest.java
@@ -29,7 +29,7 @@ import org.junit.*;
 @SuppressWarnings({"serial","javadoc"})
 public class RoundTripEnumTest extends RoundTripTest {
 
-	public RoundTripEnumTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripEnumTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -46,7 +46,7 @@ public class RoundTripEnumTest extends RoundTripTest {
 
 	@Test
 	public void testEnumB() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple().addBeanFilters(getBeanFilters()).addPojoSwaps(getPojoSwaps());
+		WriterSerializer s = new JsonSerializerBuilder().simple().beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps()).build();
 		BEnum t = BEnum.FOO;
 		assertEquals("'xfoo'", s.serialize(t));
 		t = roundTrip(t, BEnum.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
index 9177596..924a6dd 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripGenericsTest.java
@@ -27,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripGenericsTest extends RoundTripTest {
 
-	public RoundTripGenericsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripGenericsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
index 7bbd8d9..4e41a60 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripLargeObjectsTest.java
@@ -22,6 +22,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
@@ -38,7 +39,7 @@ public class RoundTripLargeObjectsTest extends RoundTripTest {
 	private static final int NUM_RUNS = 10;
 	private static final int SIZE_PARAM = 20000;
 
-	public RoundTripLargeObjectsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripLargeObjectsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -48,55 +49,55 @@ public class RoundTripLargeObjectsTest extends RoundTripTest {
 			// Full round-trip testing
 			{ /* 0 */
 				"Json DEFAULT",
-				new JsonSerializer().setTrimNullProperties(false),
+				new JsonSerializerBuilder().trimNullProperties(false),
 				JsonParser.DEFAULT,
 				0
 			},
 			{ /* 1 */
 				"Json DEFAULT_LAX",
-				new JsonSerializer.Simple().setTrimNullProperties(false),
+				new JsonSerializerBuilder().simple().trimNullProperties(false),
 				JsonParser.DEFAULT,
 				0
 			},
 			{ /* 2 */
 				"Json DEFAULT_SQ",
-				new JsonSerializer.Simple().setTrimNullProperties(false),
+				new JsonSerializerBuilder().simple().trimNullProperties(false),
 				JsonParser.DEFAULT,
 				0
 			},
 			{ /* 3 */
 				"Xml DEFAULT w/namespaces,validation",
-				new XmlSerializer.NsSq().setTrimNullProperties(false).setAddNamespaceUrisToRoot(true).setUseWhitespace(true),
+				new XmlSerializerBuilder().sq().ns().trimNullProperties(false).addNamespaceUrisToRoot(true).useWhitespace(true),
 				XmlParser.DEFAULT,
 				CHECK_XML_WHITESPACE | VALIDATE_XML
 			},
 			{ /* 4 */
 				"Xml DEFAULT wo/namespaces,validation",
-				new XmlSerializer.Sq().setTrimNullProperties(false),
+				new XmlSerializerBuilder().sq().trimNullProperties(false),
 				XmlParser.DEFAULT,
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 5 */
 				"Html",
-				new HtmlSerializer().setTrimNullProperties(false),
+				new HtmlSerializerBuilder().trimNullProperties(false),
 				HtmlParser.DEFAULT,
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 6 */
 				"UrlEncoding",
-				new UrlEncodingSerializer().setTrimNullProperties(false),
+				new UrlEncodingSerializerBuilder().trimNullProperties(false),
 				UrlEncodingParser.DEFAULT,
 				0
 			},
 			{ /* 7 */
 				"Uon",
-				new UonSerializer().setTrimNullProperties(false),
+				new UonSerializerBuilder().trimNullProperties(false),
 				UonParser.DEFAULT,
 				0
 			},
 			{ /* 8 */
 				"MsgPack",
-				new MsgPackSerializer().setTrimNullProperties(false),
+				new MsgPackSerializerBuilder().trimNullProperties(false),
 				MsgPackParser.DEFAULT,
 				0
 			},

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
index f7d2d13..7a3ecca 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripMapsTest.java
@@ -21,6 +21,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transforms.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
@@ -32,7 +33,7 @@ import org.junit.*;
 @SuppressWarnings({"deprecation","javadoc"})
 public class RoundTripMapsTest extends RoundTripTest {
 
-	public RoundTripMapsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripMapsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -105,27 +106,27 @@ public class RoundTripMapsTest extends RoundTripTest {
 		t.put(new byte[]{4,5,6}, null);
 		t.put(null, "b");
 
-		s = new JsonSerializer.Simple().addPojoSwaps(getPojoSwaps()).setTrimNullProperties(false);
+		s = new JsonSerializerBuilder().simple().pojoSwaps(getPojoSwaps()).trimNullProperties(false).build();
 		e = "{AQID:'a',BAUG:null,null:'b'}";
 		r = s.serialize(t);
 		assertEquals(e, r);
 
-		s = new XmlSerializer.NsSq().addPojoSwaps(getPojoSwaps()).setTrimNullProperties(false);
+		s = new XmlSerializerBuilder().ns().sq().pojoSwaps(getPojoSwaps()).trimNullProperties(false).build();
 		e = "<object><AQID>a</AQID><BAUG _type='null'/><_x0000_>b</_x0000_></object>";
 		r = s.serialize(t);
 		assertEquals(e, r);
 
-		s = new HtmlSerializer.Sq().addPojoSwaps(getPojoSwaps()).setTrimNullProperties(false).setAddKeyValueTableHeaders(true);
+		s = new HtmlSerializerBuilder().sq().pojoSwaps(getPojoSwaps()).trimNullProperties(false).addKeyValueTableHeaders(true).build();
 		e = "<table><tr><th>key</th><th>value</th></tr><tr><td>AQID</td><td>a</td></tr><tr><td>BAUG</td><td><null/></td></tr><tr><td><null/></td><td>b</td></tr></table>";
 		r = s.serialize(t);
 		assertEquals(e, r);
 
-		s = new UonSerializer.Encoding().addPojoSwaps(getPojoSwaps()).setTrimNullProperties(false);
+		s = new UonSerializerBuilder().encoding().pojoSwaps(getPojoSwaps()).trimNullProperties(false).build();
 		e = "(AQID=a,BAUG=null,null=b)";
 		r = s.serialize(t);
 		assertEquals(e, r);
 
-		s = new UrlEncodingSerializer().addPojoSwaps(getPojoSwaps()).setTrimNullProperties(false);
+		s = new UrlEncodingSerializerBuilder().pojoSwaps(getPojoSwaps()).trimNullProperties(false).build();
 		e = "AQID=a&BAUG=null&null=b";
 		r = s.serialize(t);
 		assertEquals(e, r);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
index e398451..8177638 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripNumericConstructorsTest.java
@@ -15,6 +15,7 @@ package org.apache.juneau.a.rttests;
 import static org.junit.Assert.*;
 
 import java.util.*;
+
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 import org.junit.*;
@@ -26,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings({"javadoc","deprecation"})
 public class RoundTripNumericConstructorsTest extends RoundTripTest {
 
-	public RoundTripNumericConstructorsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripNumericConstructorsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
index 80d0bde..3b1aefa 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsAsStringsTest.java
@@ -27,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings({"unused","javadoc"})
 public class RoundTripObjectsAsStringsTest extends RoundTripTest {
 
-	public RoundTripObjectsAsStringsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripObjectsAsStringsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
index d40ebf3..a3fc073 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripObjectsWithSpecialMethodsTest.java
@@ -29,7 +29,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripObjectsWithSpecialMethodsTest extends RoundTripTest {
 
-	public RoundTripObjectsWithSpecialMethodsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripObjectsWithSpecialMethodsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
index a8eefcb..fb3f952 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitiveObjectBeansTest.java
@@ -27,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripPrimitiveObjectBeansTest extends RoundTripTest {
 
-	public RoundTripPrimitiveObjectBeansTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripPrimitiveObjectBeansTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
index 49b18f8..54e0374 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripPrimitivesBeansTest.java
@@ -27,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings({"serial","javadoc"})
 public class RoundTripPrimitivesBeansTest extends RoundTripTest {
 
-	public RoundTripPrimitivesBeansTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripPrimitivesBeansTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripReadOnlyBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripReadOnlyBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripReadOnlyBeansTest.java
index 1f8f8cf..ce4e5c4 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripReadOnlyBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripReadOnlyBeansTest.java
@@ -26,7 +26,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripReadOnlyBeansTest extends RoundTripTest {
 
-	public RoundTripReadOnlyBeansTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripReadOnlyBeansTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripSimpleObjectsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripSimpleObjectsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripSimpleObjectsTest.java
index 33cbe28..d3339a8 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripSimpleObjectsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripSimpleObjectsTest.java
@@ -28,7 +28,7 @@ import org.junit.*;
 @SuppressWarnings({"unchecked","rawtypes","javadoc"})
 public class RoundTripSimpleObjectsTest extends RoundTripTest {
 
-	public RoundTripSimpleObjectsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripSimpleObjectsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
index 25c8222..f5ed6be 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTest.java
@@ -14,7 +14,7 @@ package org.apache.juneau.a.rttests;
 
 import static org.apache.juneau.a.rttests.RoundTripTest.Flags.*;
 
-import java.lang.reflect.Type;
+import java.lang.reflect.*;
 import java.util.*;
 import java.util.Map.*;
 
@@ -25,6 +25,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 import org.junit.runner.*;
@@ -48,136 +49,136 @@ public abstract class RoundTripTest {
 			// Full round-trip testing
 			{ /* 0 */
 				"Json - default",
-				new JsonSerializer().setTrimNullProperties(false),
-				JsonParser.DEFAULT,
+				new JsonSerializerBuilder().trimNullProperties(false),
+				new JsonParserBuilder(),
 				0
 			},
 			{ /* 1 */
 				"Json - lax",
-				new JsonSerializer.Simple().setTrimNullProperties(false),
-				JsonParser.DEFAULT,
+				new JsonSerializerBuilder().simple().trimNullProperties(false),
+				new JsonParserBuilder(),
 				0
 			},
 			{ /* 2 */
 				"Json - lax, readable",
-				new JsonSerializer.SimpleReadable().setTrimNullProperties(false),
-				JsonParser.DEFAULT,
+				new JsonSerializerBuilder().simple().ws().trimNullProperties(false),
+				new JsonParserBuilder(),
 				0
 			},
 			{ /* 3 */
 				"Xml - namespaces, validation, readable",
-				new XmlSerializer.NsSq().setTrimNullProperties(false).setAddNamespaceUrisToRoot(true).setUseWhitespace(true),
-				XmlParser.DEFAULT,
+				new XmlSerializerBuilder().ns().sq().trimNullProperties(false).addNamespaceUrisToRoot(true).useWhitespace(true),
+				new XmlParserBuilder(),
 				CHECK_XML_WHITESPACE | VALIDATE_XML
 			},
 			{ /* 4 */
 				"Xml - no namespaces, validation",
-				new XmlSerializer.Sq().setTrimNullProperties(false),
-				XmlParser.DEFAULT,
+				new XmlSerializerBuilder().sq().trimNullProperties(false),
+				new XmlParserBuilder(),
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 5 */
 				"Html - default",
-				new HtmlSerializer().setTrimNullProperties(false),
-				HtmlParser.DEFAULT,
+				new HtmlSerializerBuilder().trimNullProperties(false),
+				new HtmlParserBuilder(),
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 6 */
 				"Html - readable",
-				new HtmlSerializer.SqReadable().setTrimNullProperties(false),
-				HtmlParser.DEFAULT,
+				new HtmlSerializerBuilder().sq().ws().trimNullProperties(false),
+				new HtmlParserBuilder(),
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 7 */
 				"Html - with key/value headers",
-				new HtmlSerializer().setAddKeyValueTableHeaders(true),
-				HtmlParser.DEFAULT,
+				new HtmlSerializerBuilder().addKeyValueTableHeaders(true),
+				new HtmlParserBuilder(),
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 8 */
 				"Uon - default",
-				new UonSerializer().setTrimNullProperties(false),
-				UonParser.DEFAULT,
+				new UonSerializerBuilder().trimNullProperties(false),
+				new UonParserBuilder(),
 				0
 			},
 			{ /* 9 */
 				"Uon - readable",
-				new UonSerializer.Readable().setTrimNullProperties(false),
-				UonParser.DEFAULT,
+				new UonSerializerBuilder().ws().trimNullProperties(false),
+				new UonParserBuilder(),
 				0
 			},
 			{ /* 10 */
 				"Uon - encoded",
-				new UonSerializer.Encoding().setTrimNullProperties(false),
-				UonParser.DEFAULT_DECODING,
+				new UonSerializerBuilder().encoding().trimNullProperties(false),
+				new UonParserBuilder().decoding(),
 				0
 			},
 			{ /* 11 */
 				"UrlEncoding - default",
-				new UrlEncodingSerializer().setTrimNullProperties(false),
-				UrlEncodingParser.DEFAULT,
+				new UrlEncodingSerializerBuilder().trimNullProperties(false),
+				new UrlEncodingParserBuilder(),
 				0
 			},
 			{ /* 12 */
 				"UrlEncoding - readable",
-				new UrlEncodingSerializer.Readable().setTrimNullProperties(false),
-				UrlEncodingParser.DEFAULT,
+				new UrlEncodingSerializerBuilder().ws().trimNullProperties(false),
+				new UrlEncodingParserBuilder(),
 				0
 			},
 			{ /* 13 */
 				"UrlEncoding - expanded params",
-				new UrlEncodingSerializer().setExpandedParams(true),
-				new UrlEncodingParser().setExpandedParams(true),
+				new UrlEncodingSerializerBuilder().expandedParams(true),
+				new UrlEncodingParserBuilder().expandedParams(true),
 				0
 			},
 			{ /* 14 */
 				"Rdf.Xml",
-				new RdfSerializer.Xml().setTrimNullProperties(false).setAddLiteralTypes(true),
-				RdfParser.DEFAULT_XML,
+				new RdfSerializerBuilder().trimNullProperties(false).addLiteralTypes(true),
+				new RdfParserBuilder().xml(),
 				0
 			},
 			{ /* 15 */
 				"Rdf.XmlAbbrev",
-				new RdfSerializer.XmlAbbrev().setTrimNullProperties(false).setAddLiteralTypes(true),
-				RdfParser.DEFAULT_XML,
+				new RdfSerializerBuilder().xmlabbrev().trimNullProperties(false).addLiteralTypes(true),
+				new RdfParserBuilder().xml(),
 				0
 			},
 			{ /* 16 */
 				"Rdf.Turtle",
-				new RdfSerializer.Turtle().setTrimNullProperties(false).setAddLiteralTypes(true),
-				RdfParser.DEFAULT_TURTLE,
+				new RdfSerializerBuilder().turtle().trimNullProperties(false).addLiteralTypes(true),
+				new RdfParserBuilder().turtle(),
 				0
 			},
 			{ /* 17 */
 				"Rdf.NTriple",
-				new RdfSerializer.NTriple().setTrimNullProperties(false).setAddLiteralTypes(true),
-				RdfParser.DEFAULT_NTRIPLE,
+				new RdfSerializerBuilder().ntriple().trimNullProperties(false).addLiteralTypes(true),
+				new RdfParserBuilder().ntriple(),
 				0
 			},
 			{ /* 18 */
 				"Rdf.N3",
-				new RdfSerializer.N3().setTrimNullProperties(false).setAddLiteralTypes(true),
-				RdfParser.DEFAULT_N3,
+				new RdfSerializerBuilder().n3().trimNullProperties(false).addLiteralTypes(true),
+				new RdfParserBuilder().n3(),
 				0
 			},
 			{ /* 19 */
 				"MsgPack",
-				new MsgPackSerializer().setTrimNullProperties(false),
-				MsgPackParser.DEFAULT,
+				new MsgPackSerializerBuilder().trimNullProperties(false),
+				new MsgPackParserBuilder(),
 				0
 			},
 
 			// Validation testing only
 			{ /* 20 */
 				"Json schema",
-				new JsonSchemaSerializer().setTrimNullProperties(false),
+				new JsonSchemaSerializerBuilder().trimNullProperties(false),
 				null,
 				RETURN_ORIGINAL_OBJECT
 			},
 			{ /* 21 */
 				"Xml schema",
-				new XmlSchemaSerializer().setTrimNullProperties(false),
-				new XmlValidatorParser(),
+				new XmlSchemaSerializerBuilder().trimNullProperties(false),
+				new XmlValidatorParserBuilder(),
 				RETURN_ORIGINAL_OBJECT | CHECK_XML_WHITESPACE
 			},
 		});
@@ -191,19 +192,19 @@ public abstract class RoundTripTest {
 	protected String label;
 	public boolean debug = false;
 
-	public RoundTripTest(String label, Serializer s, Parser p, int flags) throws Exception {
-		this.s = s.clone().addBeanFilters(getBeanFilters()).addPojoSwaps(getPojoSwaps()).addToBeanDictionary(getDictionary()).setProperties(getProperties());
-		this.p = p == null ? null : p.clone().addBeanFilters(getBeanFilters()).addPojoSwaps(getPojoSwaps()).addToBeanDictionary(getDictionary()).setProperties(getProperties());
+	public RoundTripTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		this.label = label;
 
 		Map<Class<Object>, Class<? extends Object>> m = getImplClasses();
 		if (m != null) {
 			for (Entry<Class<Object>, Class<? extends Object>> e : m.entrySet()) {
-				this.s.addImplClass(e.getKey(), e.getValue());
-				if (this.p != null)
-					this.p.addImplClass(e.getKey(), e.getValue());
+				s.implClass(e.getKey(), e.getValue());
+				if (p != null)
+					p.implClass(e.getKey(), e.getValue());
 			}
 		}
+		this.s = s.beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps()).beanDictionary(getDictionary()).properties(getProperties()).build();
+		this.p = p == null ? null : p.beanFilters(getBeanFilters()).pojoSwaps(getPojoSwaps()).beanDictionary(getDictionary()).properties(getProperties()).build();
 		this.validateXmlWhitespace = (flags & CHECK_XML_WHITESPACE) > 0;
 		this.validateXml = (flags & VALIDATE_XML) > 0;
 		this.returnOriginalObject = (flags & RETURN_ORIGINAL_OBJECT) > 0;
@@ -258,22 +259,22 @@ public abstract class RoundTripTest {
 		return p;
 	}
 
-	protected void addBeanFilters(Class<?>...c) {
-		s.addBeanFilters(c);
+	protected void beanFilters(Class<?>...c) {
+		s = s.builder().beanFilters(c).build();
 		if (p != null)
-			p.addBeanFilters(c);
+			p = p.builder().beanFilters(c).build();
 	}
 
-	protected void addPojoSwaps(Class<?>...c) {
-		s.addPojoSwaps(c);
+	protected void pojoSwaps(Class<?>...c) {
+		s = s.builder().pojoSwaps(c).build();
 		if (p != null)
-			p.addPojoSwaps(c);
+			p = p.builder().pojoSwaps(c).build();
 	}
 
-	protected void addToBeanDictionary(Class<?>...c) {
-		s.addToBeanDictionary(c);
+	protected void beanDictionary(Class<?>...c) {
+		s = s.builder().beanDictionary(c).build();
 		if (p != null)
-			p.addToBeanDictionary(c);
+			p = p.builder().beanDictionary(c).build();
 	}
 
 	public boolean isValidationOnly() {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
index a3aa3b6..a5cf645 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripToObjectMapsTest.java
@@ -28,7 +28,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripToObjectMapsTest extends RoundTripTest {
 
-	public RoundTripToObjectMapsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripToObjectMapsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
index cc6c1b9..a3af81d 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTransformBeansTest.java
@@ -21,7 +21,6 @@ import javax.xml.datatype.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.annotation.Pojo;
 import org.apache.juneau.json.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
@@ -36,7 +35,7 @@ import org.junit.*;
 @SuppressWarnings({"unchecked","rawtypes","serial","javadoc"})
 public class RoundTripTransformBeansTest extends RoundTripTest {
 
-	public RoundTripTransformBeansTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripTransformBeansTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -50,9 +49,7 @@ public class RoundTripTransformBeansTest extends RoundTripTest {
 			CalendarSwap.ISO8601DTZ.class,
 			DateSwap.ISO8601DTZ.class
 		};
-		s.addPojoSwaps(f);
-		if (p != null)
-			p.addPojoSwaps(f);
+		pojoSwaps(f);
 		A t = new A().init();
 		t = roundTrip(t, A.class);
 
@@ -170,9 +167,7 @@ public class RoundTripTransformBeansTest extends RoundTripTest {
 			CalendarSwap.DateMedium.class,
 			DateSwap.RFC2822DT.class,
 		};
-		s.addPojoSwaps(f);
-		if (p != null)
-			p.addPojoSwaps(f);
+		pojoSwaps(f);
 		A t = new A().init();
 		t = roundTrip(t, A.class);
 
@@ -258,8 +253,8 @@ public class RoundTripTransformBeansTest extends RoundTripTest {
 		GregorianCalendar gc = new GregorianCalendar();
 		XMLGregorianCalendar c = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
 
-		Serializer s = getSerializer().clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
-		Parser p = getParser().clone().addPojoSwaps(XMLGregorianCalendarSwap.class);
+		Serializer s = getSerializer().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
+		Parser p = getParser().builder().pojoSwaps(XMLGregorianCalendarSwap.class).build();
 
 		Object r = s.serialize(c);
 		XMLGregorianCalendar c2 = p.parse(r, XMLGregorianCalendar.class);
@@ -333,10 +328,10 @@ public class RoundTripTransformBeansTest extends RoundTripTest {
 	//====================================================================================================
 	@Test
 	public void testSurrogates() throws Exception {
-		addPojoSwaps(D2.class);
+		pojoSwaps(D2.class);
 
-		JsonSerializer s = new JsonSerializer.Simple().addPojoSwaps(D2.class);
-		JsonParser p = new JsonParser().addPojoSwaps(D2.class);
+		JsonSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(D2.class).build();
+		JsonParser p = new JsonParserBuilder().pojoSwaps(D2.class).build();
 		Object r;
 		D1 d1 = D1.create();
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTrimStringsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTrimStringsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTrimStringsTest.java
index 37c1d10..dfac4fe 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTrimStringsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripTrimStringsTest.java
@@ -25,7 +25,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripTrimStringsTest extends RoundTripTest {
 
-	public RoundTripTrimStringsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripTrimStringsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 
@@ -40,8 +40,8 @@ public class RoundTripTrimStringsTest extends RoundTripTest {
 		Parser p = getParser();
 		Object in, a, e;
 
-		Serializer s2 = s.clone().setTrimStrings(true);
-		Parser p2 = p.clone().setTrimStrings(true);
+		Serializer s2 = s.builder().trimStrings(true).build();
+		Parser p2 = p.builder().trimStrings(true).build();
 
 		in = " foo bar ";
 		e = "foo bar";

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/csv/CsvTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/csv/CsvTest.java b/juneau-core-test/src/test/java/org/apache/juneau/csv/CsvTest.java
index 1ca1fbd..84f9abf 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/csv/CsvTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/csv/CsvTest.java
@@ -31,7 +31,7 @@ public class CsvTest {
 		l.add(new A("b1",1));
 		l.add(new A("b2",2));
 
-		WriterSerializer s = new CsvSerializer();
+		WriterSerializer s = CsvSerializer.DEFAULT;
 		String r;
 
 		r = s.serialize(l);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/dto/atom/AtomTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/atom/AtomTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/atom/AtomTest.java
index 362aa8a..fdc8206 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/atom/AtomTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/atom/AtomTest.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.dto.atom;
 
 import static org.apache.juneau.TestUtils.*;
-import static org.junit.Assert.*;
 import static org.apache.juneau.dto.atom.AtomBuilder.*;
+import static org.junit.Assert.*;
 
 import java.net.*;
 
@@ -98,7 +98,7 @@ public class AtomTest {
 			+"	<updated>2016-12-31T01:02:03-04:00</updated>\n"
 			+"</feed>\n";
 
-		s = new XmlSerializer.SqReadable().setEnableNamespaces(false).setSortProperties(true);
+		s = new XmlSerializerBuilder().sq().ws().enableNamespaces(false).sortProperties(true).build();
 		r = s.serialize(f);
 		assertEquals(expected, r);
 		f2 = p.parse(r, Feed.class);
@@ -144,7 +144,7 @@ public class AtomTest {
 			+"	<atom:updated>2016-12-31T01:02:03-04:00</atom:updated>\n"
 			+"</atom:feed>\n";
 
-		s = new XmlSerializer.SqReadable().setEnableNamespaces(true).setAddNamespaceUrisToRoot(true).setSortProperties(true);
+		s = new XmlSerializerBuilder().sq().ws().enableNamespaces(true).addNamespaceUrisToRoot(true).sortProperties(true).build();
 		r = s.serialize(f);
 		assertEquals(expected, r);
 		f2 = p.parse(r, Feed.class);
@@ -190,7 +190,7 @@ public class AtomTest {
 			+"	<updated>2016-12-31T01:02:03-04:00</updated>\n"
 			+"</feed>\n";
 
-		s = new XmlSerializer.SqReadable().setDefaultNamespace("atom").setEnableNamespaces(true).setAddNamespaceUrisToRoot(true).setSortProperties(true);
+		s = new XmlSerializerBuilder().sq().ws().defaultNamespace("atom").enableNamespaces(true).addNamespaceUrisToRoot(true).sortProperties(true).build();
 		r = s.serialize(f);
 		assertEquals(expected, r);
 		f2 = p.parse(r, Feed.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/dto/cognos/CognosXmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/cognos/CognosXmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/cognos/CognosXmlTest.java
index 358d8e3..0f0bdd4 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/cognos/CognosXmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/cognos/CognosXmlTest.java
@@ -72,12 +72,13 @@ public class CognosXmlTest {
 			new Column("productLineCode", "xs:int")
 		};
 
-		XmlSerializer s = new XmlSerializer()
-			.setUseWhitespace(true)
-			.setQuoteChar('\'')
-			.setDefaultNamespace("cognos")
-			.setEnableNamespaces(true)
-			.setAddNamespaceUrisToRoot(true);
+		XmlSerializer s = new XmlSerializerBuilder()
+			.ws()
+			.sq()
+			.defaultNamespace("cognos")
+			.ns()
+			.addNamespaceUrisToRoot(true)
+			.build();
 
 		DataSet ds = new DataSet(c, rows, BeanContext.DEFAULT.createSession());
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
index 15d45d2..de68b7a 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5ComboTest.java
@@ -16,7 +16,7 @@ import static org.apache.juneau.dto.html5.HtmlBuilder.*;
 
 import java.util.*;
 
-import org.apache.juneau.ComboTest;
+import org.apache.juneau.*;
 import org.junit.runner.*;
 import org.junit.runners.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5TemplateComboTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5TemplateComboTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5TemplateComboTest.java
index cf9ad84..3d43c1e 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5TemplateComboTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/html5/Html5TemplateComboTest.java
@@ -16,9 +16,8 @@ import static org.apache.juneau.dto.html5.HtmlBuilder.*;
 
 import java.util.*;
 
-import org.apache.juneau.BeanSession;
-import org.apache.juneau.ComboTest;
-import org.apache.juneau.annotation.Bean;
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
 import org.junit.runner.*;
 import org.junit.runners.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/dto/jsonschema/JsonSchemaTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/dto/jsonschema/JsonSchemaTest.java b/juneau-core-test/src/test/java/org/apache/juneau/dto/jsonschema/JsonSchemaTest.java
index 9f2d1a8..1700106 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/dto/jsonschema/JsonSchemaTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/dto/jsonschema/JsonSchemaTest.java
@@ -24,7 +24,7 @@ public class JsonSchemaTest {
 
 	@Test
 	public void testSchema1() throws Exception {
-		JsonSerializer s = JsonSerializer.DEFAULT_LAX_READABLE.clone().setAddBeanTypeProperties(false);
+		JsonSerializer s = new JsonSerializerBuilder().simple().ws().addBeanTypeProperties(false).build();
 		JsonParser p = JsonParser.DEFAULT;
 		String r;
 		Schema t, t2;
@@ -118,7 +118,7 @@ public class JsonSchemaTest {
 
 	@Test
 	public void testSchema2() throws Exception {
-		JsonSerializer s = JsonSerializer.DEFAULT_LAX_READABLE.clone().setAddBeanTypeProperties(false);
+		JsonSerializer s = new JsonSerializerBuilder().simple().ws().addBeanTypeProperties(false).build();
 		JsonParser p = JsonParser.DEFAULT;
 		String r;
 		Schema t, t2;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
index 12a6707..e6fec70 100644
--- a/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/html/BasicHtmlTest.java
@@ -17,9 +17,8 @@ import static org.junit.Assert.*;
 import java.util.*;
 
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.html.annotation.Html;
-import org.apache.juneau.xml.annotation.Xml;
-import org.apache.juneau.xml.annotation.XmlFormat;
+import org.apache.juneau.html.annotation.*;
+import org.apache.juneau.xml.annotation.*;
 import org.junit.*;
 import org.junit.runner.*;
 import org.junit.runners.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
index b03bd57..90f5c5c 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonParserTest.java
@@ -29,7 +29,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testFromSerializer() throws Exception {
-		ReaderParser p = HtmlParser.DEFAULT.clone().addToBeanDictionary(A1.class);
+		ReaderParser p = new HtmlParserBuilder().beanDictionary(A1.class).build();
 		Map m = null;
 		String in;
 
@@ -63,7 +63,7 @@ public class CommonParserTest {
 		t2.add(new A3("name0","value0"));
 		t2.add(new A3("name1","value1"));
 		t1.list = t2;
-		in = new HtmlSerializer().setAddBeanTypeProperties(true).serialize(t1);
+		in = new HtmlSerializerBuilder().addBeanTypeProperties(true).build().serialize(t1);
 		t1 = (A1)p.parse(in, Object.class);
 		assertEquals("value1", t1.list.get(1).value);
 
@@ -94,7 +94,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new HtmlParser().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new HtmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		B t;
 
 		String in = "<table _type='object'><tr><th><string>key</string></th><th><string>value</string></th></tr><tr><td><string>a</string></td><td><number>1</number></td></tr><tr><td><string>unknown</string></td><td><number>1</number></td></tr><tr><td><string>b</string></td><td><number>2</number></td></tr></table>";
@@ -103,7 +103,7 @@ public class CommonParserTest {
 		assertEquals(t.b, 2);
 
 		try {
-			p = new HtmlParser();
+			p = HtmlParser.DEFAULT;
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -143,7 +143,7 @@ public class CommonParserTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		HtmlParser p = new HtmlParser().setIgnoreUnknownBeanProperties(true);
+		HtmlParser p = new HtmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java
index d4e29a5..0f1e267 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/html/CommonTest.java
@@ -34,18 +34,18 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 		HtmlParser p = HtmlParser.DEFAULT;
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>s1</td><td><null/></td></tr><tr><td>s2</td><td>s2</td></tr></table>", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table>", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -66,19 +66,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 		HtmlParser p = HtmlParser.DEFAULT;
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><table><tr><th>key</th><th>value</th></tr></table></td></tr><tr><td>f2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>f2a</td><td><null/></td></tr><tr><td>f2b</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table></td></tr></table></td></tr></table>", r);
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>f2a</td><td><null/></td></tr><tr><td>f2b</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>s2</td><td>s2</td></tr></table></td></tr></table></td></tr></table>", r);
 		t2 = p.parse(r, B.class);
 		assertNull(t2.f1);
@@ -100,19 +100,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 		HtmlParser p = HtmlParser.DEFAULT;
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f1</td><td><ul></ul></td></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r);
 		t2 = p.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>f2</td><td><table _type='array'><tr><th>s2</th></tr><tr><null/></tr><tr><td>s2</td></tr></table></td></tr></table>", r);
 		t2 = p.parse(r, C.class);
 		assertNull(t2.f1);
@@ -134,13 +134,13 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 		HtmlParser p = HtmlParser.DEFAULT;
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals(
 			"<table>"
 				+"<tr><th>key</th><th>value</th></tr>"
@@ -163,8 +163,8 @@ public class CommonTest {
 		t2 = p.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals(
 			"<table>"
 				+"<tr><th>key</th><th>value</th></tr>"
@@ -200,7 +200,7 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testBeanPropertyProperties() throws Exception {
-		HtmlSerializer s = HtmlSerializer.DEFAULT_SQ.clone().setAddKeyValueTableHeaders(true);
+		HtmlSerializer s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true).build();
 		E1 t = new E1();
 		String r;
 
@@ -353,13 +353,13 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setUriAnchorText(PROPERTY_NAME).setUseWhitespace(false).setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().uriAnchorText(PROPERTY_NAME).useWhitespace(false).addKeyValueTableHeaders(true);
 		TestURI t = new TestURI();
 		String r;
 		String expected;
 
-		s.setRelativeUriBase(null);
-		r = strip(s.serialize(t));
+		s.relativeUriBase(null);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1</a>"
@@ -379,8 +379,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = strip(s.serialize(t));
+		s.relativeUriBase("");  // Same as null.
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1</a>"
@@ -400,8 +400,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = strip(s.serialize(t));
+		s.relativeUriBase("/cr");
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1</a>"
@@ -421,8 +421,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = strip(s.serialize(t));
+		s.relativeUriBase("/cr/");  // Same as above
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1</a>"
@@ -442,8 +442,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = strip(s.serialize(t));
+		s.relativeUriBase("/");
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/f0/x0'>f0</a>"
 			+"\n[f1]=<a href='/f1/x1'>f1</a>"
@@ -463,10 +463,10 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = strip(s.serialize(t));
+		s.absolutePathUriBase("http://foo");
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1</a>"
@@ -486,8 +486,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = strip(s.serialize(t));
+		s.absolutePathUriBase("http://foo/");
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1</a>"
@@ -507,8 +507,8 @@ public class CommonTest {
 		;
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = strip(s.serialize(t));
+		s.absolutePathUriBase("");  // Same as null.
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1</a>"
@@ -539,31 +539,11 @@ public class CommonTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		HtmlSerializer s = new HtmlSerializer().lock();
-		try {
-			s.setEnableNamespaces(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -574,7 +554,7 @@ public class CommonTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -582,9 +562,9 @@ public class CommonTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -594,12 +574,14 @@ public class CommonTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.html.CommonTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		assertEquals("<table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>foo</td></tr><tr><td>r2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>bar</td></tr><tr><td>r3</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>baz</td></tr></table></td></tr></table></td></tr></table>",
-			s.serialize(r1));
+		s.ignoreRecursions(true);
+		assertEquals(
+			"<table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>foo</td></tr><tr><td>r2</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>bar</td></tr><tr><td>r3</td><td><table><tr><th>key</th><th>value</th></tr><tr><td>name</td><td>baz</td></tr></table></td></tr></table></td></tr></table>",
+			s.build().serialize(r1)
+		);
 
 		// Make sure this doesn't blow up.
-		s.getSchemaSerializer().serialize(r1);
+		s.build().getSchemaSerializer().serialize(r1);
 	}
 
 	public static class R1 {
@@ -620,7 +602,7 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testBasicBean() throws Exception {
-		WriterSerializer s = new HtmlSerializer.Sq().setTrimNullProperties(false).setSortProperties(true).setAddKeyValueTableHeaders(true);
+		WriterSerializer s = new HtmlSerializerBuilder().sq().trimNullProperties(false).sortProperties(true).addKeyValueTableHeaders(true).build();
 
 		J a = new J();
 		a.setF1("J");

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/html/HtmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/html/HtmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/html/HtmlTest.java
index 2025430..5a48716 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/html/HtmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/html/HtmlTest.java
@@ -49,13 +49,13 @@ public class HtmlTest {
 	//====================================================================================================
 	@Test
 	public void testAnchorTextOptions() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializerBuilder s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true);
 		TestURI t = new TestURI();
 		String r;
 		String expected = null;
 
-		s.setUriAnchorText(TO_STRING);
-		r = strip(s.serialize(t));
+		s.uriAnchorText(TO_STRING);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='f0/x0'>f0/x0</a>"
 			+"\n[f1]=<a href='f1/x1'>f1/x1</a>"
@@ -74,10 +74,10 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL</a>";
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://myhost");
-		s.setRelativeUriBase("/cr");
-		s.setUriAnchorText(TO_STRING);
-		r = strip(s.serialize(t));
+		s.absolutePathUriBase("http://myhost");
+		s.relativeUriBase("/cr");
+		s.uriAnchorText(TO_STRING);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0/x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1/x1</a>"
@@ -96,8 +96,8 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL</a>";
 		assertEquals(expected, r);
 
-		s.setUriAnchorText(URI);
-		r = strip(s.serialize(t));
+		s.uriAnchorText(URI);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>/cr/f0/x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>/cr/f1/x1</a>"
@@ -116,8 +116,8 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL</a>";
 		assertEquals(expected, r);
 
-		s.setUriAnchorText(LAST_TOKEN);
-		r = strip(s.serialize(t));
+		s.uriAnchorText(LAST_TOKEN);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>x1</a>"
@@ -136,8 +136,8 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>xe</a>";
 		assertEquals(expected, r);
 
-		s.setUriAnchorText(URI_ANCHOR);
-		r = strip(s.serialize(t));
+		s.uriAnchorText(URI_ANCHOR);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0/x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1/x1</a>"
@@ -156,8 +156,8 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL</a>";
 		assertEquals(expected, r);
 
-		s.setLabelParameter("label2");
-		r = strip(s.serialize(t));
+		s.labelParameter("label2");
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0/x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1/x1</a>"
@@ -176,8 +176,8 @@ public class HtmlTest {
 			+"\n[fe]=<a href='http://www.apache.org/fe/xe?foo=bar&label2=MY_LABEL'>MY_LABEL</a>";
 		assertEquals(expected, r);
 
-		s.setDetectLinksInStrings(false);
-		r = strip(s.serialize(t));
+		s.detectLinksInStrings(false);
+		r = strip(s.build().serialize(t));
 		expected = ""
 			+"\n[f0]=<a href='/cr/f0/x0'>f0/x0</a>"
 			+"\n[f1]=<a href='/cr/f1/x1'>f1/x1</a>"
@@ -196,9 +196,9 @@ public class HtmlTest {
 			+"\n[fe]=http://www.apache.org/fe/xe?foo=bar&amp;label2=MY_LABEL";
 			assertEquals(expected, r);
 
-			s.setDetectLinksInStrings(true);
-			s.setLookForLabelParameters(false);
-			r = strip(s.serialize(t));
+			s.detectLinksInStrings(true);
+			s.lookForLabelParameters(false);
+			r = strip(s.build().serialize(t));
 			expected = ""
 				+"\n[f0]=<a href='/cr/f0/x0'>f0/x0</a>"
 				+"\n[f1]=<a href='/cr/f1/x1'>f1/x1</a>"
@@ -232,7 +232,7 @@ public class HtmlTest {
 	//====================================================================================================
 	@Test
 	public void testHtmlAnnotationAsPlainText() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializer s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true).build();
 		Object o = null;
 		String r;
 
@@ -264,7 +264,7 @@ public class HtmlTest {
 	//====================================================================================================
 	@Test
 	public void testHtmlAnnotationAsXml() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq().setAddKeyValueTableHeaders(true);
+		HtmlSerializer s = new HtmlSerializerBuilder().sq().addKeyValueTableHeaders(true).build();
 		Object o = null;
 		String r;
 
@@ -292,7 +292,7 @@ public class HtmlTest {
 	//====================================================================================================
 	@Test
 	public void testNoTableHeaders() throws Exception {
-		HtmlSerializer s = new HtmlSerializer.Sq();
+		HtmlSerializer s = HtmlSerializer.DEFAULT_SQ;
 		Object o = null;
 		String r;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigFileTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigFileTest.java b/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigFileTest.java
index 6ea5a29..8c423ef 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigFileTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/ini/ConfigFileTest.java
@@ -2046,7 +2046,7 @@ public class ConfigFileTest {
 		cf.put("d", "$B{$A{X}}");
 		cf.put("e", "$D{X}");
 
-		VarResolver vr = new VarResolver().addVars(ALVar.class, BLVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(ALVar.class, BLVar.class).build();
 
 		cf = cf.getResolving(vr);
 
@@ -2057,7 +2057,7 @@ public class ConfigFileTest {
 		assertEquals("$D{X}", cf.getString("e"));
 
 		// Create new resolver that addx $C and overrides $A
-		VarResolver vr2 = vr.clone().addVars(AUVar.class, DUVar.class);
+		VarResolver vr2 = vr.builder().vars(AUVar.class, DUVar.class).build();
 
 		// true == augment by adding existing as parent to the new resolver
 		cf = cf.getResolving(vr2);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
index 9dc89d2..8c77649 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/jena/CommonParserTest.java
@@ -18,7 +18,7 @@ import static org.junit.Assert.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.annotation.Bean;
+import org.apache.juneau.annotation.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
 import org.junit.*;
@@ -40,14 +40,14 @@ public class CommonParserTest {
 		return s.replaceFirst("<rdf:RDF[^>]+>\\s*", "").replaceAll("</rdf:RDF>$", "").trim().replaceAll("[\\r\\n]", "");
 	}
 
-	private RdfSerializer getBasicSerializer() {
-		return new RdfSerializer()
-			.setQuoteChar('\'')
-			.setAddLiteralTypes(true)
-			.setUseWhitespace(false)
-			.setProperty(RDF_rdfxml_allowBadUris, true)
-			.setProperty(RDF_rdfxml_showDoctypeDeclaration, false)
-			.setProperty(RDF_rdfxml_showXmlDeclaration, false);
+	private RdfSerializerBuilder getBasicSerializer() {
+		return new RdfSerializerBuilder()
+			.sq()
+			.addLiteralTypes(true)
+			.useWhitespace(false)
+			.property(RDF_rdfxml_allowBadUris, true)
+			.property(RDF_rdfxml_showDoctypeDeclaration, false)
+			.property(RDF_rdfxml_showXmlDeclaration, false);
 	}
 
 	//====================================================================================================
@@ -55,8 +55,8 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testFromSerializer() throws Exception {
-		WriterSerializer s = getBasicSerializer();
-		ReaderParser p = new RdfParser.Xml().setTrimWhitespace(true);
+		WriterSerializer s = getBasicSerializer().build();
+		ReaderParser p = new RdfParserBuilder().xml().trimWhitespace(true).build();
 		Map m = null;
 		String in;
 		Integer one = Integer.valueOf(1);
@@ -109,7 +109,7 @@ public class CommonParserTest {
 		t2.add(new A3("name1","value1"));
 		t1.list = t2;
 
-		s.setAddBeanTypeProperties(true);
+		s = getBasicSerializer().addBeanTypeProperties(true).build();
 		in = strip(s.serialize(t1));
 		assertEquals("<rdf:Description><jp:_type>A1</jp:_type><jp:list><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:name>name0</jp:name><jp:value>value0</jp:value></rdf:li><rdf:li rdf:parseType='Resource'><jp:name>name1</jp:name><jp:value>value1</jp:value></rdf:li></rdf:Seq></jp:list></rdf:Description>", in);
 		in = wrap(in);
@@ -139,7 +139,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new RdfParser.Xml().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new RdfParserBuilder().xml().ignoreUnknownBeanProperties(true).build();
 		B t;
 
 		String in = wrap("<rdf:Description><jp:a rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>1</jp:a><jp:unknownProperty>foo</jp:unknownProperty><jp:b rdf:datatype='http://www.w3.org/2001/XMLSchema#int'>2</jp:b></rdf:Description>");
@@ -148,7 +148,7 @@ public class CommonParserTest {
 		assertEquals(t.b, 2);
 
 		try {
-			p = new RdfParser.Xml();
+			p = new RdfParserBuilder().xml().build();
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -163,7 +163,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testCollectionPropertiesWithNoSetters() throws Exception {
-		RdfParser p = new RdfParser.Xml();
+		RdfParser p = new RdfParserBuilder().xml().build();
 		String in = wrap("<rdf:Description><jp:ints><rdf:Seq><rdf:li>1</rdf:li><rdf:li>2</rdf:li></rdf:Seq></jp:ints><jp:beans><rdf:Seq><rdf:li rdf:parseType='Resource'><jp:a>1</jp:a><jp:b>2</jp:b></rdf:li></rdf:Seq></jp:beans></rdf:Description>");
 		C t = p.parse(in, C.class);
 		assertEquals(t.getInts().size(), 2);
@@ -187,7 +187,7 @@ public class CommonParserTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		RdfParser p = new RdfParser.Xml().setIgnoreUnknownBeanProperties(true);
+		RdfParser p = new RdfParserBuilder().xml().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */


[09/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
deleted file mode 100644
index ec9dca9..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerContext.java
+++ /dev/null
@@ -1,99 +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.urlencoding;
-
-import org.apache.juneau.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * Configurable properties on the {@link UonSerializer} class.
- * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
- * <p>
- * See {@link ContextFactory} for more information about context properties.
- *
- * <h5 class='section'>Inherited configurable properties:</h5>
- * <ul class='javahierarchy'>
- * 	<li class='c'><a class="doclink" href="../BeanContext.html#ConfigProperties">BeanContext</a> - Properties associated with handling beans on serializers and parsers.
- * 	<ul>
- * 		<li class='c'><a class="doclink" href="../serializer/SerializerContext.html#ConfigProperties">SerializerContext</a> - Configurable properties common to all serializers.
- * 	</ul>
- * </ul>
- */
-public class UonSerializerContext extends SerializerContext {
-
-	/**
-	 * <b>Configuration property:</b>  Encode non-valid URI characters.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UonSerializer.encodeChars"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk> for {@link UonSerializer}, <jk>true</jk> for {@link UrlEncodingSerializer}
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Encode non-valid URI characters with <js>"%xx"</js> constructs.
-	 * <p>
-	 * If <jk>true</jk>, non-valid URI characters will be converted to <js>"%xx"</js> sequences.
-	 * Set to <jk>false</jk> if parameter value is being passed to some other code that will already
-	 * 	perform URL-encoding of non-valid URI characters.
-	 */
-	public static final String UON_encodeChars = "UonSerializer.encodeChars";
-
-	/**
-	 * <b>Configuration property:</b>  Add <js>"_type"</js> properties when needed.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UonSerializer.addBeanTypeProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred through reflection.
-	 * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
-	 * For example, when serializing a {@code Map<String,Object>} field, where the bean class cannot be determined from the value type.
-	 * <p>
-	 * When present, this value overrides the {@link SerializerContext#SERIALIZER_addBeanTypeProperties} setting and is
-	 * provided to customize the behavior of specific serializers in a {@link SerializerGroup}.
-	 */
-	public static final String UON_addBeanTypeProperties = "UonSerializer.addBeanTypeProperties";
-
-
-	final boolean
-		encodeChars,
-		addBeanTypeProperties;
-
-	/**
-	 * Constructor.
-	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
-	 *
-	 * @param cf The factory that created this context.
-	 */
-	public UonSerializerContext(ContextFactory cf) {
-		super(cf);
-		encodeChars = cf.getProperty(UON_encodeChars, boolean.class, false);
-		addBeanTypeProperties = cf.getProperty(UON_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
-	}
-
-	@Override /* Context */
-	public ObjectMap asMap() {
-		return super.asMap()
-			.append("UonSerializerContext", new ObjectMap()
-				.append("encodeChars", encodeChars)
-				.append("addBeanTypeProperties", addBeanTypeProperties)
-			);
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
deleted file mode 100644
index 27aeb38..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonSerializerSession.java
+++ /dev/null
@@ -1,88 +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.urlencoding;
-
-import static org.apache.juneau.msgpack.MsgPackSerializerContext.*;
-import static org.apache.juneau.urlencoding.UonSerializerContext.*;
-
-import java.lang.reflect.*;
-import java.util.*;
-
-import org.apache.juneau.*;
-import org.apache.juneau.json.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * Session object that lives for the duration of a single use of {@link UonSerializer}.
- * <p>
- * This class is NOT thread safe.  It is meant to be discarded after one-time use.
- */
-public class UonSerializerSession extends SerializerSession {
-
-	private final boolean
-		encodeChars,
-		addBeanTypeProperties;
-
-	/**
-	 * Create a new session using properties specified in the context.
-	 *
-	 * @param ctx The context creating this session object.
-	 * The context contains all the configuration settings for this object.
-	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
-	 * @param op The override properties.
-	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
-	 * @param locale The session locale.
-	 * If <jk>null</jk>, then the locale defined on the context is used.
-	 * @param timeZone The session timezone.
-	 * If <jk>null</jk>, then the timezone defined on the context is used.
-	 * @param mediaType The session media type (e.g. <js>"application/json"</js>).
-	 */
-	protected UonSerializerSession(UonSerializerContext ctx, ObjectMap op, Object output, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		super(ctx, op, output, javaMethod, locale, timeZone, mediaType);
-		if (op == null || op.isEmpty()) {
-			encodeChars = ctx.encodeChars;
-			addBeanTypeProperties = ctx.addBeanTypeProperties;
-		} else {
-			encodeChars = op.getBoolean(UON_encodeChars, ctx.encodeChars);
-			addBeanTypeProperties = op.getBoolean(MSGPACK_addBeanTypeProperties, ctx.addBeanTypeProperties);
-		}
-	}
-
-	/**
-	 * Returns the {@link UonSerializerContext#UON_encodeChars} setting value for this session.
-	 *
-	 * @return The {@link UonSerializerContext#UON_encodeChars} setting value for this session.
-	 */
-	public final boolean isEncodeChars() {
-		return encodeChars;
-	}
-
-	/**
-	 * Returns the {@link UonSerializerContext#UON_addBeanTypeProperties} setting value for this session.
-	 *
-	 * @return The {@link UonSerializerContext#UON_addBeanTypeProperties} setting value for this session.
-	 */
-	@Override /* SerializerSession */
-	public final boolean isAddBeanTypeProperties() {
-		return addBeanTypeProperties;
-	}
-
-	@Override /* SerializerSession */
-	public final UonWriter getWriter() throws Exception {
-		Object output = getOutput();
-		if (output instanceof UonWriter)
-			return (UonWriter)output;
-		return new UonWriter(this, super.getWriter(), isUseWhitespace(), isEncodeChars(), isTrimStrings(), getRelativeUriBase(), getAbsolutePathUriBase());
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
deleted file mode 100644
index bfbe5e0..0000000
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UonWriter.java
+++ /dev/null
@@ -1,281 +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.urlencoding;
-
-import java.io.*;
-
-import org.apache.juneau.internal.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * Specialized writer for serializing UON-encoded text.
- * <p>
- * <h5 class='section'>Notes:</h5>
- * <ul>
- * 	<li>This class is not intended for external use.
- * </ul>
- */
-public final class UonWriter extends SerializerWriter {
-
-	private final UonSerializerSession session;
-	private final boolean encodeChars;
-
-	// Characters that do not need to be URL-encoded in strings.
-	private static final AsciiSet unencodedChars = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~=");
-
-	// Characters that do not need to be URL-encoded in attribute names.
-	// Identical to unencodedChars, but excludes '='.
-	private static final AsciiSet unencodedCharsAttrName = new AsciiSet("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789;/?:@-_.!*'$(),~");
-
-	// Characters that need to be preceeded with an escape character.
-	private static final AsciiSet escapedChars = new AsciiSet("~'");
-
-	private static final AsciiSet needsQuoteChars = new AsciiSet("),=\n\t\r\b\f ");
-
-	private static final AsciiSet maybeNeedsQuotesFirstChar = new AsciiSet("),=\n\t\r\b\f tfn+-.#0123456789");
-
-	private static char[] hexArray = "0123456789ABCDEF".toCharArray();
-
-	/**
-	 * Constructor.
-	 *
-	 * @param session The session that created this writer.
-	 * @param out The writer being wrapped.
-	 * @param useWhitespace If <jk>true</jk>, tabs will be used in output.
-	 * @param encodeChars If <jk>true</jk>, special characters should be encoded.
-	 * @param trimStrings If <jk>true</jk>, strings should be trimmed before they're serialized.
-	 * @param relativeUriBase The base (e.g. <js>https://localhost:9443/contextPath"</js>) for relative URIs (e.g. <js>"my/path"</js>).
-	 * @param absolutePathUriBase The base (e.g. <js>https://localhost:9443"</js>) for relative URIs with absolute paths (e.g. <js>"/contextPath/my/path"</js>).
-	 */
-	protected UonWriter(UonSerializerSession session, Writer out, boolean useWhitespace, boolean encodeChars, boolean trimStrings, String relativeUriBase, String absolutePathUriBase) {
-		super(out, useWhitespace, trimStrings, '\'', relativeUriBase, absolutePathUriBase);
-		this.session = session;
-		this.encodeChars = encodeChars;
-	}
-
-	/**
-	 * Serializes the specified simple object as a UON string value.
-	 *
-	 * @param o The object being serialized.
-	 * @param isTopAttrName If this is a top-level attribute name we're serializing.
-	 * @return This object (for method chaining).
-	 * @throws IOException Should never happen.
-	 */
-	protected UonWriter appendObject(Object o, boolean isTopAttrName) throws IOException {
-
-		if (o instanceof Boolean)
-			return appendBoolean(o);
-		if (o instanceof Number)
-			return appendNumber(o);
-		if (o == null)
-			return append("null");
-
-		String s = session.toString(o);
-		char c0 = s.isEmpty() ? 0 : s.charAt(0);
-
-		boolean needsQuotes =
-			s.isEmpty()
-			|| c0 == '@'
-			|| c0 == '('
-			|| needsQuoteChars.contains(s)
-			|| (
-				maybeNeedsQuotesFirstChar.contains(c0)
-				&& (
-					"true".equals(s)
-					|| "false".equals(s)
-					|| "null".equals(s)
-					|| StringUtils.isNumeric(s)
-				)
-			)
-		;
-
-		AsciiSet unenc = (isTopAttrName ? unencodedCharsAttrName : unencodedChars);
-		AsciiSet esc = escapedChars;
-
-		if (needsQuotes)
-			append('\'');
-		for (int i = 0; i < s.length(); i++) {
-			char c = s.charAt(i);
-			if (esc.contains(c))
-				append('~');
-			if ((!encodeChars) || unenc.contains(c))
-				append(c);
-			else {
-				if (c == ' ')
-					append('+');
-				else {
-					int p = s.codePointAt(i);
-					if (p < 0x0080)
-						appendHex(p);
-					else if (p < 0x0800) {
-						int p1=p>>>6;
-						appendHex(p1+192).appendHex((p&63)+128);
-					} else if (p < 0x10000) {
-						int p1=p>>>6, p2=p1>>>6;
-						appendHex(p2+224).appendHex((p1&63)+128).appendHex((p&63)+128);
-					} else {
-						i++;  // Two-byte codepoint...skip past surrogate pair lower byte.
-						int p1=p>>>6, p2=p1>>>6, p3=p2>>>6;
-						appendHex(p3+240).appendHex((p2&63)+128).appendHex((p1&63)+128).appendHex((p&63)+128);
-					}
-				}
-			}
-		}
-		if (needsQuotes)
-			append('\'');
-
-		return this;
-	}
-
-	/**
-	 * Appends a boolean value to the output.
-	 *
-	 * @param o The boolean value to append to the output.
-	 * @return This object (for method chaining).
-	 * @throws IOException
-	 */
-	protected UonWriter appendBoolean(Object o) throws IOException {
-		append(o.toString());
-		return this;
-	}
-
-	/**
-	 * Appends a numeric value to the output.
-	 *
-	 * @param o The numeric value to append to the output.
-	 * @return This object (for method chaining).
-	 * @throws IOException
-	 */
-	protected UonWriter appendNumber(Object o) throws IOException {
-		append(o.toString());
-		return this;
-	}
-
-	/**
-	 * Prints out a two-byte %xx sequence for the given byte value.
-	 */
-	private UonWriter appendHex(int b) throws IOException {
-		if (b > 255)
-			throw new IOException("Invalid value passed to appendHex.  Must be in the range 0-255.  Value=" + b);
-		append('%').append(hexArray[b>>>4]).append(hexArray[b&0x0F]);
-		return this;
-	}
-
-	/**
-	 * Appends a URI to the output.
-	 *
-	 * @param uri The URI to append to the output.
-	 * @return This object (for method chaining).
-	 * @throws IOException
-	 */
-	@Override
-	public SerializerWriter appendUri(Object uri) throws IOException {
-		String s = uri.toString();
-		if (s.indexOf("://") == -1) {
-			if (StringUtils.startsWith(s, '/')) {
-				if (absolutePathUriBase != null)
-					append(absolutePathUriBase);
-			} else {
-				if (relativeUriBase != null) {
-					append(relativeUriBase);
-					if (! relativeUriBase.equals("/"))
-						append("/");
-				}
-			}
-		}
-		return appendObject(s, false);
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* SerializerWriter */
-	public UonWriter cr(int depth) throws IOException {
-		super.cr(depth);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter appendln(int indent, String text) throws IOException {
-		super.appendln(indent, text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter appendln(String text) throws IOException {
-		super.appendln(text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter append(int indent, String text) throws IOException {
-		super.append(indent, text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter append(int indent, char c) throws IOException {
-		super.append(indent, c);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter q() throws IOException {
-		super.q();
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter i(int indent) throws IOException {
-		super.i(indent);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter nl() throws IOException {
-		super.nl();
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter append(Object text) throws IOException {
-		super.append(text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter append(String text) throws IOException {
-		super.append(text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter appendIf(boolean b, String text) throws IOException {
-		super.appendIf(b, text);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter appendIf(boolean b, char c) throws IOException {
-		super.appendIf(b, c);
-		return this;
-	}
-
-	@Override /* SerializerWriter */
-	public UonWriter append(char c) throws IOException {
-		super.append(c);
-		return this;
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingContext.java
index d412eeb..abd3bb9 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingContext.java
@@ -15,8 +15,8 @@ package org.apache.juneau.urlencoding;
 /**
  * Configurable properties on the {@link UrlEncodingSerializer} and {@link UrlEncodingParser} classes.
  * <p>
- * Use the {@link UrlEncodingSerializer#setProperty(String, Object)} and
- * 	{@link UrlEncodingParser#setProperty(String, Object)} methods to set property values.
+ * Use the {@link UrlEncodingSerializerBuilder#property(String, Object)} and
+ * 	{@link UrlEncodingParserBuilder#property(String, Object)} methods to set property values.
  */
 public final class UrlEncodingContext implements Cloneable {
 
@@ -33,11 +33,11 @@ public final class UrlEncodingContext implements Cloneable {
 	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
 	 * 	}
 	 *
-	 * 	UrlEncodingSerializer s1 = <jk>new</jk> UrlEncodingParser();
-	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingParser().setExpandedParams(<jk>true</jk>);
+	 * 	UrlEncodingSerializer s1 = UrlEncodingSerializer.<jsf>DEFAULT</jsf>;
+	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingSerializerBuilder().expandedParams(<jk>true</jk>).build();
 	 *
-	 * 	String s1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
-	 * 	String s2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
+	 * 	String ss1 = s1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
+	 * 	String ss2 = s2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
 	 * </p>
 	 * <p>
 	 * This option only applies to beans.
@@ -53,17 +53,4 @@ public final class UrlEncodingContext implements Cloneable {
 
 	boolean
 		expandedParams = false;
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Cloneable */
-	public UrlEncodingContext clone() {
-		try {
-			return (UrlEncodingContext)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
index 1a76fd6..f6de298 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParser.java
@@ -12,7 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.urlencoding;
 
-import static org.apache.juneau.urlencoding.UrlEncodingParserContext.*;
+import static org.apache.juneau.uon.UonParserContext.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -22,6 +22,7 @@ import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Parses URL-encoded text into POJO models.
@@ -51,13 +52,28 @@ import org.apache.juneau.transform.*;
 public class UrlEncodingParser extends UonParser {
 
 	/** Reusable instance of {@link UrlEncodingParser}. */
-	public static final UrlEncodingParser DEFAULT = new UrlEncodingParser().lock();
+	public static final UrlEncodingParser DEFAULT = new UrlEncodingParser(PropertyStore.create());
+
+
+	private final UrlEncodingParserContext ctx;
 
 	/**
 	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
 	 */
-	public UrlEncodingParser() {
-		setDecodeChars(true);
+	public UrlEncodingParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(UrlEncodingParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public ObjectMap getOverrideProperties() {
+		return super.getOverrideProperties().append(UON_decodeChars, true);
+	}
+
+	@Override /* CoreObject */
+	public UrlEncodingParserBuilder builder() {
+		return new UrlEncodingParserBuilder(propertyStore);
 	}
 
 	private <T> T parseAnything(UrlEncodingParserSession session, ClassMeta<T> eType, ParserReader r, Object outer) throws Exception {
@@ -495,7 +511,7 @@ public class UrlEncodingParser extends UonParser {
 
 	@Override /* Parser */
 	public UrlEncodingParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new UrlEncodingParserSession(getContext(UrlEncodingParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new UrlEncodingParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	@Override /* Parser */
@@ -523,478 +539,4 @@ public class UrlEncodingParser extends UonParser {
 		m = parseIntoMap(s, r, m, (ClassMeta<K>)session.getClassMeta(keyType), (ClassMeta<V>)session.getClassMeta(valueType));
 		return m;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b> Serialize bean property collections/arrays as separate key/value pairs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
-	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jk>public class</jk> A {
-	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
-	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
-	 * 	}
-	 *
-	 * 	UrlEncodingSerializer s1 = <jk>new</jk> UrlEncodingParser();
-	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingParser().setExpandedParams(<jk>true</jk>);
-	 *
-	 * 	String s1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
-	 * 	String s2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
-	 * </p>
-	 * <p>
-	 * This option only applies to beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
-	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
-	 * 		is added to it.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>URLENC_expandedParams</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see UrlEncodingParserContext#URLENC_expandedParams
-	 */
-	public UrlEncodingParser setExpandedParams(boolean value) throws LockedException {
-		return setProperty(URLENC_expandedParams, value);
-	}
-
-	@Override /* UonParser */
-	public UrlEncodingParser setDecodeChars(boolean value) throws LockedException {
-		super.setDecodeChars(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UrlEncodingParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UrlEncodingParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UrlEncodingParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public UrlEncodingParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public UrlEncodingParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UrlEncodingParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UrlEncodingParser clone() {
-		UrlEncodingParser c = (UrlEncodingParser)super.clone();
-		return c;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
new file mode 100644
index 0000000..b9ec130
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserBuilder.java
@@ -0,0 +1,513 @@
+// ***************************************************************************************************************************
+// * 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.urlencoding;
+
+import static org.apache.juneau.uon.UonParserContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
+
+/**
+ * Builder class for building instances of URL-Encoding parsers.
+ */
+public class UrlEncodingParserBuilder extends UonParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public UrlEncodingParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public UrlEncodingParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParser build() {
+		return new UrlEncodingParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b> Serialize bean property collections/arrays as separate key/value pairs.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
+	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	<jk>public class</jk> A {
+	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
+	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
+	 * 	}
+	 *
+	 * 	UrlEncodingSerializer s1 = UrlEncodingSerializer.<jsf>DEFAULT</jsf>;
+	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingSerializerBuilder().expandedParams(<jk>true</jk>).build();
+	 *
+	 * 	String ss1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
+	 * 	String ss2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
+	 * </p>
+	 * <p>
+	 * This option only applies to beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
+	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
+	 * 		is added to it.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>URLENC_expandedParams</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see UrlEncodingContext#URLENC_expandedParams
+	 */
+	public UrlEncodingParserBuilder expandedParams(boolean value) {
+		return property(UrlEncodingContext.URLENC_expandedParams, value);
+	}
+
+	@Override /* UonParser */
+	public UrlEncodingParserBuilder decodeChars(boolean value) {
+		return property(UON_decodeChars, value);
+	}
+
+	@Override /* ParserBuilder */
+	public UrlEncodingParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UrlEncodingParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UrlEncodingParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UrlEncodingParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public UrlEncodingParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> UrlEncodingParserBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserContext.java
index a9829c1..c26779a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserContext.java
@@ -13,69 +13,31 @@
 package org.apache.juneau.urlencoding;
 
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Configurable properties on the {@link UrlEncodingParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  */
 public class UrlEncodingParserContext extends UonParserContext {
 
-	/**
-	 * <b>Configuration property:</b> Serialize bean property collections/arrays as separate key/value pairs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
-	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jk>public class</jk> A {
-	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
-	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
-	 * 	}
-	 *
-	 * 	UrlEncodingSerializer s1 = <jk>new</jk> UrlEncodingParser();
-	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingParser().setExpandedParams(<jk>true</jk>);
-	 *
-	 * 	String s1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
-	 * 	String s2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
-	 * </p>
-	 * <p>
-	 * This option only applies to beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
-	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
-	 * 		is added to it.
-	 * </ul>
-	 */
-	public static final String URLENC_expandedParams = "UrlEncoding.expandedParams";
-
-
 	final boolean
 		expandedParams;
 
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public UrlEncodingParserContext(ContextFactory cf) {
-		super(cf);
-		this.expandedParams = cf.getProperty(URLENC_expandedParams, boolean.class, false);
+	public UrlEncodingParserContext(PropertyStore ps) {
+		super(ps);
+		this.expandedParams = ps.getProperty(UrlEncodingContext.URLENC_expandedParams, boolean.class, false);
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
index 2d2ba44..44bfc4b 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingParserSession.java
@@ -12,13 +12,12 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.urlencoding;
 
-import static org.apache.juneau.urlencoding.UrlEncodingParserContext.*;
-
 import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Session object that lives for the duration of a single use of {@link UrlEncodingParser}.
@@ -57,7 +56,7 @@ public class UrlEncodingParserSession extends UonParserSession {
 		if (op == null || op.isEmpty()) {
 			expandedParams = ctx.expandedParams;
 		} else {
-			expandedParams = op.getBoolean(URLENC_expandedParams, false);
+			expandedParams = op.getBoolean(UrlEncodingContext.URLENC_expandedParams, false);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
index 94c8f97..950bbbd 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializer.java
@@ -12,7 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.urlencoding;
 
-import static org.apache.juneau.urlencoding.UrlEncodingSerializerContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+import static org.apache.juneau.uon.UonSerializerContext.*;
 
 import java.io.*;
 import java.lang.reflect.*;
@@ -24,6 +25,7 @@ import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Serializes POJO models to URL-encoded notation with UON-encoded values (a notation for URL-encoded query paramter values).
@@ -132,42 +134,75 @@ import org.apache.juneau.transform.*;
 public class UrlEncodingSerializer extends UonSerializer {
 
 	/** Reusable instance of {@link UrlEncodingSerializer}, all default settings. */
-	public static final UrlEncodingSerializer DEFAULT = new UrlEncodingSerializer().lock();
+	public static final UrlEncodingSerializer DEFAULT = new UrlEncodingSerializer(PropertyStore.create());
 
 	/** Reusable instance of {@link UrlEncodingSerializer.Expanded}. */
-	public static final UrlEncodingSerializer DEFAULT_EXPANDED = new Expanded().lock();
+	public static final UrlEncodingSerializer DEFAULT_EXPANDED = new Expanded(PropertyStore.create());
 
 	/** Reusable instance of {@link UrlEncodingSerializer.Readable}. */
-	public static final UrlEncodingSerializer DEFAULT_READABLE = new Readable().lock();
+	public static final UrlEncodingSerializer DEFAULT_READABLE = new Readable(PropertyStore.create());
 
 	/**
-	 * Constructor.
-	 */
-	public UrlEncodingSerializer() {
-		setEncodeChars(true);
-	}
-
-	/**
-	 * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setSimpleMode(<jk>true</jk>).setExpandedParams(<jk>true</jk>);</code>.
+	 * Equivalent to <code><jk>new</jk> UrlEncodingSerializerBuilder().expandedParams(<jk>true</jk>).build();</code>.
 	 */
 	@Produces(value="application/x-www-form-urlencoded",contentType="application/x-www-form-urlencoded")
 	public static class Expanded extends UrlEncodingSerializer {
-		/** Constructor */
-		public Expanded() {
-			setExpandedParams(true);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Expanded(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(UrlEncodingContext.URLENC_expandedParams, true);
 		}
 	}
 
 	/**
-	 * Equivalent to <code><jk>new</jk> UrlEncodingSerializer().setUseWhitespace(<jk>true</jk>);</code>.
+	 * Equivalent to <code><jk>new</jk> UrlEncodingSerializerBuilder().useWhitespace(<jk>true</jk>).build();</code>.
 	 */
 	public static class Readable extends UrlEncodingSerializer {
-		/** Constructor */
-		public Readable() {
-			setUseWhitespace(true);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Readable(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(SERIALIZER_useWhitespace, true);
 		}
 	}
 
+
+	private final UrlEncodingSerializerContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public UrlEncodingSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(UrlEncodingSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public UrlEncodingSerializerBuilder builder() {
+		return new UrlEncodingSerializerBuilder(propertyStore);
+	}
+
+	@Override /* CoreObject */
+	protected ObjectMap getOverrideProperties() {
+		return super.getOverrideProperties().append(UON_encodeChars, true);
+	}
+
 	/**
 	 * Workhorse method. Determines the type of object, and then calls the
 	 * appropriate type-specific serialization method.
@@ -349,7 +384,7 @@ public class UrlEncodingSerializer extends UonSerializer {
 
 	@Override /* Serializer */
 	public UrlEncodingSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new UrlEncodingSerializerSession(getContext(UrlEncodingSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new UrlEncodingSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	@Override /* Serializer */
@@ -357,545 +392,4 @@ public class UrlEncodingSerializer extends UonSerializer {
 		UrlEncodingSerializerSession s = (UrlEncodingSerializerSession)session;
 		serializeAnything(s, s.getWriter(), o);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Serialize bean property collections/arrays as separate key/value pairs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
-	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jk>public class</jk> A {
-	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
-	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
-	 * 	}
-	 *
-	 * 	UrlEncodingSerializer s1 = <jk>new</jk> UrlEncodingParser();
-	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingParser().setExpandedParams(<jk>true</jk>);
-	 *
-	 * 	String s1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
-	 * 	String s2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
-	 * </p>
-	 * <p>
-	 * This option only applies to beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
-	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
-	 * 		is added to it.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>URLENC_expandedParams</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see UrlEncodingSerializerContext#URLENC_expandedParams
-	 */
-	public UrlEncodingSerializer setExpandedParams(boolean value) throws LockedException {
-		return setProperty(URLENC_expandedParams, value);
-	}
-
-	@Override /* UonSerializer */
-	public UrlEncodingSerializer setEncodeChars(boolean value) throws LockedException {
-		super.setEncodeChars(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public UrlEncodingSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public UrlEncodingSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UrlEncodingSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public UrlEncodingSerializer clone() {
-		UrlEncodingSerializer c = (UrlEncodingSerializer)super.clone();
-		return c;
-	}
 }


[05/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestUtils.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestUtils.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestUtils.java
index 3cd0ed3..f7615af 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestUtils.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestUtils.java
@@ -39,21 +39,29 @@ import org.xml.sax.*;
 
 public class TestUtils {
 
-	private static JsonSerializer js = new JsonSerializer.Simple()
-		.setTrimNullProperties(false);
-
-	private static JsonSerializer jsSorted = new JsonSerializer.Simple()
-		.setSortCollections(true)
-		.setSortMaps(true)
-		.setTrimNullProperties(false);
-
-
-	private static JsonSerializer js2 = new JsonSerializer.Simple()
-		.addPojoSwaps(IteratorSwap.class, EnumerationSwap.class);
-
-	private static JsonSerializer js3 = new JsonSerializer.Simple()
-		.addPojoSwaps(IteratorSwap.class, EnumerationSwap.class)
-		.setSortProperties(true);
+	private static JsonSerializer js = new JsonSerializerBuilder()
+		.simple()
+		.trimNullProperties(false)
+		.build();
+
+	private static JsonSerializer jsSorted = new JsonSerializerBuilder()
+		.simple()
+		.sortCollections(true)
+		.sortMaps(true)
+		.trimNullProperties(false)
+		.build();
+
+
+	private static JsonSerializer js2 = new JsonSerializerBuilder()
+		.simple()
+		.pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+		.build();
+
+	private static JsonSerializer js3 = new JsonSerializerBuilder()
+		.simple()
+		.pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+		.sortProperties(true)
+		.build();
 
 	/**
 	 * Verifies that two objects are equivalent.
@@ -221,7 +229,7 @@ public class TestUtils {
 	 * Test whitespace and generated schema.
 	 */
 	public static void validateXml(Object o, XmlSerializer s) throws Exception {
-		s = s.clone().setUseWhitespace(true).setEnableNamespaces(true).setAddNamespaceUrisToRoot(true);
+		s = s.builder().ws().ns().addNamespaceUrisToRoot(true).build();
 		String xml = s.serialize(o);
 
 		String xmlSchema = null;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/_TestSuite.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/_TestSuite.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/_TestSuite.java
index 4bbc700..d902804 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/_TestSuite.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/_TestSuite.java
@@ -33,11 +33,11 @@ public class _TestSuite {
 
 	@BeforeClass
 	public static void setUp() {
-		TestMicroservice.startMicroservice();
+		SamplesMicroservice.startMicroservice();
 	}
 
 	@AfterClass
 	public static void tearDown() {
-		TestMicroservice.stopMicroservice();
+		SamplesMicroservice.stopMicroservice();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/json/JsonConfigurationExample.java
----------------------------------------------------------------------
diff --git a/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/json/JsonConfigurationExample.java b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/json/JsonConfigurationExample.java
index 8adb404..77febad 100644
--- a/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/json/JsonConfigurationExample.java
+++ b/juneau-examples/juneau-examples-core/src/main/java/org/apache/juneau/examples/core/json/JsonConfigurationExample.java
@@ -27,15 +27,11 @@ public class JsonConfigurationExample {
     public static void main(String[] args) throws Exception {
         Pojo aPojo = new Pojo("a","</pojo>");
         // Json Serializers can be configured using properties defined in JsonSerializerContext
-        String withWhitespace = new JsonSerializer()
-                .setProperty(JsonSerializerContext.JSON_useWhitespace, true)
-                .serialize(aPojo);
+        String withWhitespace = new JsonSerializerBuilder().ws().build().serialize(aPojo);
         // the output will be padded with spaces after format characters
         System.out.println(withWhitespace);
 
-        String escaped = new JsonSerializer()
-                .setProperty(JsonSerializerContext.JSON_escapeSolidus, true)
-                .serialize(aPojo);
+        String escaped = new JsonSerializerBuilder().escapeSolidus(true).build().serialize(aPojo);
         // the output will have escaped /
         System.out.println(escaped);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/Microservice.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Microservice.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Microservice.java
index 66a9c7d..e643f97 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Microservice.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Microservice.java
@@ -252,12 +252,15 @@ public abstract class Microservice {
 	 *
 	 * @return A new {@link VarResolver}.
 	 */
-	protected VarResolver createVarResolver() {
-		return new VarResolver()
-			.addVars(SystemPropertiesVar.class, EnvVariablesVar.class, ConfigFileVar.class, ManifestFileVar.class, ArgsVar.class, SwitchVar.class, IfVar.class)
-			.setContextObject(ConfigFileVar.SESSION_config, cf)
-			.setContextObject(ManifestFileVar.SESSION_manifest, mf)
-			.setContextObject(ArgsVar.SESSION_args, args);
+	protected VarResolverBuilder createVarResolver() {
+		VarResolverBuilder b = new VarResolverBuilder()
+			.defaultVars()
+			.vars(ConfigFileVar.class, ManifestFileVar.class, ArgsVar.class, SwitchVar.class, IfVar.class)
+			.contextObject(ManifestFileVar.SESSION_manifest, mf)
+			.contextObject(ArgsVar.SESSION_args, args);
+		if (cf != null)
+			b.contextObject(ConfigFileVar.SESSION_config, cf);
+		return b;
 	}
 
 	/**
@@ -436,7 +439,7 @@ public abstract class Microservice {
 		// Resolve the config file if the path was specified.
 		// --------------------------------------------------------------------------------
 		if (cfPath != null) 
-			cf = ConfigMgr.DEFAULT.get(cfPath).getResolving(createVarResolver());
+			cf = ConfigMgr.DEFAULT.get(cfPath).getResolving(createVarResolver().build());
 		
 		// --------------------------------------------------------------------------------
 		// Find config file.
@@ -459,7 +462,7 @@ public abstract class Microservice {
 				cf = ConfigMgr.DEFAULT.create();
 			} else {
 				System.out.println("Running class ["+getClass().getSimpleName()+"] using config file ["+cfPath+"]");
-				cf = ConfigMgr.DEFAULT.get(cfPath).getResolving(createVarResolver());
+				cf = ConfigMgr.DEFAULT.get(cfPath).getResolving(createVarResolver().build());
 			}
 		}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
index a67199a..c0b9326 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/Resource.java
@@ -52,10 +52,10 @@ public abstract class Resource extends RestServletDefault {
 	 * Adds $ARG and $MF variables to variable resolver defined on {@link RestServlet#createVarResolver()}.
 	 */
 	@Override
-	protected VarResolver createVarResolver() {
+	protected VarResolverBuilder createVarResolver() {
 		return super.createVarResolver()
-			.addVars(ArgsVar.class, ManifestFileVar.class)
-			.setContextObject(ArgsVar.SESSION_args, Microservice.getArgs())
-			.setContextObject(ManifestFileVar.SESSION_manifest, Microservice.getManifest());
+			.vars(ArgsVar.class, ManifestFileVar.class)
+			.contextObject(ArgsVar.SESSION_args, Microservice.getArgs())
+			.contextObject(ManifestFileVar.SESSION_manifest, Microservice.getManifest());
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
index 6ccbffd..610575d 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/ResourceGroup.java
@@ -53,10 +53,10 @@ public abstract class ResourceGroup extends RestServletGroupDefault {
 	 * Adds $ARG and $MF variables to variable resolver defined on {@link RestServlet#createVarResolver()}.
 	 */
 	@Override
-	protected VarResolver createVarResolver() {
+	protected VarResolverBuilder createVarResolver() {
 		return super.createVarResolver()
-			.addVars(ArgsVar.class, ManifestFileVar.class)
-			.setContextObject(ArgsVar.SESSION_args, Microservice.getArgs())
-			.setContextObject(ManifestFileVar.SESSION_manifest, Microservice.getManifest());
+			.vars(ArgsVar.class, ManifestFileVar.class)
+			.contextObject(ArgsVar.SESSION_args, Microservice.getArgs())
+			.contextObject(ManifestFileVar.SESSION_manifest, Microservice.getManifest());
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
index 56e9789..cc30dcd 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/RestMicroservice.java
@@ -121,9 +121,10 @@ public class RestMicroservice extends Microservice {
 			@Override /* Thread */
 			public void run() {
 				try {
+					if (server.isStopping() || server.isStopped())
+						return;
 					onStopServer();
 					logger.warning("Stopping server.");
-					System.out.println();
 					server.stop();
 					logger.warning("Server stopped.");
 					onPostStopServer();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
index a49aeff..b546032 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/package.html
@@ -366,6 +366,8 @@
 	<cs>[REST]</cs>
 	
 	<cc># The HTTP port number to use.
+	# Can be a comma-delimited list of ports to try.
+	# 0 means try a random port.
 	# Default is Rest-Port setting in manifest file, or 8000.</cc>
 	<ck>port</ck> = <cv>10000</cv>
 	

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
----------------------------------------------------------------------
diff --git a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
index 5419514..c7f1b08 100755
--- a/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
+++ b/juneau-microservice/src/main/java/org/apache/juneau/microservice/resources/ConfigResource.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.microservice.resources;
 
 import static javax.servlet.http.HttpServletResponse.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.io.*;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
index b56797f..ce49c5e 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
@@ -18,7 +18,7 @@ import java.util.regex.*;
 /**
  * Used to find regular expression matches in REST responses made through {@link RestCall}.
  * <p>
- * Response patterns are applied to REST calls through the {@link RestCall#addResponsePattern(ResponsePattern)} method.
+ * Response patterns are applied to REST calls through the {@link RestCall#responsePattern(ResponsePattern)} method.
  *
  * <h5 class='section'>Example:</h5>
  * This example shows how to use a response pattern finder to find and capture patterns for <js>"x=number"</js> and <js>"y=string"</js>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index b3c33a5..9aba208 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -65,7 +65,7 @@ public final class RestCall {
 	private int retries = 1;
 	private int redirectOnPostsTries = 5;
 	private long retryInterval = -1;
-	private RetryOn retryOn = RetryOn.DEFAULT;
+	private RetryOn retryOn;
 	private boolean ignoreErrors;
 	private boolean byLines = false;
 	private TeeWriter writers = new TeeWriter();
@@ -85,8 +85,11 @@ public final class RestCall {
 	protected RestCall(RestClient client, HttpRequestBase request) throws RestCallException {
 		this.client = client;
 		this.request = request;
-		for (RestCallInterceptor i : this.client.interceptors)
-			addInterceptor(i);
+		for (RestCallInterceptor i : this.client.getInterceptors())
+			interceptor(i);
+		this.retryOn = client.retryOn;
+		this.retries = client.retries;
+		this.retryInterval = client.retryInterval;
 	}
 
 	/**
@@ -103,16 +106,26 @@ public final class RestCall {
 	 * @return This object (for method chaining).
 	 * @throws RestCallException If a retry was attempted, but the entity was not repeatable.
 	 */
-	public RestCall setInput(final Object input) throws RestCallException {
+	public RestCall input(final Object input) throws RestCallException {
+
 		if (! (request instanceof HttpEntityEnclosingRequestBase))
 			throw new RestCallException(0, "Method does not support content entity.", request.getMethod(), request.getURI(), null);
-		HttpEntity entity = (input instanceof HttpEntity ? (HttpEntity)input : new RestRequestEntity(input, client.serializer));
+
+		HttpEntity entity = (input instanceof HttpEntity) ? (HttpEntity)input : new RestRequestEntity(input, client.getSerializer());
+
 		((HttpEntityEnclosingRequestBase)request).setEntity(entity);
+
 		if (retries > 1 && ! entity.isRepeatable())
 			throw new RestCallException("Rest call set to retryable, but entity is not repeatable.");
+
 		return this;
 	}
 
+
+	//--------------------------------------------------------------------------------
+	// HTTP headers
+	//--------------------------------------------------------------------------------
+
 	/**
 	 * Convenience method for setting a header value on the request.
 	 * <p>
@@ -122,12 +135,382 @@ public final class RestCall {
 	 * @param value The header value.
 	 * @return This object (for method chaining).
 	 */
-	public RestCall setHeader(String name, Object value) {
+	public RestCall header(String name, Object value) {
 		request.setHeader(name, value.toString());
 		return this;
 	}
 
 	/**
+	 * Sets the value for the <code>Accept</code> request header.
+	 * <p>
+	 * This overrides the media type specified on the parser, but is overridden by calling <code>header(<js>"Accept"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall accept(Object value) {
+		return header("Accept", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Charset</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Charset"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall acceptCharset(Object value) {
+		return header("Accept-Charset", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Encoding</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Encoding"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall acceptEncoding(Object value) {
+		return header("Accept-Encoding", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Language</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Language"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall acceptLanguage(Object value) {
+		return header("Accept-Language", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Authorization</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Authorization"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall authorization(Object value) {
+		return header("Authorization", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Cache-Control</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Cache-Control"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall cacheControl(Object value) {
+		return header("Cache-Control", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Connection</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Connection"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall connection(Object value) {
+		return header("Connection", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Content-Length</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Content-Length"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall contentLength(Object value) {
+		return header("Content-Length", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Content-Type</code> request header.
+	 * <p>
+	 * This overrides the media type specified on the serializer, but is overridden by calling <code>header(<js>"Content-Type"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall contentType(Object value) {
+		return header("Content-Type", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Date</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Date"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall date(Object value) {
+		return header("Date", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Expect</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Expect"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall expect(Object value) {
+		return header("Expect", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Forwarded</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Forwarded"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall forwarded(Object value) {
+		return header("Forwarded", value);
+	}
+
+	/**
+	 * Sets the value for the <code>From</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"From"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall from(Object value) {
+		return header("From", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Host</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Host"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall host(Object value) {
+		return header("Host", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Match</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Match"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall ifMatch(Object value) {
+		return header("If-Match", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Modified-Since</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Modified-Since"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall ifModifiedSince(Object value) {
+		return header("If-Modified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-None-Match</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-None-Match"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall ifNoneMatch(Object value) {
+		return header("If-None-Match", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Range</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Range"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall ifRange(Object value) {
+		return header("If-Range", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Unmodified-Since</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Unmodified-Since"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall ifUnmodifiedSince(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Max-Forwards</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Max-Forwards"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall maxForwards(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Origin</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Origin"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall origin(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Pragma</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Pragma"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall pragma(Object value) {
+		return header("Pragma", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Proxy-Authorization</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Proxy-Authorization"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall proxyAuthorization(Object value) {
+		return header("Proxy-Authorization", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Range</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Range"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall range(Object value) {
+		return header("Range", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Referer</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Referer"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall referer(Object value) {
+		return header("Referer", value);
+	}
+
+	/**
+	 * Sets the value for the <code>TE</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"TE"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall te(Object value) {
+		return header("TE", value);
+	}
+
+	/**
+	 * Sets the value for the <code>User-Agent</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"User-Agent"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall userAgent(Object value) {
+		return header("User-Agent", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Upgrade</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Upgrade"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall upgrade(Object value) {
+		return header("Upgrade", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Via</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Via"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall via(Object value) {
+		return header("Via", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Warning</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Warning"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestCall warning(Object value) {
+		return header("Warning", value);
+	}
+
+	/**
+	 * Sets the client version by setting the value for the <js>"X-Client-Version"</js> header.
+	 *
+	 * @param version The version string (e.g. <js>"1.2.3"</js>)
+	 * @return This object (for method chaining).
+	 */
+	public RestCall clientVersion(String version) {
+		return header("X-Client-Version", version);
+	}
+
+	/**
 	 * Make this call retryable if an error response (>=400) is received.
 	 *
 	 * @param retries The number of retries to attempt.
@@ -137,7 +520,8 @@ public final class RestCall {
 	 * @return This object (for method chaining).
 	 * @throws RestCallException If current entity is not repeatable.
 	 */
-	public RestCall setRetryable(int retries, long interval, RetryOn retryOn) throws RestCallException {
+	@SuppressWarnings("hiding")
+	public RestCall retryable(int retries, long interval, RetryOn retryOn) throws RestCallException {
 		if (request instanceof HttpEntityEnclosingRequestBase) {
 		HttpEntity e = ((HttpEntityEnclosingRequestBase)request).getEntity();
 		if (e != null && ! e.isRepeatable())
@@ -174,7 +558,7 @@ public final class RestCall {
 	 * @param maxAttempts Allow a redirect to occur this number of times.
 	 * @return This object (for method chaining).
 	 */
-	public RestCall setRedirectMaxAttempts(int maxAttempts) {
+	public RestCall redirectMaxAttempts(int maxAttempts) {
 		this.redirectOnPostsTries = maxAttempts;
 		return this;
 	}
@@ -185,7 +569,7 @@ public final class RestCall {
 	 * @param interceptor The interceptor to add to this call.
 	 * @return This object (for method chaining).
 	 */
-	public RestCall addInterceptor(RestCallInterceptor interceptor) {
+	public RestCall interceptor(RestCallInterceptor interceptor) {
 		interceptors.add(interceptor);
 		interceptor.onInit(this);
 		return this;
@@ -352,7 +736,7 @@ public final class RestCall {
 	 * @return This object (for method chaining).
 	 */
 	public RestCall failurePattern(final String errorPattern) {
-		addResponsePattern(
+		responsePattern(
 			new ResponsePattern(errorPattern) {
 				@Override
 				public void onMatch(RestCall rc, Matcher m) throws RestCallException {
@@ -383,7 +767,7 @@ public final class RestCall {
 	 * @return This object (for method chaining).
 	 */
 	public RestCall successPattern(String successPattern) {
-		addResponsePattern(
+		responsePattern(
 			new ResponsePattern(successPattern) {
 				@Override
 				public void onNoMatch(RestCall rc) throws RestCallException {
@@ -405,9 +789,9 @@ public final class RestCall {
 	 * @param responsePattern The response pattern finder.
 	 * @return This object (for method chaining).
 	 */
-	public RestCall addResponsePattern(final ResponsePattern responsePattern) {
+	public RestCall responsePattern(final ResponsePattern responsePattern) {
 		captureResponse();
-		addInterceptor(
+		interceptor(
 			new RestCallInterceptor() {
 				@Override
 				public void onClose(RestCall restCall) throws RestCallException {
@@ -506,7 +890,7 @@ public final class RestCall {
 				retries--;
 				Exception ex = null;
 				try {
-			response = client.execute(request);
+					response = client.execute(request);
 					sc = (response == null || response.getStatusLine() == null) ? -1 : response.getStatusLine().getStatusCode();
 				} catch (Exception e) {
 					ex = e;
@@ -644,9 +1028,9 @@ public final class RestCall {
 	 * @throws RestCallException If no parser was defined on the client.
 	 */
 	protected Parser getParser() throws RestCallException {
-		if (client.parser == null)
+		if (client.getParser() == null)
 			throw new RestCallException(0, "No parser defined on client", request.getMethod(), request.getURI(), null);
-		return client.parser;
+		return client.getParser();
 	}
 
 	/**
@@ -656,9 +1040,9 @@ public final class RestCall {
 	 * @throws RestCallException If no serializer was defined on the client.
 	 */
 	protected Serializer getSerializer() throws RestCallException {
-		if (client.serializer == null)
+		if (client.getSerializer() == null)
 			throw new RestCallException(0, "No serializer defined on client", request.getMethod(), request.getURI(), null);
-		return client.serializer;
+		return client.getSerializer();
 	}
 
 	/**
@@ -861,7 +1245,7 @@ public final class RestCall {
 	 * @param header The header to set on the request.
 	 * @return This object (for method chaining).
 	 */
-	public RestCall setHeader(Header header) {
+	public RestCall header(Header header) {
 		request.setHeader(header);
 		return this;
 	}
@@ -897,7 +1281,7 @@ public final class RestCall {
 	 * @return This object (for method chaining).
 	 */
 	public RestCall logTo(Level level, Logger log) {
-		addInterceptor(new RestCallLogger(level, log));
+		interceptor(new RestCallLogger(level, log));
 		return this;
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
index 7bd7bc4..2eb8a55 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
@@ -26,7 +26,7 @@ import org.apache.http.util.*;
  * Causes a log entry to be created that shows all the request and response headers and content
  * 	at the end of the request.
  * <p>
- * Use the {@link RestClient#logTo(Level, Logger)} and {@link RestCall#logTo(Level, Logger)}
+ * Use the {@link RestClientBuilder#logTo(Level, Logger)} and {@link RestCall#logTo(Level, Logger)}
  * <p>
  * methods to create instances of this class.
  */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 6f175cc..8d4748d 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -18,32 +18,14 @@ import java.io.*;
 import java.lang.reflect.*;
 import java.lang.reflect.Proxy;
 import java.net.*;
-import java.security.*;
 import java.util.*;
 import java.util.concurrent.*;
-import java.util.logging.*;
 import java.util.regex.*;
 
-import javax.net.ssl.*;
-
 import org.apache.http.*;
-import org.apache.http.auth.*;
-import org.apache.http.client.*;
-import org.apache.http.client.CookieStore;
-import org.apache.http.client.config.*;
-import org.apache.http.client.entity.*;
 import org.apache.http.client.methods.*;
-import org.apache.http.config.*;
-import org.apache.http.conn.*;
-import org.apache.http.conn.routing.*;
-import org.apache.http.conn.socket.*;
-import org.apache.http.conn.ssl.*;
-import org.apache.http.conn.util.*;
-import org.apache.http.cookie.*;
 import org.apache.http.entity.*;
 import org.apache.http.impl.client.*;
-import org.apache.http.impl.conn.*;
-import org.apache.http.protocol.*;
 import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
@@ -68,246 +50,79 @@ import org.apache.juneau.urlencoding.*;
  * 	<li><a class="doclink" href="package-summary.html#RestClient">org.apache.juneau.rest.client &gt; REST client API</a> for more information and code examples.
  * </ul>
  */
-public class RestClient extends CoreApi {
-
-	Map<String,Object> headers = new TreeMap<String,Object>(String.CASE_INSENSITIVE_ORDER);
-	volatile CloseableHttpClient httpClient;
-	HttpClientConnectionManager httpClientConnectionManager;
-	Serializer serializer;
-	UrlEncodingSerializer urlEncodingSerializer = new UrlEncodingSerializer();  // Used for form posts only.
-	Parser parser;
-	String accept, contentType;
-	List<RestCallInterceptor> interceptors = new ArrayList<RestCallInterceptor>();
-	String remoteableServletUri;
-	private Map<Method,String> remoteableServiceUriMap = new ConcurrentHashMap<Method,String>();
-	private String rootUrl;
-	private SSLOpts sslOpts;
-	private boolean pooled;
+public class RestClient extends CoreObject {
+
+	private final Map<String,String> headers;
+	private final CloseableHttpClient httpClient;
+	private final boolean keepHttpClientOpen;
+	private final Serializer serializer;
+	private final UrlEncodingSerializer urlEncodingSerializer;  // Used for form posts only.
+	private final Parser parser;
+	private final RestCallInterceptor[] interceptors;
+	private final String remoteableServletUri;
+	private final Map<Method,String> remoteableServiceUriMap;
+	private final String rootUrl;
 	private volatile boolean isClosed = false;
-	private StackTraceElement[] creationStack;
-
-	/**
-	 * The {@link HttpClientBuilder} returned by {@link #createHttpClientBuilder()}.
-	 */
-	protected HttpClientBuilder httpClientBuilder;
-
-	/**
-	 * Create a new client with no serializer, parser, or HTTP client.
-	 * <p>
-	 * If you do not specify an {@link HttpClient} via the {@link #setHttpClient(CloseableHttpClient)}, one
-	 * 	will be created using the {@link #createHttpClient()} method.
-	 */
-	public RestClient() {
-		httpClientBuilder = createHttpClientBuilder();
-		if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackCreation"))
-			creationStack = Thread.currentThread().getStackTrace();
-	}
-
-	/**
-	 * Create a new client with the specified HTTP client.
-	 * <p>
-	 * Equivalent to calling the following:
-	 * <p class='bcode'>
-	 * 	RestClient rc = <jk>new</jk> RestClient().setHttpClient(httpClient);
-	 * </p>
-	 *
-	 * @param httpClient The HTTP client to use for communicating with remote server.
-	 */
-	public RestClient(CloseableHttpClient httpClient) {
-		this();
-		setHttpClient(httpClient);
-	}
-
-	/**
-	 * Create a new client with the specified serializer and parser instances.
-	 * <p>
-	 * Equivalent to calling the following:
-	 * <p class='bcode'>
-	 * 	RestClient rc = <jk>new</jk> RestClient().setSerializer(s).setParser(p);
-	 * </p>
-	 * <p>
-	 * If you do not specify an {@link HttpClient} via the {@link #setHttpClient(CloseableHttpClient)}, one
-	 * 	will be created using the {@link #createHttpClient()} method.
-	 *
-	 * @param s The serializer for converting POJOs to HTTP request message body text.
-	 * @param p The parser for converting HTTP response message body text to POJOs.
-	 */
-	public RestClient(Serializer s, Parser p) {
-		this();
-		setSerializer(s);
-		setParser(p);
-	}
-
-	/**
-	 * Create a new client with the specified serializer and parser instances.
-	 * <p>
-	 * Equivalent to calling the following:
-	 * <p class='bcode'>
-	 * 	RestClient rc = <jk>new</jk> RestClient().setHttpClient(httpClient).setSerializer(s).setParser(p);
-	 * </p>
-	 *
-	 * @param httpClient The HTTP client to use for communicating with remote server.
-	 * @param s The serializer for converting POJOs to HTTP request message body text.
-	 * @param p The parser for converting HTTP response message body text to POJOs.
-	 */
-	public RestClient(CloseableHttpClient httpClient, Serializer s, Parser p) {
-		this();
-		setHttpClient(httpClient);
-		setSerializer(s);
-		setParser(p);
-	}
-
-	/**
-	 * Create a new client with the specified serializer and parser classes.
-	 * <p>
-	 * Equivalent to calling the following:
-	 * <p class='bcode'>
-	 * 	RestClient rc = <jk>new</jk> RestClient().setSerializer(s).setParser(p);
-	 * </p>
-	 * <p>
-	 * If you do not specify an {@link HttpClient} via the {@link #setHttpClient(CloseableHttpClient)}, one
-	 * 	will be created using the {@link #createHttpClient()} method.
-	 *
-	 * @param s The serializer for converting POJOs to HTTP request message body text.
-	 * @param p The parser for converting HTTP response message body text to POJOs.
-	 * @throws InstantiationException If serializer or parser could not be instantiated.
-	 */
-	public RestClient(Class<? extends Serializer> s, Class<? extends Parser> p) throws InstantiationException {
-		this();
-		setSerializer(s);
-		setParser(p);
-	}
-
-	/**
-	 * Create a new client with the specified serializer and parser classes.
-	 * <p>
-	 * Equivalent to calling the following:
-	 * <p class='bcode'>
-	 * 	RestClient rc = <jk>new</jk> RestClient().setHttpClient(httpClient).setSerializer(s).setParser(p);
-	 * </p>
-	 *
-	 * @param httpClient The HTTP client to use for communicating with remote server.
-	 * @param s The serializer for converting POJOs to HTTP request message body text.
-	 * @param p The parser for converting HTTP response message body text to POJOs.
-	 * @throws InstantiationException If serializer or parser could not be instantiated.
-	 */
-	public RestClient(CloseableHttpClient httpClient, Class<? extends Serializer> s, Class<? extends Parser> p) throws InstantiationException {
-		this();
-		setHttpClient(httpClient);
-		setSerializer(s);
-		setParser(p);
-	}
-
-	/**
-	 * Creates an instance of an {@link HttpClient} to be used to handle all HTTP communications with the target server.
-	 * <p>
-	 * This HTTP client is used when the HTTP client is not specified through one of the constructors or the
-	 * 	{@link #setHttpClient(CloseableHttpClient)} method.
-	 * <p>
-	 * Subclasses can override this method to provide specially-configured HTTP clients to handle
-	 * 	stuff such as SSL/TLS certificate handling, authentication, etc.
-	 * <p>
-	 * The default implementation returns an instance of {@link HttpClient} using the client builder
-	 * 	returned by {@link #createHttpClientBuilder()}.
-	 *
-	 * @return The HTTP client to use.
-	 * @throws Exception
-	 */
-	protected CloseableHttpClient createHttpClient() throws Exception {
-		// Don't call createConnectionManager() if RestClient.setConnectionManager() was called.
-		if (httpClientConnectionManager == null)
-			httpClientBuilder.setConnectionManager(createConnectionManager());
-		return httpClientBuilder.build();
-	}
-
-	/**
-	 * Creates an instance of an {@link HttpClientBuilder} to be used to create
-	 * 	the {@link HttpClient}.
-	 * <p>
-	 * Subclasses can override this method to provide their own client builder.
-	 * <p>
-	 * The predefined method returns an {@link HttpClientBuilder} with the following settings:
-	 * <ul>
-	 * 	<li>Lax redirect strategy.
-	 * 	<li>The connection manager returned by {@link #createConnectionManager()}.
-	 * </ul>
-	 *
-	 * @return The HTTP client builder to use to create the HTTP client.
-	 */
-	protected HttpClientBuilder createHttpClientBuilder() {
-		HttpClientBuilder b = HttpClientBuilder.create();
-		b.setRedirectStrategy(new AllowAllRedirects());
-		return b;
-	}
-
-	/**
-	 * Creates the {@link HttpClientConnectionManager} returned by {@link #createConnectionManager()}.
-	 * <p>
-	 * Subclasses can override this method to provide their own connection manager.
-	 * <p>
-	 * The default implementation returns an instance of a {@link PoolingHttpClientConnectionManager}.
-	 *
-	 * @return The HTTP client builder to use to create the HTTP client.
-	 */
-	protected HttpClientConnectionManager createConnectionManager() {
-		if (sslOpts != null) {
-			HostnameVerifier hv = null;
-			switch (sslOpts.getHostVerify()) {
-				case LAX: hv = new NoopHostnameVerifier(); break;
-				case DEFAULT: hv = new DefaultHostnameVerifier(); break;
-			}
-
-			for (String p : StringUtils.split(sslOpts.getProtocols(), ',')) {
-				try {
-					TrustManager tm = new SimpleX509TrustManager(sslOpts.getCertValidate() == SSLOpts.CertValidate.LAX);
-
-					SSLContext ctx = SSLContext.getInstance(p);
-					ctx.init(null, new TrustManager[] { tm }, null);
-
-					// Create a socket to ensure this algorithm is acceptable.
-					// This will correctly disallow certain configurations (such as SSL_TLS under FIPS)
-					ctx.getSocketFactory().createSocket().close();
-					SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(ctx, hv);
-					setSSLSocketFactory(sf);
-
-					Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sf).build();
-
-					return (pooled ? new PoolingHttpClientConnectionManager(r) : new BasicHttpClientConnectionManager(r));
-				} catch (Throwable t) {}
-			}
-		}
+	private final StackTraceElement[] creationStack;
+	private StackTraceElement[] closedStack;
+	final RetryOn retryOn;
+	final int retries;
+	final long retryInterval;
+
+	/**
+	 * Create a new REST client.
+	 * @param propertyStore
+	 * @param httpClient
+	 * @param keepHttpClientOpen
+	 * @param serializer
+	 * @param parser
+	 * @param urlEncodingSerializer
+	 * @param headers
+	 * @param interceptors
+	 * @param remoteableServletUri
+	 * @param remoteableServiceUriMap
+	 * @param rootUri
+	 * @param retryOn
+	 * @param retries
+	 * @param retryInterval
+	 */
+	public RestClient(
+			PropertyStore propertyStore,
+			CloseableHttpClient httpClient,
+			boolean keepHttpClientOpen,
+			Serializer serializer,
+			Parser parser,
+			UrlEncodingSerializer urlEncodingSerializer,
+			Map<String,String> headers,
+			List<RestCallInterceptor> interceptors,
+			String remoteableServletUri,
+			Map<Method,String> remoteableServiceUriMap,
+			String rootUri,
+			RetryOn retryOn,
+			int retries,
+			long retryInterval) {
+		super(propertyStore);
+		this.httpClient = httpClient;
+		this.keepHttpClientOpen = keepHttpClientOpen;
+		this.serializer = serializer;
+		this.parser = parser;
+		this.urlEncodingSerializer = urlEncodingSerializer;
 
-			// Using pooling connection so that this client is threadsafe.
-		return (pooled ? new PoolingHttpClientConnectionManager() : new BasicHttpClientConnectionManager());
-	}
+		Map<String,String> h2 = new ConcurrentHashMap<String,String>(headers);
 
-	/**
-	 * Set up this client to use BASIC auth.
-	 *
-	 * @param host The auth scope hostname.
-	 * @param port The auth scope port.
-	 * @param user The username.
-	 * @param pw The password.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setBasicAuth(String host, int port, String user, String pw) {
-		AuthScope scope = new AuthScope(host, port);
-		Credentials up = new UsernamePasswordCredentials(user, pw);
-		CredentialsProvider p = new BasicCredentialsProvider();
-		p.setCredentials(scope, up);
-		setDefaultCredentialsProvider(p);
-		return this;
-	}
+		this.headers = Collections.unmodifiableMap(h2);
+		this.interceptors = interceptors.toArray(new RestCallInterceptor[interceptors.size()]);
+		this.remoteableServletUri = remoteableServletUri;
+		this.remoteableServiceUriMap = new ConcurrentHashMap<Method,String>(remoteableServiceUriMap);
+		this.rootUrl = rootUri;
+		this.retryOn = retryOn;
+		this.retries = retries;
+		this.retryInterval = retryInterval;
 
-	/**
-	 * When called, the {@link #createConnectionManager()} method will return a {@link PoolingHttpClientConnectionManager}
-	 * 	instead of a {@link BasicHttpClientConnectionManager}.
-	 *
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setPooled() {
-		this.pooled = true;
-		return this;
+		if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
+			creationStack = Thread.currentThread().getStackTrace();
+		else
+			creationStack = null;
 	}
 
 	/**
@@ -318,8 +133,10 @@ public class RestClient extends CoreApi {
 	 */
 	public void close() throws IOException {
 		isClosed = true;
-		if (httpClient != null)
+		if (httpClient != null && ! keepHttpClientOpen)
 			httpClient.close();
+		if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
+			closedStack = Thread.currentThread().getStackTrace();
 	}
 
 	/**
@@ -328,120 +145,11 @@ public class RestClient extends CoreApi {
 	public void closeQuietly() {
 		isClosed = true;
 		try {
-			if (httpClient != null)
+			if (httpClient != null && ! keepHttpClientOpen)
 				httpClient.close();
 		} catch (Throwable t) {}
-	}
-
-	/**
-	 * Specifies a request header property to add to all requests created by this client.
-	 *
-	 * @param name The HTTP header name.
-	 * @param value The HTTP header value.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setHeader(String name, Object value) {
-		this.headers.put(name, value);
-		return this;
-	}
-
-	/**
-	 * Sets the serializer used for serializing POJOs to the HTTP request message body.
-	 *
-	 * @param serializer The serializer.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setSerializer(Serializer serializer) {
-		this.serializer = serializer;
-		return this;
-	}
-
-	/**
-	 * Same as {@link #setSerializer(Serializer)}, except takes in a serializer class that
-	 * 	will be instantiated through a no-arg constructor.
-	 *
-	 * @param c The serializer class.
-	 * @return This object (for method chaining).
-	 * @throws InstantiationException If serializer could not be instantiated.
-	 */
-	public RestClient setSerializer(Class<? extends Serializer> c) throws InstantiationException {
-		try {
-			return setSerializer(c.newInstance());
-		} catch (IllegalAccessException e) {
-			throw new InstantiationException(e.getLocalizedMessage());
-		}
-	}
-
-	/**
-	 * Sets the parser used for parsing POJOs from the HTTP response message body.
-	 *
-	 * @param parser The parser.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setParser(Parser parser) {
-		this.parser = parser;
-		this.accept = StringUtils.toString(parser.getPrimaryMediaType());
-		return this;
-	}
-
-	/**
-	 * Same as {@link #setParser(Parser)}, except takes in a parser class that
-	 * 	will be instantiated through a no-arg constructor.
-	 *
-	 * @param c The parser class.
-	 * @return This object (for method chaining).
-	 * @throws InstantiationException If parser could not be instantiated.
-	 */
-	public RestClient setParser(Class<? extends Parser> c) throws InstantiationException {
-		try {
-			return setParser(c.newInstance());
-		} catch (IllegalAccessException e) {
-			throw new InstantiationException(e.getLocalizedMessage());
-		}
-	}
-
-	/**
-	 * Sets the internal {@link HttpClient} to use for handling HTTP communications.
-	 *
-	 * @param httpClient The HTTP client.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setHttpClient(CloseableHttpClient httpClient) {
-		this.httpClient = httpClient;
-		return this;
-	}
-
-	/**
-	 * Sets the client version by setting the value for the <js>"X-Client-Version"</js> header.
-	 *
-	 * @param version The version string (e.g. <js>"1.2.3"</js>)
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setClientVersion(String version) {
-		return setHeader("X-Client-Version", version);
-	}
-
-	/**
-	 * Adds an interceptor that gets called immediately after a connection is made.
-	 *
-	 * @param interceptor The interceptor.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient addInterceptor(RestCallInterceptor interceptor) {
-		interceptors.add(interceptor);
-		return this;
-	}
-
-	/**
-	 * Adds a {@link RestCallLogger} to the list of interceptors on this class.
-	 *
-	 * @param level The log level to log messsages at.
-	 * @param log The logger to log messages to.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient logTo(Level level, Logger log) {
-		addInterceptor(new RestCallLogger(level, log));
-		return this;
+		if (Boolean.getBoolean("org.apache.juneau.rest.client.RestClient.trackLifecycle"))
+			closedStack = Thread.currentThread().getStackTrace();
 	}
 
 	/**
@@ -463,15 +171,12 @@ public class RestClient extends CoreApi {
 	}
 
 	/**
-	 * Returns the {@link HttpClient} currently associated with this client.
+	 * Returns the list of interceptors on this client.
 	 *
-	 * @return The HTTP client currently associated with this client.
-	 * @throws Exception
+	 * @return The list of interceptors on this client.
 	 */
-	public HttpClient getHttpClient() throws Exception {
-		if (httpClient == null)
-			httpClient = createHttpClient();
-		return httpClient;
+	public RestCallInterceptor[] getInterceptors() {
+		return interceptors;
 	}
 
 	/**
@@ -483,91 +188,7 @@ public class RestClient extends CoreApi {
 	 * @throws Exception
 	 */
 	protected HttpResponse execute(HttpUriRequest req) throws Exception {
-		return getHttpClient().execute(req);
-	}
-
-	/**
-	 * Sets the value for the <code>Accept</code> request header.
-	 * <p>
-	 * This overrides the media type specified on the parser, but is overridden by calling <code>setHeader(<js>"Accept"</js>, newvalue);</code>
-	 *
-	 * @param accept The new header value.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setAccept(String accept) {
-		this.accept = accept;
-		return this;
-	}
-
-	/**
-	 * Sets the value for the <code>Content-Type</code> request header.
-	 * <p>
-	 * This overrides the media type specified on the serializer, but is overridden by calling <code>setHeader(<js>"Content-Type"</js>, newvalue);</code>
-	 *
-	 * @param contentType The new header value.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setContentType(String contentType) {
-		this.contentType = contentType;
-		return this;
-	}
-
-	/**
-	 * Sets the URI of the remoteable services REST servlet for invoking remoteable services.
-	 *
-	 * @param remoteableServletUri The URI of the REST resource implementing a remoteable services servlet.
-	 * 	(typically an instance of <code>RemoteableServlet</code>).
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setRemoteableServletUri(String remoteableServletUri) {
-		this.remoteableServletUri = remoteableServletUri;
-		return this;
-	}
-
-	/**
-	 * Set a root URL for this client.
-	 * <p>
-	 * When set, URL strings passed in through the various rest call methods (e.g. {@link #doGet(Object)}
-	 * 	will be prefixed with the specified root.
-	 * This root URL is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URL string.
-	 *
-	 * @param rootUrl The root URL to prefix to relative URL strings.  Trailing slashes are trimmed.
-	 * Usually a <code>String<code> but you can also pass in <code>URI</code> and <code>URL</code> objects as well.
-	 * @return This object (for method chaining).
-	 */
-	public RestClient setRootUrl(Object rootUrl) {
-		String s = rootUrl.toString();
-		if (s.endsWith("/"))
-			s = s.replaceAll("\\/$", "");
-		this.rootUrl = s;
-		return this;
-	}
-
-	/**
-	 * Enable SSL support on this client.
-	 *
-	 * @param opts The SSL configuration options.  See {@link SSLOpts} for details.
-	 * This method is a no-op if <code>sslConfig</code> is <jk>null</jk>.
-	 * @return This object (for method chaining).
-	 * @throws KeyStoreException
-	 * @throws NoSuchAlgorithmException
-	 */
-	public RestClient enableSSL(SSLOpts opts) throws KeyStoreException, NoSuchAlgorithmException {
-		this.sslOpts = opts;
-		return this;
-	}
-
-	/**
-	 * Enable LAX SSL support.
-	 * <p>
-	 * Certificate chain validation and hostname verification is disabled.
-	 *
-	 * @return This object (for method chaining).
-	 * @throws KeyStoreException
-	 * @throws NoSuchAlgorithmException
-	 */
-	public RestClient enableLaxSSL() throws KeyStoreException, NoSuchAlgorithmException {
-		return enableSSL(SSLOpts.LAX);
+		return httpClient.execute(req);
 	}
 
 	/**
@@ -599,7 +220,7 @@ public class RestClient extends CoreApi {
 	 * @throws RestCallException If any authentication errors occurred.
 	 */
 	public RestCall doPut(Object url, Object o) throws RestCallException {
-		return doCall("PUT", url, true).setInput(o);
+		return doCall("PUT", url, true).input(o);
 	}
 
 	/**
@@ -619,7 +240,7 @@ public class RestClient extends CoreApi {
 	 * @throws RestCallException If any authentication errors occurred.
 	 */
 	public RestCall doPost(Object url, Object o) throws RestCallException {
-		return doCall("POST", url, true).setInput(o);
+		return doCall("POST", url, true).input(o);
 	}
 
 	/**
@@ -658,7 +279,7 @@ public class RestClient extends CoreApi {
 	 */
 	public RestCall doFormPost(Object url, Object o) throws RestCallException {
 		return doCall("POST", url, true)
-			.setInput(o instanceof HttpEntity ? o : new RestRequestEntity(o, urlEncodingSerializer));
+			.input(o instanceof HttpEntity ? o : new RestRequestEntity(o, urlEncodingSerializer));
 	}
 
 	/**
@@ -716,10 +337,10 @@ public class RestClient extends CoreApi {
 			if (method != null && uri != null) {
 				rc = doCall(method, uri, content != null);
 				if (content != null)
-					rc.setInput(new StringEntity(content));
+					rc.input(new StringEntity(content));
 				if (h != null)
 					for (Map.Entry<String,Object> e : h.entrySet())
-						rc.setHeader(e.getKey(), e.getValue());
+						rc.header(e.getKey(), e.getValue());
 				return rc;
 			}
 		} catch (Exception e) {
@@ -749,7 +370,7 @@ public class RestClient extends CoreApi {
 	public RestCall doCall(HttpMethod method, Object url, Object content) throws RestCallException {
 		RestCall rc = doCall(method.name(), url, method.hasContent());
 		if (method.hasContent())
-			rc.setInput(content);
+			rc.input(content);
 		return rc;
 	}
 
@@ -764,6 +385,16 @@ public class RestClient extends CoreApi {
 	 * @throws RestCallException If any authentication errors occurred.
 	 */
 	public RestCall doCall(String method, Object url, boolean hasContent) throws RestCallException {
+		if (isClosed) {
+			Exception e2 = null;
+			if (closedStack != null) {
+				e2 = new Exception("Creation stack:");
+				e2.setStackTrace(closedStack);
+				throw new RestCallException("RestClient.close() has already been called.  This client cannot be reused.").initCause(e2);
+			}
+			throw new RestCallException("RestClient.close() has already been called.  This client cannot be reused.  Closed location stack trace can be displayed by setting the system property 'org.apache.juneau.rest.client.RestClient.trackCreation' to true.");
+		}
+
 		HttpRequestBase req = null;
 		RestCall restCall = null;
 		final String methodUC = method.toUpperCase(Locale.ENGLISH);
@@ -775,8 +406,6 @@ public class RestClient extends CoreApi {
 				}
 			};
 			restCall = new RestCall(this, req);
-			if (contentType != null)
-				restCall.setHeader("Content-Type", contentType);
 		} else {
 			req = new HttpRequestBase() {
 				@Override /* HttpRequest */
@@ -791,10 +420,12 @@ public class RestClient extends CoreApi {
 		} catch (URISyntaxException e) {
 			throw new RestCallException(e);
 		}
-		if (accept != null)
-			restCall.setHeader("Accept", accept);
 		for (Map.Entry<String,? extends Object> e : headers.entrySet())
-			restCall.setHeader(e.getKey(), e.getValue());
+			restCall.header(e.getKey(), e.getValue());
+
+		if (parser != null && ! req.containsHeader("Accept"))
+			req.setHeader("Accept", parser.getPrimaryMediaType().toString());
+
 		return restCall;
 	}
 
@@ -804,7 +435,7 @@ public class RestClient extends CoreApi {
 	 * @param interfaceClass The interface to create a proxy for.
 	 * @return The new proxy interface.
 	 * @throws RuntimeException If the Remotable service URI has not been specified on this
-	 * 	client by calling {@link #setRemoteableServletUri(String)}.
+	 * 	client by calling {@link RestClientBuilder#remoteableServletUri(String)}.
 	 */
 	@SuppressWarnings("unchecked")
 	public <T> T getRemoteableProxy(final Class<T> interfaceClass) {
@@ -854,587 +485,16 @@ public class RestClient extends CoreApi {
 		return new URI(s);
 	}
 
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreAPI */
-	public RestClient setProperty(String property, Object value) throws LockedException {
-		super.setProperty(property, value);
-		if (serializer != null)
-			serializer.setProperty(property, value);
-		if (parser != null)
-			parser.setProperty(property, value);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.setProperty(property, value);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		if (serializer != null)
-			serializer.setProperties(properties);
-		if (parser != null)
-			parser.setProperties(properties);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient addNotBeanClasses(Class<?>...classes) throws LockedException {
-		super.addNotBeanClasses(classes);
-		if (serializer != null)
-			serializer.addNotBeanClasses(classes);
-		if (parser != null)
-			parser.addNotBeanClasses(classes);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.addNotBeanClasses(classes);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient addBeanFilters(Class<?>...classes) throws LockedException {
-		super.addBeanFilters(classes);
-		if (serializer != null)
-			serializer.addBeanFilters(classes);
-		if (parser != null)
-			parser.addBeanFilters(classes);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.addBeanFilters(classes);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient addPojoSwaps(Class<?>...classes) throws LockedException {
-		super.addPojoSwaps(classes);
-		if (serializer != null)
-			serializer.addPojoSwaps(classes);
-		if (parser != null)
-			parser.addPojoSwaps(classes);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.addPojoSwaps(classes);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient addToBeanDictionary(Class<?>...classes) throws LockedException {
-		super.addToBeanDictionary(classes);
-		if (serializer != null)
-			serializer.addToBeanDictionary(classes);
-		if (parser != null)
-			parser.addToBeanDictionary(classes);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.addToBeanDictionary(classes);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public <T> RestClient addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		if (serializer != null)
-			serializer.addImplClass(interfaceClass, implClass);
-		if (parser != null)
-			parser.addImplClass(interfaceClass, implClass);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreAPI */
-	public RestClient setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		if (serializer != null)
-			serializer.setClassLoader(classLoader);
-		if (parser != null)
-			parser.setClassLoader(classLoader);
-		if (urlEncodingSerializer != null)
-			urlEncodingSerializer.setClassLoader(classLoader);
-		return this;
-	}
-
-
-	//------------------------------------------------------------------------------------------------
-	// Passthrough methods for HttpClientBuilder.
-	//------------------------------------------------------------------------------------------------
-
-	/**
-	 * @param redirectStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setRedirectStrategy(RedirectStrategy)
-	 */
-	public RestClient setRedirectStrategy(RedirectStrategy redirectStrategy) {
-		httpClientBuilder.setRedirectStrategy(redirectStrategy);
-		return this;
-	}
-
-	/**
-	 * @param cookieSpecRegistry
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultCookieSpecRegistry(Lookup)
-	 */
-	public RestClient setDefaultCookieSpecRegistry(Lookup<CookieSpecProvider> cookieSpecRegistry) {
-		httpClientBuilder.setDefaultCookieSpecRegistry(cookieSpecRegistry);
-		return this;
-	}
-
-	/**
-	 * @param requestExec
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setRequestExecutor(HttpRequestExecutor)
-	 */
-	public RestClient setRequestExecutor(HttpRequestExecutor requestExec) {
-		httpClientBuilder.setRequestExecutor(requestExec);
-		return this;
-	}
-
-	/**
-	 * @param hostnameVerifier
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setSSLHostnameVerifier(HostnameVerifier)
-	 */
-	public RestClient setSSLHostnameVerifier(HostnameVerifier hostnameVerifier) {
-		httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
-		return this;
-	}
-
-	/**
-	 * @param publicSuffixMatcher
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setPublicSuffixMatcher(PublicSuffixMatcher)
-	 */
-	public RestClient setPublicSuffixMatcher(PublicSuffixMatcher publicSuffixMatcher) {
-		httpClientBuilder.setPublicSuffixMatcher(publicSuffixMatcher);
-		return this;
-	}
-
-	/**
-	 * @param sslContext
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setSSLContext(SSLContext)
-	 */
-	public RestClient setSSLContext(SSLContext sslContext) {
-		httpClientBuilder.setSSLContext(sslContext);
-		return this;
-	}
-
-	/**
-	 * @param sslSocketFactory
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setSSLSocketFactory(LayeredConnectionSocketFactory)
-	 */
-	public RestClient setSSLSocketFactory(LayeredConnectionSocketFactory sslSocketFactory) {
-		httpClientBuilder.setSSLSocketFactory(sslSocketFactory);
-		return this;
-	}
-
-	/**
-	 * @param maxConnTotal
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setMaxConnTotal(int)
-	 */
-	public RestClient setMaxConnTotal(int maxConnTotal) {
-		httpClientBuilder.setMaxConnTotal(maxConnTotal);
-		return this;
-	}
-
-	/**
-	 * @param maxConnPerRoute
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setMaxConnPerRoute(int)
-	 */
-	public RestClient setMaxConnPerRoute(int maxConnPerRoute) {
-		httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
-		return this;
-	}
-
-	/**
-	 * @param config
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultSocketConfig(SocketConfig)
-	 */
-	public RestClient setDefaultSocketConfig(SocketConfig config) {
-		httpClientBuilder.setDefaultSocketConfig(config);
-		return this;
-	}
-
-	/**
-	 * @param config
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultConnectionConfig(ConnectionConfig)
-	 */
-	public RestClient setDefaultConnectionConfig(ConnectionConfig config) {
-		httpClientBuilder.setDefaultConnectionConfig(config);
-		return this;
-	}
-
-	/**
-	 * @param connTimeToLive
-	 * @param connTimeToLiveTimeUnit
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setConnectionTimeToLive(long,TimeUnit)
-	 */
-	public RestClient setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
-		httpClientBuilder.setConnectionTimeToLive(connTimeToLive, connTimeToLiveTimeUnit);
-		return this;
-	}
-
-	/**
-	 * @param connManager
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setConnectionManager(HttpClientConnectionManager)
-	 */
-	public RestClient setConnectionManager(HttpClientConnectionManager connManager) {
-		this.httpClientConnectionManager = connManager;
-		httpClientBuilder.setConnectionManager(connManager);
-		return this;
-	}
-
-	/**
-	 * @param shared
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setConnectionManagerShared(boolean)
-	 */
-	public RestClient setConnectionManagerShared(boolean shared) {
-		httpClientBuilder.setConnectionManagerShared(shared);
-		return this;
-	}
-
-	/**
-	 * @param reuseStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setConnectionReuseStrategy(ConnectionReuseStrategy)
-	 */
-	public RestClient setConnectionReuseStrategy(ConnectionReuseStrategy reuseStrategy) {
-		httpClientBuilder.setConnectionReuseStrategy(reuseStrategy);
-		return this;
-	}
-
-	/**
-	 * @param keepAliveStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setKeepAliveStrategy(ConnectionKeepAliveStrategy)
-	 */
-	public RestClient setKeepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy) {
-		httpClientBuilder.setKeepAliveStrategy(keepAliveStrategy);
-		return this;
-	}
-
-	/**
-	 * @param targetAuthStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setTargetAuthenticationStrategy(AuthenticationStrategy)
-	 */
-	public RestClient setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
-		httpClientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
-		return this;
-	}
-
-	/**
-	 * @param proxyAuthStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setProxyAuthenticationStrategy(AuthenticationStrategy)
-	 */
-	public RestClient setProxyAuthenticationStrategy(AuthenticationStrategy proxyAuthStrategy) {
-		httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthStrategy);
-		return this;
-	}
-
-	/**
-	 * @param userTokenHandler
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setUserTokenHandler(UserTokenHandler)
-	 */
-	public RestClient setUserTokenHandler(UserTokenHandler userTokenHandler) {
-		httpClientBuilder.setUserTokenHandler(userTokenHandler);
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableConnectionState()
-	 */
-	public RestClient disableConnectionState() {
-		httpClientBuilder.disableConnectionState();
-		return this;
-	}
-
-	/**
-	 * @param schemePortResolver
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setSchemePortResolver(SchemePortResolver)
-	 */
-	public RestClient setSchemePortResolver(SchemePortResolver schemePortResolver) {
-		httpClientBuilder.setSchemePortResolver(schemePortResolver);
-		return this;
-	}
-
-	/**
-	 * @param userAgent
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setUserAgent(String)
-	 */
-	public RestClient setUserAgent(String userAgent) {
-		httpClientBuilder.setUserAgent(userAgent);
-		return this;
-	}
-
-	/**
-	 * @param defaultHeaders
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultHeaders(Collection)
-	 */
-	public RestClient setDefaultHeaders(Collection<? extends Header> defaultHeaders) {
-		httpClientBuilder.setDefaultHeaders(defaultHeaders);
-		return this;
-	}
-
-	/**
-	 * @param itcp
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#addInterceptorFirst(HttpResponseInterceptor)
-	 */
-	public RestClient addInterceptorFirst(HttpResponseInterceptor itcp) {
-		httpClientBuilder.addInterceptorFirst(itcp);
-		return this;
-	}
-
-	/**
-	 * @param itcp
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#addInterceptorLast(HttpResponseInterceptor)
-	 */
-	public RestClient addInterceptorLast(HttpResponseInterceptor itcp) {
-		httpClientBuilder.addInterceptorLast(itcp);
-		return this;
-	}
-
-	/**
-	 * @param itcp
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#addInterceptorFirst(HttpRequestInterceptor)
-	 */
-	public RestClient addInterceptorFirst(HttpRequestInterceptor itcp) {
-		httpClientBuilder.addInterceptorFirst(itcp);
-		return this;
-	}
-
-	/**
-	 * @param itcp
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#addInterceptorLast(HttpRequestInterceptor)
-	 */
-	public RestClient addInterceptorLast(HttpRequestInterceptor itcp) {
-		httpClientBuilder.addInterceptorLast(itcp);
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableCookieManagement()
-	 */
-	public RestClient disableCookieManagement() {
-		httpClientBuilder.disableCookieManagement();
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableContentCompression()
-	 */
-	public RestClient disableContentCompression() {
-		httpClientBuilder.disableContentCompression();
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableAuthCaching()
-	 */
-	public RestClient disableAuthCaching() {
-		httpClientBuilder.disableAuthCaching();
-		return this;
-	}
-
-	/**
-	 * @param httpprocessor
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setHttpProcessor(HttpProcessor)
-	 */
-	public RestClient setHttpProcessor(HttpProcessor httpprocessor) {
-		httpClientBuilder.setHttpProcessor(httpprocessor);
-		return this;
-	}
-
-	/**
-	 * @param retryHandler
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setRetryHandler(HttpRequestRetryHandler)
-	 */
-	public RestClient setRetryHandler(HttpRequestRetryHandler retryHandler) {
-		httpClientBuilder.setRetryHandler(retryHandler);
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableAutomaticRetries()
-	 */
-	public RestClient disableAutomaticRetries() {
-		httpClientBuilder.disableAutomaticRetries();
-		return this;
-	}
-
-	/**
-	 * @param proxy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setProxy(HttpHost)
-	 */
-	public RestClient setProxy(HttpHost proxy) {
-		httpClientBuilder.setProxy(proxy);
-		return this;
-	}
-
-	/**
-	 * @param routePlanner
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setRoutePlanner(HttpRoutePlanner)
-	 */
-	public RestClient setRoutePlanner(HttpRoutePlanner routePlanner) {
-		httpClientBuilder.setRoutePlanner(routePlanner);
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#disableRedirectHandling()
-	 */
-	public RestClient disableRedirectHandling() {
-		httpClientBuilder.disableRedirectHandling();
-		return this;
-	}
-
-	/**
-	 * @param connectionBackoffStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setConnectionBackoffStrategy(ConnectionBackoffStrategy)
-	 */
-	public RestClient setConnectionBackoffStrategy(ConnectionBackoffStrategy connectionBackoffStrategy) {
-		httpClientBuilder.setConnectionBackoffStrategy(connectionBackoffStrategy);
-		return this;
-	}
-
-	/**
-	 * @param backoffManager
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setBackoffManager(BackoffManager)
-	 */
-	public RestClient setBackoffManager(BackoffManager backoffManager) {
-		httpClientBuilder.setBackoffManager(backoffManager);
-		return this;
-	}
-
-	/**
-	 * @param serviceUnavailStrategy
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)
-	 */
-	public RestClient setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy serviceUnavailStrategy) {
-		httpClientBuilder.setServiceUnavailableRetryStrategy(serviceUnavailStrategy);
-		return this;
-	}
-
-	/**
-	 * @param cookieStore
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultCookieStore(CookieStore)
-	 */
-	public RestClient setDefaultCookieStore(CookieStore cookieStore) {
-		httpClientBuilder.setDefaultCookieStore(cookieStore);
-		return this;
-	}
-
-	/**
-	 * @param credentialsProvider
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultCredentialsProvider(CredentialsProvider)
-	 */
-	public RestClient setDefaultCredentialsProvider(CredentialsProvider credentialsProvider) {
-		httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
-		return this;
-	}
-
-	/**
-	 * @param authSchemeRegistry
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultAuthSchemeRegistry(Lookup)
-	 */
-	public RestClient setDefaultAuthSchemeRegistry(Lookup<AuthSchemeProvider> authSchemeRegistry) {
-		httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
-		return this;
-	}
-
-	/**
-	 * @param contentDecoderMap
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setContentDecoderRegistry(Map)
-	 */
-	public RestClient setContentDecoderRegistry(Map<String,InputStreamFactory> contentDecoderMap) {
-		httpClientBuilder.setContentDecoderRegistry(contentDecoderMap);
-		return this;
-	}
-
-	/**
-	 * @param config
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#setDefaultRequestConfig(RequestConfig)
-	 */
-	public RestClient setDefaultRequestConfig(RequestConfig config) {
-		httpClientBuilder.setDefaultRequestConfig(config);
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#useSystemProperties()
-	 */
-	public RestClient useSystemProperties() {
-		httpClientBuilder.useSystemProperties();
-		return this;
-	}
-
-	/**
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#evictExpiredConnections()
-	 */
-	public RestClient evictExpiredConnections() {
-		httpClientBuilder.evictExpiredConnections();
-		return this;
-	}
-
-	/**
-	 * @param maxIdleTime
-	 * @param maxIdleTimeUnit
-	 * @return This object (for method chaining).
-	 * @see HttpClientBuilder#evictIdleConnections(long,TimeUnit)
-	 */
-	public RestClient evictIdleConnections(long maxIdleTime, TimeUnit maxIdleTimeUnit) {
-		httpClientBuilder.evictIdleConnections(maxIdleTime, maxIdleTimeUnit);
-		return this;
-	}
-
 	@Override
 	protected void finalize() throws Throwable {
-		if (! isClosed) {
+		if (! isClosed && ! keepHttpClientOpen) {
 			System.err.println("WARNING:  RestClient garbage collected before it was finalized.");
 			if (creationStack != null) {
 				System.err.println("Creation Stack:");
 				for (StackTraceElement e : creationStack)
 					System.err.println(e);
 			} else {
-				System.err.println("Creation stack traces can be displayed by setting the system property 'org.apache.juneau.rest.client.RestClient.trackCreation' to true.");
+				System.err.println("Creation stack traces can be displayed by setting the system property 'org.apache.juneau.rest.client.RestClient.trackLifecycle' to true.");
 			}
 		}
 	}


[11/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/uon/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/uon/package.html b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
new file mode 100644
index 0000000..e6b1d10
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/uon/package.html
@@ -0,0 +1,1339 @@
+<!DOCTYPE HTML>
+<!--
+/***************************************************************************************************************************
+ * 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.
+ *
+ ***************************************************************************************************************************/
+ -->
+<html>
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<style type="text/css">
+		/* For viewing in Page Designer */
+		@IMPORT url("../../../../../../javadoc.css");
+
+		/* For viewing in REST interface */
+		@IMPORT url("../htdocs/javadoc.css");
+		body { 
+			margin: 20px; 
+		}	
+	</style>
+	<script>
+		/* Replace all @code and @link tags. */	
+		window.onload = function() {
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@code ([^\}]+)\}/g, '<code>$1</code>');
+			document.body.innerHTML = document.body.innerHTML.replace(/\{\@link (([^\}]+)\.)?([^\.\}]+)\}/g, '<code>$3</code>');
+		}
+	</script>
+</head>
+<body>
+<p>UON notation serialization and parsing support</p>
+<script>
+	function toggle(x) {
+		var div = x.nextSibling;
+		while (div != null && div.nodeType != 1)
+			div = div.nextSibling;
+		if (div != null) {
+			var d = div.style.display;
+			if (d == 'block' || d == '') {
+				div.style.display = 'none';
+				x.className += " closed";
+			} else {
+				div.style.display = 'block';
+				x.className = x.className.replace(/(?:^|\s)closed(?!\S)/g , '' );
+			}
+		}
+	}
+</script>
+
+<a id='TOC'></a><h5 class='toc'>Table of Contents</h5>
+<ol class='toc'>
+	<li><p><a class='doclink' href='#Overview'>UON support overview</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#OverviewExample'>Example</a></p>
+	</ol>
+	<li><p><a class='doclink' href='#UrlEncodingSerializer'>UrlEncodingSerializer and UonSerializer classes</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#BeanAnnotations'>@Bean and @BeanProperty annotations</a></p>
+		<li><p><a class='doclink' href='#Collections'>Collections</a></p>
+		<li><p><a class='doclink' href='#Recursion'> Non-tree models and recursion detection</a></p>
+		<li><p><a class='doclink' href='#SerializerConfigurableProperties'>Configurable properties</a></p>
+		<li><p><a class='doclink' href='#SerializerOtherNotes'>Other notes</a></p>
+	</ol>
+	<li><p><a class='doclink' href='#UrlEncodingParser'>UrlEncodingParser and UonParser classes</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#GenericParsing'>Parsing into generic POJO models</a></p>
+		<li><p><a class='doclink' href='#ParserConfigurableProperties'>Configurable properties</a></p>
+		<li><p><a class='doclink' href='#ParserOtherNotes'>Other notes</a></p>
+	</ol>
+	<li><p><a class='doclink' href='#RestApiSupport'>REST API support</a></p> 
+	<ol>
+		<li><p><a class='doclink' href='#RestServerSupport'>REST server support</a></p>
+		<ol>
+		<li><p><a class='doclink' href='#RestServletDefault'>Using RestServletDefault</a></p>
+		<li><p><a class='doclink' href='#RestServlet'>Using RestServlet with annotations</a></p>
+		<li><p><a class='doclink' href='#DefaultProvider'>Using JAX-RS DefaultProvider</a></p>
+		<li><p><a class='doclink' href='#BaseProvider'>Using JAX-RS BaseProvider with annotations</a></p>
+		</ol>
+		<li><p><a class='doclink' href='#RestClientSupport'>REST client support</a></p>
+	</ol>	
+</ol>
+
+<!-- ======================================================================================================== -->
+<a id="Overview"></a>
+<h2 class='topic' onclick='toggle(this)'>1 - URL encoding support overview</h2>
+<div class='topic'>
+	<p>
+		Juneau supports converting arbitrary POJOs to and from URL-encoded strings using ultra-efficient serializers and parsers.<br>
+		The serializer converts POJOs directly to URL-encoded strings without the need for intermediate DOM objects using a highly-efficient state machine.<br>
+		Likewise, the parser creates POJOs directly from URL-encoded strings without the need for intermediate DOM objects. 
+	</p>
+	<p>
+		Juneau uses UON (URL-Encoded Object Notation) for representing POJOs.  
+		The UON specification can be found <a href='doc-files/rfc_uon.txt'>here</a>.
+	</p>
+	<p>
+		Juneau can serialize and parse instances of any of the following POJO types:
+	</p>
+	<ul class='spaced-list'>
+		<li>Java primitives and primitive objects (e.g. <code>String</code>, <code>Integer</code>, <code>Boolean</code>, <code>Float</code>).
+		<li>Java Collections Framework objects (e.g. <code>HashSet</code>, <code>TreeMap</code>) containing anything on this list.
+		<li>Multi-dimensional arrays of any type on this list.
+		<li>Java Beans with properties of any type on this list.
+		<li>Classes with standard transformations to and from <code>Strings</code> (e.g. classes containing <code>toString()</code>, <code>fromString()</code>, <code>valueOf()</code>, <code>constructor(String)</code>).
+		<li>Non-serializable classes and properties with associated <code>PojoSwaps</code> that convert them to serializable forms.
+	</ul>
+	<p>
+		Refer to <a href='../../../../overview-summary.html#Core.PojoCategories' class='doclink'>POJO Categories</a> for a complete definition of supported POJOs.
+	</p>
+	<h6 class='topic'>Prerequisites</h6>
+	<p>
+		The Juneau URL-encoding serialization and parsing support does not require any external prerequisites.  
+		It only requires Java 1.6 or above.
+	</p>
+
+	<!-- ======================================================================================================== -->
+	<a id="OverviewExample"></a>
+	<h3 class='topic' onclick='toggle(this)'>1.1 - URL-encoding support overview - example</h3>
+	<div class='topic'>
+		<p>
+			The example shown here is from the Address Book resource located in the <code>org.apache.juneau.sample.war</code> application.<br>
+			The POJO model consists of a <code>List</code> of <code>Person</code> beans, with each <code>Person</code> containing
+				zero or more <code>Address</code> beans.
+		</p>
+		<p>
+			When you point a browser at <code>/sample/addressBook/people/1</code>, the POJO is rendered as HTML:
+		</p>
+		<img class='bordered' src="doc-files/Example_HTML.png">
+		<p>
+			By appending <code>?Accept=application/x-www-form-urlencoded&amp;plainText=true</code> to the URL, you can view the data as a URL-encoded string:
+		</p>
+		<p class='bcode'>
+	<un>0</un>=(
+		<ua>uri</ua>=<us>http://localhost:10000/addressBook/people/1</us>,
+		<ua>addressBookUri</ua>=<us>http://localhost:10000/addressBook/</us>,
+		<ua>id</ua>=<un>1</un>,
+		<ua>name</ua>=<us>'Barack+Obama'</us>,
+		<ua>birthDate</ua>=<us>'Aug+4,+1961'</us>,
+		<ua>addresses</ua>=@(
+			(
+				<ua>uri</ua>=<us>http://localhost:10000/addressBook/addresses/1</us>,
+				<ua>personUri</ua>=<us>http://localhost:10000/addressBook/people/1</us>,
+				<ua>id</ua>=<un>1</un>,
+				<ua>street</ua>=<us>'1600+Pennsylvania+Ave'</us>,
+				<ua>city</ua>=<us>Washington</us>,
+				<ua>state</ua>=<us>DC</us>,
+				<ua>zip</ua>=<un>20500</un>,
+				<ua>isCurrent</ua>=<uk>true</uk>
+			),
+			(
+				<ua>uri</ua>=<us>http://localhost:10000/addressBook/addresses/2</us>,
+				<ua>personUri</ua>=<us>http://localhost:10000/addressBook/people/1</us>,
+				<ua>id</ua>=<un>2</un>,
+				<ua>street</ua>=<us>'5046+S+Greenwood+Ave'</us>,
+				<ua>city</ua>=<us>Chicago</us>,
+				<ua>state</ua>=<us>IL</us>,
+				<ua>zip</ua>=<un>60615</un>,
+				<ua>isCurrent</ua>=<uk>false</uk>
+			)
+		),
+		<ua>age</ua>=<un>56</un>
+	)
+	&amp;<un>1</un>=(
+		<ua>uri</ua>=<us>http://localhost:10000/addressBook/people/2</us>,
+		<ua>addressBookUri</ua>=<us>http://localhost:10000/addressBook/</us>,
+		<ua>id</ua>=<un>2</un>,
+		<ua>name</ua>=<us>'George+Walker+Bush'</us>,
+		<ua>birthDate</ua>=<us>'Jul+6,+1946'</us>,
+		<ua>addresses</ua>=@(
+			(
+				<ua>uri</ua>=<us>http://localhost:10000/addressBook/addresses/3</us>,
+				<ua>personUri</ua>=<us>http://localhost:10000/addressBook/people/2</us>,
+				<ua>id</ua>=<un>3</un>,
+				<ua>street</ua>=<us>'43+Prairie+Chapel+Rd'</us>,
+				<ua>city</ua>=<us>Crawford</us>,
+				<ua>state</ua>=<us>TX</us>,
+				<ua>zip</ua>=<un>76638</un>,
+				<ua>isCurrent</ua>=<uk>true</uk>
+			),
+			(
+				<ua>uri</ua>=<us>http://localhost:10000/addressBook/addresses/4</us>,
+				<ua>personUri</ua>=<us>http://localhost:10000/addressBook/people/2</us>,
+				<ua>id</ua>=<un>4</un>,
+				<ua>street</ua>=<us>'1600+Pennsylvania+Ave'</us>,
+				<ua>city</ua>=<us>Washington</us>,
+				<ua>state</ua>=<us>DC</us>,
+				<ua>zip</ua>=<un><us>20500</un>,
+				<ua>isCurrent</ua>=<uk>false</uk>
+			)
+		),
+		<ua>age</ua>=<un>71</un>
+	)		
+		</p>
+		
+		<p>
+			Juneau supports two kinds of serialization:
+		</p>
+		<ul class='spaced-list'>
+			<li>Construction of full URL query parameter strings (e.g. <code>&amp;key=value</code> pairs) from beans and maps.
+			<li>Construction of URL query parameter value strings (e.g. just the <code>value</code> portion of <code>&amp;key=value</code> pairs) from any POJO.  
+		</ul>
+		<p>
+			Top-level beans and maps can serialized as key/value pairs as shown below:
+		</p>
+		<h6 class='figure'>Example:  A bean with 2 string properties, 'foo' and 'baz', serialized to a query string</h6>
+		<p class='bcode'>	
+	http://localhost/sample?<ua>foo</ua>=<us>bar</us>&amp;<ua>baz</ua>=<us>bing</us>
+		</p>
+		<p>
+			Lower-level beans and maps are also serialized as key/value pairs, but are surrounded with a <js>"(...)"</js> construct to denote an object mapping, 
+				and uses a comma as the parameter delimiter instead of <js>"&amp;"</js>.<br>
+		</p>
+		<h6 class='figure'>Example:  A bean serialized as a query parameter value.</h6>
+		<p class='bcode'>	
+	http://localhost/sample?<ua>a1</ua>=(<ua>foo</ua>=<us>bar</us>,<ua>baz</ua>=<us>bing</us>)
+		</p>
+		
+		<h6 class='figure'>General methodology:</h6>
+		<table class='styled' style='border-collapse: collapse;'>
+			<tr><th>Java type</th><th>JSON equivalent</th><th>UON</th></tr>
+			<tr>
+				<td>Maps/beans</td>
+				<td>OBJECT</td>
+				<td class='code'>
+	<ua>a1</ua>=(<ua>b1</ua>=<us>x1</us>,<ua>b2</ua>=<us>x2</us>)
+	<ua>a1</ua>=(<ua>b1</ua>=(<ua>c1</ua>=<us>x1</us>,<ua>c2</ua>=<us>x2</us>))
+				</td>
+			</tr>
+			<tr>
+				<td>Collections/arrays</td>
+				<td>ARRAY</td>
+				<td class='code'>
+	<ua>a1</ua>=@(<us>x1</us>,<us>x2</us>)
+	<ua>a1</ua>=@(@(<us>x1</us>,<us>x2</us>),@(<us>x3</us>,<us>x4</us>))
+	<ua>a1</ua>=@((<ua>b1</ua>=<us>x1</us>,<ua>b2</ua>=<us>x2</us>),(<ua>c1</ua>=<us>x1</us>,<ua>c2</ua>=<us>x2</us>))
+				</td>
+			</tr>
+			<tr>
+				<td>Booleans</td>
+				<td>BOOLEAN</td>
+				<td class='code'>
+	<ua>a1</ua>=<uk>true</uk>&amp;<ua>a2</ua>=<uk>false</uk>
+				</td>
+			</tr>
+			<tr>
+				<td>int/float/double/...</td>
+				<td>NUMBER</td>
+				<td class='code'>
+	<ua>a1</ua>=<un>123</un>&amp;<ua>a2</ua>=<un>1.23e1</un>
+				</td>
+			</tr>
+			<tr>
+				<td>null</td>
+				<td>NULL</td>
+				<td class='code'>
+	<ua>a1</ua>=<uk>null</uk>
+				</td>
+			</tr>
+			<tr>
+				<td>String</td>
+				<td>STRING</td>
+				<td class='code'>
+	<ua>a1</ua>=<us>foobar</us>
+	<ua>a1</ua>=<us>'true'</us>
+	<ua>a1</ua>=<us>'null'</us>
+	<ua>a1</ua>=<us>'123'</us>
+	<ua>a1</ua>=<us>' string with whitespace '</us>
+	<ua>a1</ua>=<us>'string with ~'escaped~' quotes'</us>
+				</td>
+			</tr>
+		</table>
+		<p>
+			Refer to the <a href='doc-files/rfc_uon.txt'>UON specification</a> for a complete set of syntax rules.		
+		<p>
+			<code>PojoSwaps</code> can be used to convert non-serializable POJOs into serializable forms, such as converting 
+				<code>Calendar</code> object to ISO8601 strings, or <code><uk>byte</uk>[]</code> arrays to Base-64 encoded strings.<br>
+			These transforms can be associated at various levels:
+		</p>
+		<ul class='spaced-list'>
+			<li>On serializer and parser instances to handle all objects of the class type globally.
+			<li>On classes through the <code><ja>@Bean</ja></code> annotation.
+			<li>On bean properties through the <code><ja>@BeanProperty</ja></code> annotations.
+		</ul>
+		<h6 class='figure'>Example:  A serialized Calendar object using <code>CalendarSwap.RFC2822DTZ</code> transform.</h6>
+		<p class='bcode'>	
+	http://localhost/sample?<ua>a1=<us>'Sun,+03+Mar+1901+09:05:06+GMT'</us>
+		</p>
+		<p>
+			For more information about transforms, refer to <a class='doclink' href='../transform/package-summary.html#TOC'>org.apache.juneau.transform</a>.
+		</p>
+	</div>
+	
+</div>
+
+<!-- ======================================================================================================== -->
+<a id="UrlEncodingSerializer"></a>
+<h2 class='topic' onclick='toggle(this)'>2 - UrlEncodingSerializer and UonSerializer classes</h2>
+<div class='topic'>
+	<p>
+		{@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.uon.UonSerializer} classes are used to convert POJOs to URL-encoded strings.<br>
+		The <code>UonSerializer</code> class converts parameter values to UON notation. 
+		The <code>UrlEncodingSerializer</code> class converts a POJO to key/value URL-Encoded pairs using <code>UonSerializer</code> to serialize the values.
+		If you're trying to construct complete URL-Encoded entities, use <code>UrlEncodingSerializer</code>. 
+		If you're constructing your own key/value pairs, use <code>UonSerializer</code>.
+	</p>	
+	<p>
+		The serializers include several configurable settings.<br>
+		Static reusable instances of serializers are provided with commonly-used settings:
+	</p>
+	<ul class='spaced-list'>
+		<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT} - All default settings, strict mode.
+		<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT} - All default settings, strict mode.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_ENCODING} - Same as DEFAULT, but use URL-Encoding on special characters.
+	</ul>
+	<p>
+		The general guidelines on which serializer to use is:
+	</p>
+	<ul class='spaced-list'>
+		<li>Use encoding serializers when you're using the results to construct a URI yourself, and therefore 
+			need invalid URI characters to be encoded.
+		<li>Use unencoding serializers when you're creating parameter values and passing them off to some other
+			utility class that will itself encode invalid URI characters.
+		<li>Use the readable serializer for debugging purposes.
+	</ul>
+
+	<h6 class='topic'>Notes about examples</h6>
+	<p>
+		The examples shown in this document will use default strict settings.<br>
+		For brevity, the examples will use public fields instead of getters/setters to reduce the size of the examples.<br>
+		In the real world, you'll typically want to use standard bean getters and setters.
+	</p>
+	<p>
+		To start off simple, we'll begin with the following simplified bean and build upon it.
+	</p>
+	<p class='bcode'>
+	<jk>public class</jk> Person {
+		<jc>// Bean properties</jc>
+		<jk>public int</jk> <jf>id</jf>;
+		<jk>public</jk> String <jf>name</jf>;
+
+		<jc>// Bean constructor (needed by parser)</jc>
+		<jk>public</jk> Person() {}
+
+		<jc>// Normal constructor</jc>
+		<jk>public</jk> Person(<jk>int</jk> id, String name) {
+			<jk>this</jk>.<jf>id</jf> = id;
+			<jk>this</jk>.<jf>name</jf> = name;
+		}
+	}
+	</p>
+	<p>
+		The following code shows how to convert this to a URL-encoded value:
+	</p>
+	<p class='bcode'>
+	<jc>// Use serializer with readable output, simple mode.</jc>
+	UonSerializer s = UonSerializer.<jsf>DEFAULT</jsf>;
+
+	<jc>// Create our bean.</jc>
+	Person p = <uk>new</uk> Person(1, <js>"John Smith"</js>);
+
+	<jc>// Serialize the bean to URL-encoded parameter value.</jc>
+	String urlencoded = s.serialize(p);
+	</p>
+	<p>
+		The code above produces the following output:
+	</p>
+	<p class='bcode'>
+	(<ua>id</ua>=<un>1</un>,<ua>name</ua>=<us>'John+Smith'</us>)
+	</p>
+	<p>
+		The {@link org.apache.juneau.urlencoding.UrlEncodingSerializer} class converts
+		maps and beans into top-level query parameter strings.
+	</p>
+	<p class='bcode'>
+	<jc>// Use serializer with readable output, simple mode.</jc>
+	UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT</jsf>;
+	
+	<jc>// Serialize the bean to URL-encoded query string.</jc>
+	String urlencoded = s.serialize(p);
+	</p>
+	<p>
+		The code above produces the following output:
+	</p>
+	<p class='bcode'>
+	<ua>id</ua>=<un>1</un>&amp;<ua>name</ua>=<us>'John+Smith'</us>
+	</p>
+	<p>
+		By default, the <code>UrlEncodingSerializer</code> class will URL-Encode special characters, and the <code>UonSerializer</code> will NOT URL-encode special characters.  
+	</p>
+	
+
+	<!-- ======================================================================================================== -->
+	<a id="BeanAnnotations"></a>
+	<h3 class='topic' onclick='toggle(this)'>2.1 - @Bean and @BeanProperty annotations</h3>
+	<div class='topic'>
+		<p>
+			The {@link org.apache.juneau.annotation.Bean @Bean} and {@link org.apache.juneau.annotation.BeanProperty @BeanProperty} annotations
+				are used to customize the behavior of beans across the entire framework.<br>
+			They have various uses:
+		</p>
+		<ul class='spaced-list'>
+			<li>Hiding bean properties.
+			<li>Specifying the ordering of bean properties.
+			<li>Overriding the names of bean properties.
+			<li>Associating transforms at both the class and property level (to convert non-serializable POJOs to serializable forms).
+		</ul>
+		<p>
+			For example, we now add a <code>birthDate</code> property, and associate a transform with it to transform
+				it to an ISO8601 date-time string in GMT time.<br>
+			We'll also add a couple of <code>URI</code> properties.<br>
+			By default, <code>Calendars</code> are treated as beans by the framework, which is usually not how you want them serialized.<br>
+			Using transforms, we can convert them to standardized string forms.
+		</p>
+		<p class='bcode'>	
+	<jk>public class</jk> Person {
+		<jc>// Bean properties</jc>
+		<jk>public int</jk> <jf>id</jf>;
+		<jk>public</jk> String <jf>name</jf>;
+		<jk>public</jk> URI <jf>uri</jf>;
+		<jk>public</jk> URI <jf>addressBookUri</jf>;
+
+		<ja>@BeanProperty</ja>(swap=CalendarSwap.ISO8601DTZ.<jk>class</jk>) <jk>public</jk> Calendar <jf>birthDate</jf>;
+
+		<jc>// Bean constructor (needed by parser)</jc>
+		<jk>public</jk> Person() {}
+
+		<jc>// Normal constructor</jc>
+		<jk>public</jk> Person(<jk>int</jk> id, String name, String uri, String addressBookUri, String birthDate) <jk>throws</jk> Exception {
+			<jk>this</jk>.<jf>id</jf> = id;
+			<jk>this</jk>.<jf>name</jf> = name;
+			<jk>this</jk>.<jf>uri</jf> = <jk>new</jk> URI(uri);
+			<jk>this</jk>.<jf>addressBookUri</jf> = <jk>new</jk> URI(addressBookUri);
+			<jk>this</jk>.<jf>birthDate</jf> = <jk>new</jk> GregorianCalendar();
+			<jk>this</jk>.<jf>birthDate</jf>.setTime(DateFormat.<jsm>getDateInstance</jsm>(DateFormat.<jsf>MEDIUM</jsf>).parse(birthDate));
+		}
+	}
+		</p>
+		<p>
+			Next, we alter our code to pass in the birthdate:
+		</p>
+		<p class='bcode'>
+	<jc>// Create our bean.</jc>
+	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
+		</p>
+		<p>
+			Now when we rerun the sample code, we'll get the following:
+		</p>
+		<p class='bcode'>
+	(<ua>id</ua>=<un>1</un>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>)
+		</p>
+		<p>
+			Using <code>UrlEncodingSerializer</code> instead would create the following:
+		</p>
+		<p class='bcode'>
+	<ua>id</ua>=<un>1</un>&amp;<ua>name</ua>=<us>'John+Smith'</us>&amp;<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>&amp;<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>&amp;<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>
+		</p>
+		<p>
+			Another useful feature is the {@link org.apache.juneau.annotation.Bean#propertyNamer()} annotation that allows you to plug in your own
+				logic for determining bean property names.<br>
+			The {@link org.apache.juneau.PropertyNamerDashedLC} is an example of an alternate property namer.
+			It converts bean property names to lowercase-dashed format.
+		</p>
+		<h6 class='figure'>Example:</h6>
+		<p class='bcode'>	
+	<ja>@Bean</ja>(propertyNamer=PropertyNamerDashedLC.<jk>class</jk>)
+	<jk>public class</jk> Person {
+		...
+		</p>
+		<h6 class='figure'>Results</h6>
+		<p class='bcode'>
+	(<ua>id</ua>=<un>1</us>,<ua>name</ua>=<us>'John+Smith'</us>,<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>,<ua>address-book-uri</ua>=<us>http://sample/addressBook</us>,<ua>birth-date</ua>=<us>1946-08-12T00:00:00Z</us>)
+		</p>
+	</div>
+	
+		
+	<!-- ======================================================================================================== -->
+	<a id="Collections"></a>
+	<h3 class='topic' onclick='toggle(this)'>2.2 - Collections</h3>
+	<div class='topic'>
+		<p>
+			In our example, let's add a list-of-beans property to our sample class:
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> Person {
+		
+		<jc>// Bean properties</jc>
+		<jk>public</jk> LinkedList&lt;Address&gt; <jf>addresses</jf> = <jk>new</jk> LinkedList&lt;Address&gt;();
+		...
+	}
+		</p>
+		<p>
+			The <code>Address</code> class has the following properties defined:
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> Address {
+
+		<jc>// Bean properties</jc>
+		<jk>public</jk> URI <jf>uri</jf>;
+		<jk>public</jk> URI <jf>personUri</jf>;
+		<jk>public int</jk> <jf>id</jf>;
+		<jk>public</jk> String <jf>street</jf>, <jf>city</jf>, <jf>state</jf>;
+		<jk>public int</jk> <jf>zip</jf>;
+		<jk>public boolean</jk> <jf>isCurrent</jf>;
+	}
+		</p>
+		<p>
+			Next, add some quick-and-dirty code to add an address to our person bean:
+		</p>
+		<p class='bcode'>
+	<jc>// Use serializer with readable output, simple mode.</jc>
+	UonSerializer s = UonSerializer.<jsf>DEFAULT_READABLE</jsf>;
+
+	<jc>// Create our bean.</jc>
+	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
+	Address a = <jk>new</jk> Address();
+	a.<jf>uri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/address/1"</js>);
+	a.<jf>personUri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/person/1"</js>);
+	a.<jf>id</jf> = 1;
+	a.<jf>street</jf> = <js>"100 Main Street"</js>;
+	a.<jf>city</jf> = <js>"Anywhereville"</js>;
+	a.<jf>state</jf> = <js>"NY"</js>;
+	a.<jf>zip</jf> = 12345;
+	a.<jf>isCurrent</jf> = <jk>true</jk>;
+	p.<jf>addresses</jf>.add(a);	
+		</p>
+		<p>
+			Now when we run the sample code, we get the following (in readable format):
+		</p>
+		<p class='bcode'>
+	(
+		<ua>id</ua>=<un>1</un>, 
+		<ua>name</ua>=<us>'John+Smith'</us>, 
+		<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>, 
+		<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+		<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+		<ua>addresses</ua>=@(
+			(
+				<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>, 
+				<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>, 
+				<ua>id</ua>=<un>1</un>, 
+				<ua>street</ua>=<us>'100+Main+Street'</us>, 
+				<ua>city</ua>=<us>Anywhereville</us>, 
+				<ua>state</ua>=<us>NY</us>, 
+				<ua>zip</ua>=<un>12345</un>, 
+				<ua>isCurrent</ua>=<uk>true</uk>
+			)
+		)
+	)
+		</p>
+		<p>
+			If we were to use <code>UrlEncodingSerializer</code> instead, we would get the following:
+		</p>
+		<p class='bcode'>
+	<ua>id</ua>=<un>1</un>&amp; 
+	<ua>name</ua>=<us>'John+Smith'</us>&amp; 
+	<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>&amp; 
+	<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>&amp;
+	<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>&amp;
+	<ua>addresses</ua>=@(
+		(
+			<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>, 
+			<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>, 
+			<ua>id</ua>=<un>1</un>, 
+			<ua>street</ua>=<us>'100+Main+Street'</us>, 
+			<ua>city</ua>=<us>Anywhereville</us>, 
+			<ua>state</ua>=<us>NY</us>, 
+			<ua>zip</ua>=<un>12345</un>, 
+			<ua>isCurrent</ua>=<uk>true</uk>
+		)
+	)
+		</p>
+	</div>
+	<p>
+		Note how the top level <code>Person</code> bean is serialized using the standard <js>'&amp;'</js> delimiter, whereas the lower-level <code>Address</code>
+			bean is serialized using the <js>','</js> character to prevent the <code>addresses</code> field from being incompletely parsed.
+	</p>
+
+
+	<!-- ======================================================================================================== -->
+	<a id="Recursion"></a>
+	<h3 class='topic' onclick='toggle(this)'>2.3 - Non-tree models and recursion detection</h3>
+	<div class='topic'>
+		<p>
+			The URL-encoding serializer is designed to be used against POJO tree structures. <br> 
+			It expects that there not be loops in the POJO model (e.g. children with references to parents, etc...).<br>
+			If you try to serialize models with loops, you will usually cause a <code>StackOverflowError</code> to 
+				be thrown (if {@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_maxDepth} is not reached first).
+		</p>
+		<p>
+			If you still want to use the URL-encoding serializer on such models, Juneau provides the 
+				{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_detectRecursions} setting.<br>
+			It tells the serializer to look for instances of an object in the current branch of the tree and
+				skip serialization when a duplicate is encountered.
+		</p>
+		<p>
+			For example, let's make a POJO model out of the following classes:
+		</p>
+		<p class='bcode'>
+	<jk>public class</jk> A {
+		<jk>public</jk> B b;
+	}
+	
+	<jk>public class</jk> B {
+		<jk>public</jk> C c;
+	}
+	
+	<jk>public class</jk> C {
+		<jk>public</jk> A a;
+	}
+		</p>
+		<p>
+			Now we create a model with a loop and serialize the results.
+		</p>
+		<p class='bcode'>
+	<jc>// Clone an existing serializer and set property for detecting recursions.</jc>
+	UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT_READABLE</jsf>.builder().detectRecursions(<jk>true</jk>).build();
+
+	<jc>// Create a recursive loop.</jc>
+	A a = <jk>new</jk> A();
+	a.<jf>b</jf> = <jk>new</jk> B();
+	a.<jf>b</jf>.<jf>c</jf> = <jk>new</jk> C();
+	a.<jf>b</jf>.<jf>c</jf>.<jf>a</jf> = a;
+	
+	<jc>// Serialize.</jc>
+	String json = s.serialize(a);
+		</p>
+		<p>
+			What we end up with is the following, which does not serialize the contents of the <code>c</code> field:
+		</p>
+		<p class='bcode'>
+	(
+		<ua>b</ua>=(
+			<ua>c</ua>=()
+		)
+	)
+		</p>
+		<p>
+			Without recursion detection enabled, this would cause a stack-overflow error.
+		</p>
+		<p>
+			Recursion detection introduces a performance penalty of around 20%.<br>
+			For this reason the setting is disabled by default.
+		</p>
+	</div>
+
+
+	<!-- ======================================================================================================== -->
+	<a id="SerializerConfigurableProperties"></a>
+	<h3 class='topic' onclick='toggle(this)'>2.4 - Configurable properties</h3>
+	<div class='topic'>
+		<p>
+			See the following classes for all configurable properties that can be used on this serializer:
+		</p>
+		<ul class='spaced-list'>
+			<li>{@link org.apache.juneau.BeanContext} - Bean context properties.
+			<li>{@link org.apache.juneau.uon.UonSerializerContext} - UON serializer context properties.
+			<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerContext} - URL-Encoding serializer context properties.
+		</ul>
+	</div>		
+
+
+	<!-- ======================================================================================================== -->
+	<a id="SerializerOtherNotes"></a>
+	<h3 class='topic' onclick='toggle(this)'>2.5 - Other notes</h3>
+	<div class='topic'>
+		<ul class='spaced-list'>
+			<li>Like all other Juneau serializers, the URL-encoding serializers are thread safe and maintain an internal cache of bean classes encountered.<br>
+				For performance reasons, it's recommended that serializers be reused whenever possible instead of always creating new instances.
+		</ul>
+	</div>
+</div>
+
+
+<!-- ======================================================================================================== -->
+<a id="UrlEncodingParser"></a>
+<h2 class='topic' onclick='toggle(this)'>3 - UrlEncodingParser and UonParser classes</h2>
+<div class='topic'>
+	<p>
+		{@link org.apache.juneau.urlencoding.UrlEncodingParser} and {@link org.apache.juneau.uon.UonParser} classes are used to convert URL-encoded strings back into POJOs.<br>
+		The <code>UonParser</code> class converts UON-encoded parameter values to POJOs.
+		The <code>UrlEncodingParser</code> class converts entire URL-Encoded strings to POJOs using <code>UonSerializer</code> to serialize indivisual values.
+		If you're trying to parse an entire URL-Encoded string, use <code>UrlEncodingParser</code>. 
+		If you're trying to parse an individual value (such as that returned by <code>RestServlet.getQueryParameter(name)</code>), use <code>UonParser</code>.
+	</p>	
+	<p>
+		The following static reusable instances of <code>UrlEncodingParser</code> are provided for convenience:
+	</p>
+	<ul class='spaced-list'>
+		<li>{@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} - Default parser for entire URL-encoded strings, decode <code>%xx</code> sequences.
+		<li>{@link org.apache.juneau.uon.UonParser#DEFAULT} - Default parser for URL-encoded parameter values, don't decode <code>%xx</code> sequences.
+		<li>{@link org.apache.juneau.uon.UonParser#DEFAULT_DECODING} - Default parser for URL-encoded parameter values, decode <code>%xx</code> sequences.
+	</ul>
+	<p>
+		The general guildlines on which parser to use is:
+	</p>
+	<ul class='spaced-list'>
+		<li>Use the <code>DEFAULT</code> parser for parameter values that have already had <code>%xx</code> sequences decoded, 
+			such as when using <code>HttpServletRequest.getQueryParameter(name)</code>.
+		<li>Use the <code>DEFAULT_ENCODED</code> parser if the input has not already had <code>%xx</code> sequences decoded.
+	</ul>
+	<p>
+		Let's build upon the previous example and parse the generated URL-encoded string back into the original bean.<br>
+		We start with the URL-encoded string that was generated.
+	</p>
+	<p class='bcode'>
+	<jc>// Use serializer with readable output.</jc>
+	UonSerializer s = UonSerializer.<jsf>DEFAULT_READABLE</jsf>;
+
+	<jc>// Create our bean.</jc>
+	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
+	Address a = <jk>new</jk> Address();
+	a.<jf>uri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/address/1"</js>);
+	a.<jf>personUri</jf> = <jk>new</jk> URI(<js>"http://sample/addressBook/person/1"</js>);
+	a.<jf>id</jf> = 1;
+	a.<jf>street</jf> = <js>"100 Main Street"</js>;
+	a.<jf>city</jf> = <js>"Anywhereville"</js>;
+	a.<jf>state</jf> = <js>"NY"</js>;
+	a.<jf>zip</jf> = 12345;
+	a.<jf>isCurrent</jf> = <jk>true</jk>;
+	p.<jf>addresses</jf>.add(a);	
+
+	<jc>// Serialize the bean.</jc>
+	String urlencoded = s.serialize(p);
+	</p>
+	<p>
+		This code produced the following:
+	</p>
+	<p class='bcode'>
+	(
+		<ua>id</ua>=<un>1</un>, 
+		<ua>name</ua>=<us>'John+Smith'</us>, 
+		<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>, 
+		<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+		<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+		<ua>addresses</ua>=@(
+			(
+				<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>, 
+				<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>, 
+				<ua>id</ua>=<un>1</un>, 
+				<ua>street</ua>=<us>'100+Main+Street'</us>, 
+				<ua>city</ua>=<us>Anywhereville</us>, 
+				<ua>state</ua>=<us>NY</us>, 
+				<ua>zip</ua>=<un>12345</un>, 
+				<ua>isCurrent</ua>=<uk>true</uk>
+			)
+		)
+	)
+	</p>
+	<p>
+		The code to convert this back into a bean is:
+	</p>
+	<p class='bcode'>
+	<jc>// Parse it back into a bean using the reusable JSON parser.</jc>
+	Person p = UonParser.<jsf>DEFAULT</jsf>.parse(urlencoded, Person.<jk>class</jk>);
+
+	<jc>// Render it back as JSON.</jc>
+	json = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(p);
+	</p>
+	<p>
+		We print it back out to JSON to show that all the data has been preserved:
+	</p>
+	<p class='bcode'>
+	{
+		id: <un>1</un>, 
+		name: <js>'John Smith'</js>, 
+		uri: <js>'http://sample/addressBook/person/1'</js>, 
+		addressBookUri: <js>'http://sample/addressBook'</js>, 
+		birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+		addresses: [
+			{
+				uri: <js>'http://sample/addressBook/address/1'</js>, 
+				personUri: <js>'http://sample/addressBook/person/1'</js>, 
+				id: <un>1</un>, 
+				street: <js>'100 Main Street'</js>, 
+				city: <js>'Anywhereville'</js>, 
+				state: <js>'NY'</js>, 
+				zip: <un>12345</un>, 
+				isCurrent: <jk>true</jk>
+			}
+		]
+	}	
+	</p>
+	
+
+	<!-- ======================================================================================================== -->
+	<a id="GenericParsing"></a>
+	<h3 class='topic' onclick='toggle(this)'>3.1 - Parsing into generic POJO models</h3>
+	<div class='topic'>
+		<p>
+			The URL-encoding parser is not limited to parsing back into the original bean classes.<br>  
+			If the bean classes are not available on the parsing side, the parser can also be used to 
+				parse into a generic model consisting of <code>Maps</code>, <code>Collections</code>, and primitive
+				objects.
+		</p>
+		<p>
+			You can parse into any <code>Map</code> type (e.g. <code>HashMap</code>, <code>TreeMap</code>), but
+				using {@link org.apache.juneau.ObjectMap} is recommended since it has many convenience methods
+				for converting values to various types.<br> 
+			The same is true when parsing collections.  You can use any Collection (e.g. <code>HashSet</code>, <code>LinkedList</code>)
+				or array (e.g. <code>Object[]</code>, <code>String[]</code>, <code>String[][]</code>), but using 
+				{@link org.apache.juneau.ObjectList} is recommended.
+		</p>
+		<p>
+			When the map or list type is not specified, or is the abstract <code>Map</code>, <code>Collection</code>, or <code>List</code> types, 
+				the parser will use <code>ObjectMap</code> and <code>ObjectList</code> by default.
+		</p>
+		<p>
+			Starting back with our original URL-encoded string:
+		</p>
+		<p class='bcode'>
+	(
+		<ua>id</ua>=<un>1</un>, 
+		<ua>name</ua>=<us>'John+Smith'</us>, 
+		<ua>uri</ua>=<us>http://sample/addressBook/person/1</us>, 
+		<ua>addressBookUri</ua>=<us>http://sample/addressBook</us>,
+		<ua>birthDate</ua>=<us>1946-08-12T00:00:00Z</us>,
+		<ua>addresses</ua>=@(
+			(
+				<ua>uri</ua>=<us>http://sample/addressBook/address/1</us>, 
+				<ua>personUri</ua>=<us>http://sample/addressBook/person/1</us>, 
+				<ua>id</ua>=<un>1</un>, 
+				<ua>street</ua>=<us>'100+Main+Street'</us>, 
+				<ua>city</ua>=<us>Anywhereville</us>, 
+				<ua>state</ua>=<us>NY</us>, 
+				<ua>zip</ua>=<un>12345</un>, 
+				<ua>isCurrent</ua>=<uk>true</uk>
+			)
+		)
+	)
+		</p>
+		<p>
+			We can parse this into a generic <code>ObjectMap</code>:
+		</p>
+		<p class='bcode'>	
+	<jc>// Parse URL-encoded string into a generic POJO model.</jc>
+	ObjectMap m = UonParser.<jsf>DEFAULT</jsf>.parse(urlencoded, ObjectMap.<jk>class</jk>);
+
+	<jc>// Convert it back to JSON.</jc>
+	String json = JsonSerializer.<jsf>DEFAULT_LAX_READABLE</jsf>.serialize(m);
+		</p>
+		<p>
+			What we end up with is the exact same output.<br>
+			Even the numbers and booleans are preserved because they are parsed into <code>Number</code> and <code>Boolean</code> objects
+				when parsing into generic models.
+		</p>
+		<p class='bcode'>
+	{
+		id: <un>1</un>, 
+		name: <js>'John Smith'</js>, 
+		uri: <js>'http://sample/addressBook/person/1'</js>, 
+		addressBookUri: <js>'http://sample/addressBook'</js>, 
+		birthDate: <js>'1946-08-12T00:00:00Z'</js>, 
+		addresses: [
+			{
+				uri: <js>'http://sample/addressBook/address/1'</js>, 
+				personUri: <js>'http://sample/addressBook/person/1'</js>, 
+				id: <un>1</un>, 
+				street: <js>'100 Main Street'</js>, 
+				city: <js>'Anywhereville'</js>, 
+				state: <js>'NY'</js>, 
+				zip: <un>12345</un>, 
+				isCurrent: <jk>true</jk>
+			}
+		]
+	}
+		</p>
+		<p>
+			Once parsed into a generic model, various convenience methods are provided on the <code>ObjectMap</code>
+				and <code>ObjectList</code> classes to retrieve values:
+		</p>
+		<p class='bcode'>
+	<jc>// Parse URL-encoded string into a generic POJO model.</jc>
+	ObjectMap m = UonParser.<jsf>DEFAULT</jsf>.parse(urlencoded, ObjectMap.<jk>class</jk>);
+
+	<jc>// Get some simple values.</jc>
+	String name = m.getString(<js>"name"</js>);
+	<jk>int</jk> id = m.getInt(<js>"id"</js>);
+
+	<jc>// Get a value convertable from a String.</jc>
+	URI uri = m.get(URI.<jk>class</jk>, <js>"uri"</js>);
+
+	<jc>// Get a value using a transform.</jc>
+	CalendarSwap transform = <jk>new</jk> CalendarSwap.ISO8601DTZ();
+	Calendar birthDate = m.get(transform, <js>"birthDate"</js>);
+
+	<jc>// Get the addresses.</jc>
+	ObjectList addresses = m.getObjectList(<js>"addresses"</js>);
+
+	<jc>// Get the first address and convert it to a bean.</jc>
+	Address address = addresses.get(Address.<jk>class</jk>, 0);
+		</p>
+
+		<p>
+			As a general rule, parsing into beans is often more efficient than parsing into generic models.<br>
+			And working with beans is often less error prone than working with generic models.
+		</p>		
+	</div>
+
+
+	<!-- ======================================================================================================== -->
+	<a id="ParserConfigurableProperties"></a>
+	<h3 class='topic' onclick='toggle(this)'>3.2 - Configurable properties</h3>
+	<div class='topic'>
+		<p>
+			See the following classes for all configurable properties that can be used on this parser:
+		</p>
+		<ul class='spaced-list'>
+			<li>{@link org.apache.juneau.BeanContext} - Bean context properties.
+			<li>{@link org.apache.juneau.uon.UonParserContext} - UON parser context properties.
+			<li>{@link org.apache.juneau.urlencoding.UrlEncodingParserContext} - URL-Encoding parser context properties.
+		</ul>
+	</div>		
+
+
+	<!-- ======================================================================================================== -->
+	<a id="ParserOtherNotes"></a>
+	<h3 class='topic' onclick='toggle(this)'>3.3 - Other notes</h3>
+	<div class='topic'>
+		<ul class='spaced-list'>
+			<li>Like all other Juneau parsers, the URL-encoding parsers are thread safe and maintain an internal cache of bean classes encountered.<br>
+				For performance reasons, it's recommended that parser be reused whenever possible instead of always creating new instances.
+		</ul>
+	</div>
+	
+</div>
+
+
+<!-- ======================================================================================================== -->
+<a id="RestApiSupport"></a>
+<h2 class='topic' onclick='toggle(this)'>4 - REST API support</h2>
+<div class='topic'>
+	<p>
+		Juneau provides fully-integrated support for URL-encoding serialization/parsing in the REST server and client APIs.<br>
+		The next two sections describe these in detail.
+	</p>
+
+	<!-- ======================================================================================================== -->
+	<a id="RestServerSupport"></a>
+	<h3 class='topic' onclick='toggle(this)'>4.1 - REST server support</h3>
+	<div class='topic'>
+		<p>
+			There are four general ways of defining REST interfaces with support for JSON.
+			Two using the built-in Juneau Server API, and two using the JAX-RS integration component.
+		</p>
+		<ul class='spaced-list'>
+			<li>Create a servlet that subclasses from {@link org.apache.juneau.rest.RestServletDefault}.<br>
+					This includes URL-encoding serialization/parsing support by default, in addition to several other media types.
+			<li>Create a servlet that subclasses from {@link org.apache.juneau.rest.RestServlet} and specify the
+					URL-encoding serializer and/or parser using the {@link org.apache.juneau.rest.annotation.RestResource#serializers()} and
+					{@link org.apache.juneau.rest.annotation.RestResource#parsers()} on the entire servlet class, or 
+					the {@link org.apache.juneau.rest.annotation.RestMethod#serializers()} and {@link org.apache.juneau.rest.annotation.RestMethod#parsers()}
+					annotations on individual methods within the class.
+			<li>Register {@link org.apache.juneau.rest.jaxrs.DefaultProvider} with JAX-RS.<br>
+					This includes URL-encoding serialization/parsing support by default, in addition to several other media types.
+			<li>Create and register a subclass of {@link org.apache.juneau.rest.jaxrs.BaseProvider} and specify the serializers and parsers to use on JAX-RS resources.
+		</ul>
+		<p>
+			In general, the Juneau REST server API is much more configurable and easier to use than JAX-RS, but beware that the author may be slightly biased in this statement.
+		</p>
+
+		<!-- ======================================================================================================== -->
+		<a id="RestServletDefault"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.1 - Using RestServletDefault</h4>
+		<div class='topic'>
+			<p>
+				The quickest way to implement a REST resource with URL-encoding support is to create a subclass of {@link org.apache.juneau.rest.RestServletDefault}.<br>
+				This class provides support for JSON, XML, HTML, URL-Encoding, and others.
+			</p>
+			<p>
+				The <code>AddressBookResource</code> example shown in the first chapter uses the <code>RestServletJenaDefault</code> class
+					which is a subclass of <code>RestServletDefault</code> with additional support for RDF languages.<br>
+				The start of the class definition is shown below:
+			</p>
+			<p class='bcode'>
+	<jc>// Proof-of-concept resource that shows off the capabilities of working with POJO resources.
+	// Consists of an in-memory address book repository.</jc>
+	<ja>@RestResource</ja>(
+		messages=<js>"nls/AddressBookResource"</js>,
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, value=<js>"$L{title}"</js>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_description</jsf>, value=<js>"$L{description}"</js>),
+			<ja>@Property</ja>(name=HtmlDocSerializerContext.<jsf>HTMLDOC_links</jsf>, value=<js>"{options:'?method=OPTIONS',doc:'doc'}"</js>)
+		},
+		encoders=GzipEncoder.<jk>class</jk>
+	)
+	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServletJenaDefault {
+			</p>
+			<p>
+				Notice how serializer and parser properties can be specified using the <code>@RestResource.properties()</code> annotation.<br>
+				In this case, we're overriding the <jsf>SERIALIZER_useWhitespace</jsf> property to add whitespace to the output.
+				The remaining properties are specific to the HTML serializer.
+			</p>
+			<p>
+ 				The <code>$L{...}</code> variable represent localized strings pulled from the resource bundle identified by the <code>messages</code> annotation.
+ 				These variables are replaced at runtime based on the HTTP request locale.
+				Several built-in runtime variable types are defined, and the API can be extended to include user-defined variables.
+				See {@link org.apache.juneau.rest.RestServlet#getVarResolver()} for more information.
+			</p>
+			<p>
+				This document won't go into all the details of the Juneau <code>RestServlet</code> class.<br>
+				Refer to the <a class='doclink' href='../rest/package-summary.html#TOC'>org.apache.juneau.rest</a> documentation for more information on the REST servlet class in general.
+			</p>
+			<p>
+				The rest of the code in the resource class consists of REST methods that simply accept and return POJOs.<br>
+				The framework takes care of all content negotiation, serialization/parsing, and error handling.<br>
+				Below are 3 of those methods to give you a general idea of the concept:
+			</p>
+			<p class='bcode'>
+	<jc>// GET person request handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404})
+	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+		<jk>return</jk> findPerson(id);
+	}
+	
+	<jc>// POST person handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"POST"</js>, path=<js>"/people"</js>, guards=AdminGuard.<jk>class</jk>, rc={307,404})
+	<jk>public void</jk> createPerson(RestResponse res, <ja>@Body</ja> CreatePerson cp) <jk>throws</jk> Exception {
+		Person p = addressBook.createPerson(cp);
+		res.sendRedirect(p.<jf>uri</jf>);
+	}
+
+	<jc>// DELETE person handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"DELETE"</js>, path=<js>"/people/{id}"</js>, guards=AdminGuard.<jk>class</jk>, rc={200,404})
+	<jk>public</jk> String deletePerson(RestResponse res, <ja>@Path</ja> <jk>int</jk> id) <jk>throws</jk> Exception {
+		Person p = findPerson(id);
+		addressBook.remove(p);
+		<jk>return</jk> <js>"DELETE successful"</js>;			
+	}	
+			</p>
+			<p>
+				The resource class can be registered with the web application like any other servlet, or can be 
+					defined as a child of another resource through the {@link org.apache.juneau.rest.annotation.RestResource#children()} annotation.
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="RestServlet"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.2 - Using RestServlet with annotations</h4>
+		<div class='topic'>
+			<p>
+				For fine-tuned control of media types, the {@link org.apache.juneau.rest.RestServlet} class 
+					can be subclassed directly.<br>
+				The serializers/parsers can be specified through annotations at the class and/or method levels.
+			</p>
+			<p>
+				An equivalent <code>AddressBookResource</code> class could be defined to only support URL-encoding using
+					the following definition:
+			</p>
+			<p class='bcode'>
+	<ja>@RestResource</ja>(
+		serializers={UrlEncodingSerializer.<jk>class</jk>},
+		parsers={UrlEncodingParser.<jk>class</jk>},
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
+		}
+	)
+	<jk>public class</jk> AddressBookResource <jk>extends</jk> RestServlet {
+			</p>
+			<p>
+				Likewise, serializers and parsers can be specified/augmented/overridden at the method level like so:
+			</p>
+			<p class='bcode'>
+	<jc>// GET person request handler</jc>
+	<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/people/{id}/*"</js>, rc={200,404},
+		serializers={UrlEncodingSerializer.<jk>class</jk>},
+		parsers={UrlEncodingParser.<jk>class</jk>},
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
+		}
+	)
+	<jk>public</jk> Person getPerson(RestRequest req, <ja>@Path</ja> <jk>int</jk> id) throws Exception {
+		properties.put(HtmlDocSerializerContext.<jsf>HTMLDOC_title</jsf>, req.getPathInfo());
+		<jk>return</jk> findPerson(id);
+	}
+			</p>
+			<p>
+				The {@link org.apache.juneau.rest.annotation.RestMethod#serializersInherit()} and 
+					{@link org.apache.juneau.rest.annotation.RestMethod#parsersInherit()} control how various artifacts
+					are inherited from the parent class.<br>
+				Refer to <a class='doclink' href='../rest/package-summary.html#TOC'>org.apache.juneau.rest</a> for additional information on using these annotations.
+			</p>
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="DefaultProvider"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.3 - Using JAX-RS DefaultProvider</h4>
+		<div class='topic'>
+			<p>
+				URL-encoding media type support in JAX-RS can be achieved by using the {@link org.apache.juneau.rest.jaxrs.DefaultProvider} class.<br>
+				It implements the JAX-RS <code>MessageBodyReader</code> and <code>MessageBodyWriter</code> interfaces for all Juneau supported media types.
+			</p>
+			<p>
+				The <code>DefaultProvider</code> class definition is shown below:
+			</p>
+			<p class='bcode'>
+	<ja>@Provider</ja>
+	<ja>@Produces</ja>(
+		<js>"application/json,text/json,"</js>+                    <jc>// JsonSerializer</jc>
+		<js>"application/json+simple,text/json+simple,"</js>+      <jc>// JsonSerializer.Simple</jc>
+		<js>"application/json+schema,text/json+schema,"</js>+      <jc>// JsonSchemaSerializer</jc>
+		<js>"text/xml,"</js>+                                      <jc>// XmlDocSerializer</jc>
+		<js>"text/xml+simple,"</js>+                               <jc>// XmlDocSerializer.Simple</jc>
+		<js>"text/xml+schema,"</js>+                               <jc>// XmlSchemaDocSerializer</jc>
+		<js>"text/html,"</js>+                                     <jc>// HtmlDocSerializer</jc>
+		<js>"text/uon,"</js>+                                      <jc>// UonSerializer</jc>
+		<js>"application/x-www-form-urlencoded,"</js>+             <jc>// UrlEncodingSerializer</jc>
+		<js>"text/xml+soap,"</js>+                                 <jc>// SoapXmlSerializer</jc>
+		<js>"application/x-java-serialized-object"</js>            <jc>// JavaSerializedObjectSerializer</jc>
+	)
+	<ja>@Consumes</ja>(
+		<js>"application/json,text/json,"</js>+                    <jc>// JsonParser</jc>
+		<js>"text/xml,"</js>+                                      <jc>// XmlParser</jc>
+		<js>"text/html,"</js>+                                     <jc>// HtmlParser</jc>
+		<js>"text/uon,"</js>+                                      <jc>// UonParser</jc>
+		<js>"application/x-www-form-urlencoded,"</js>+             <jc>// UrlEncodingParser</jc>
+		<js>"application/x-java-serialized-object"</js>            <jc>// JavaSerializedObjectParser</jc>
+	)
+	<ja>@JuneauProvider</ja>(
+		serializers={
+			JsonSerializer.<jk>class</jk>,
+			JsonSerializer.Simple.<jk>class</jk>,
+			JsonSchemaSerializer.<jk>class</jk>,
+			XmlDocSerializer.<jk>class</jk>,
+			XmlDocSerializer.Simple.<jk>class</jk>,
+			XmlSchemaDocSerializer.<jk>class</jk>,
+			HtmlDocSerializer.<jk>class</jk>,
+			UonSerializer.<jk>class</jk>,
+			UrlEncodingSerializer.<jk>class</jk>,
+			SoapXmlSerializer.<jk>class</jk>,
+			JavaSerializedObjectSerializer.<jk>class</jk>
+		},
+		parsers={
+			JsonParser.<jk>class</jk>,
+			XmlParser.<jk>class</jk>,
+			HtmlParser.<jk>class</jk>,
+			UonParser.<jk>class</jk>,
+			UrlEncodingParser.<jk>class</jk>,
+			JavaSerializedObjectParser.<jk>class</jk>,
+		}
+	)
+	<jk>public final class</jk> DefaultProvider <jk>extends</jk> BaseProvider {}
+			</p>
+			<p>
+				That's the entire class.  It consists of only annotations to hook up media types to Juneau serializers and parsers.
+				The <ja>@Provider</ja>, <ja>@Produces</ja>, and <ja>@Consumes</ja> annotations are standard JAX-RS annotations, and the <ja>@JuneauProvider</ja> annotation is from Juneau.
+			</p>
+			<p>
+				To enable the provider, you need to make the JAX-RS environment aware of it.
+				In Wink, this is accomplished by adding an entry to a config file.
+			</p>
+			<p class='bcode'>
+	<xt>&lt;web-app</xt> <ua>version</ua>=<us>"2.3"</us><xt>&gt;</xt>
+		<xt>&lt;servlet&gt;</xt>
+			<xt>&lt;servlet-name&gt;</xt>WinkService<xt>&lt;/servlet-name&gt;</xt>
+			<xt>&lt;servlet-class&gt;</xt>org.apache.wink.server.internal.servlet.RestServlet<xt>&lt;/servlet-class&gt;</xt>
+			<xt>&lt;init-param&gt;</xt>
+				<xt>&lt;param-name&gt;</xt>applicationConfigLocation<xt>&lt;/param-name&gt;</xt>
+				<xt>&lt;param-value&gt;</xt>/WEB-INF/wink.cfg<xt>&lt;/param-value&gt;</xt>
+			<xt>&lt;/init-param&gt;</xt>
+		<xt>&lt;/servlet&gt;</xt>
+			</p>
+			<p>
+				Simply include a reference to the provider in the configuration file.
+			<p class='bcode'>
+	org.apache.juneau.rest.jaxrs.DefaultProvider
+			</p>
+			<p>
+				Properties can be specified on providers through the {@link org.apache.juneau.rest.jaxrs.JuneauProvider#properties()} annotation.<br>
+				Properties can also be specified at the method level by using the {@link org.apache.juneau.rest.annotation.RestMethod#properties} annotation, like so:
+			</p>
+			<p class='bcode'>
+	<ja>@GET</ja>
+	<ja>@Produces</ja>(<js>"*/*"</js>)
+	<ja>@RestMethod</ja>( <jc>/* Override some properties */</jc>
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
+		}
+	)
+	<jk>public</jk> Message getMessage() {
+		<jk>return</jk> message;
+	}
+			</p>
+			<h6 class='topic'>Limitations</h6>
+			<p>
+				In general, the Juneau REST API is considerably more flexible than the JAX-RS API, since you can specify and override
+					serializers, parsers, properties, transforms, converters, guards, etc... at both the class and method levels.<br>
+				Therefore, the JAX-RS API has the following limitations that the Juneau Server API does not:
+			</p>
+			<ul class='spaced-list'>
+				<li>The ability to specify different media type providers at the class and method levels.<br> 
+					For example, you may want to use <code>JsonSerializer</code> with one set of properties on 
+						one class, and another instance with different properties on another class.<br>
+					There is currently no way to define this at the class level.<br>
+					You can override properties at the method level, but this can be cumbersome since it would have to be
+						done for all methods in the resource.
+				<li>The Juneau Server API allows you to manipulate properties programatically through the {@link org.apache.juneau.rest.RestResponse#setProperty(String,Object)}
+					method, and through the {@link org.apache.juneau.rest.annotation.Properties} annotation.<br>
+					There is no equivalent in JAX-RS.
+			</ul>
+		</div>
+
+		<!-- ======================================================================================================== -->
+		<a id="BaseProvider"></a>
+		<h4 class='topic' onclick='toggle(this)'>4.1.4 - Using JAX-RS BaseProvider with annotations</h4>
+		<div class='topic'>
+			<p>
+				To provide support for only JSON media types, you can define your own provider class, like so:
+			</p>
+			<p class='bcode'>
+	<ja>@Provider</ja>
+	<ja>@Produces</ja>(
+		<js>"application/x-www-form-urlencoded"</js>                  <jc>// UrlEncodingSerializer</jc>
+	)
+	<ja>@Consumes</ja>(
+		<js>"application/x-www-form-urlencoded"</js>                  <jc>// UrlEncodingParser</jc>
+	)
+	<ja>@JuneauProvider</ja>(
+		serializers={
+			UrlEncodingSerializer.<jk>class</jk>
+		},
+		parsers={
+			UrlEncodingParser.<jk>class</jk>,
+		}
+		properties={
+			<ja>@Property</ja>(name=SerializerContext.<jsf>SERIALIZER_useWhitespace</jsf>, value=<js>"true"</js>)
+		}
+	)
+	<jk>public final class</jk> MyUrlEncodingProvider <jk>extends</jk> BaseProvider {}
+			</p>
+			<p>
+				Then register it with Wink the same way as <code>DefaultProvider</code>.
+			</p>
+		</div>
+
+	</div>
+
+	<!-- ======================================================================================================== -->
+	<a id="RestClientSupport"></a>
+	<h3 class='topic' onclick='toggle(this)'>4.2 - REST client support</h3>
+	<div class='topic'>
+		<p>
+			The {@link org.apache.juneau.rest.client.RestClient} class provides an easy-to-use REST client interface with 
+				pluggable media type handling using any of the Juneau serializers and parsers.<br>
+			Defining a client to support the URL-encoding media type on HTTP requests and responses can be done in one line of code:
+		</p>
+		<p class='bcode'>
+	<jc>// Create a client to handle URL-encoded requests and responses.</jc>
+	RestClient client = <uk>new</uk> RestClient(UrlEncodingSerializer.<uk>class</uk>, UrlEncodingParser.<uk>class</uk>);
+		</p>
+		<p>
+			The client handles all content negotiation based on the registered serializers and parsers.
+		</p>
+		<p>
+			The following code is pulled from the main method of the <code>ClientTest</code> class in the sample web application, and
+				is run against the <code>AddressBookResource</code> class running within the sample app.<br>
+			It shows how the client can be used to interact with the REST API while completely hiding the negotiated content type and working with nothing more than beans.
+		</p>
+		<h6 class='figure'>Example:</h6>
+		<p class='bcode'>
+	String root = <js>"http://localhost:9080/sample/addressBook"</js>;
+	
+	<jc>// Get the current contents of the address book</jc>
+	AddressBook ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size());
+	
+	<jc>// Delete the existing entries</jc>
+	<jk>for</jk> (Person p : ab) {
+		String r = client.doDelete(p.<jf>uri</jf>).getResponse(String.<jk>class</jk>);
+		System.<jsm>out</jsm>.println(<js>"Deleted person "</js> + p.<jf>name</jf> + <js>", response = "</js> + r);
+	}
+	
+	<jc>// Make sure they're gone</jc>
+	ab = client.doGet(root).getResponse(AddressBook.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Number of entries = "</js> + ab.size());
+	
+	<jc>// Add 1st person again</jc>
+	CreatePerson cp = <jk>new</jk> CreatePerson(
+		<js>"Barack Obama"</js>, 
+		<jsm>toCalendar</jsm>(<js>"Aug 4, 1961"</js>),
+		<jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>true</jk>),
+		<jk>new</jk> CreateAddress(<js>"5046 S Greenwood Ave"</js>, <js>"Chicago"</js>, <js>"IL"</js>, 60615, <jk>false</jk>)
+	); 
+	Person p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>);
+	
+	<jc>// Add 2nd person again, but add addresses separately</jc>
+	cp = <jk>new</jk> CreatePerson(
+		<js>"George Walker Bush"</js>, 
+		toCalendar(<js>"Jul 6, 1946"</js>)
+	);
+	p = client.doPost(root + <js>"/people"</js>, cp).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created person "</js> + p.<jf>name</jf> + <js>", uri = "</js> + p.<jf>uri</jf>);
+	
+	<jc>// Add addresses to 2nd person</jc>
+	CreateAddress ca = <jk>new</jk> CreateAddress(<js>"43 Prairie Chapel Rd"</js>, <js>"Crawford"</js>, <js>"TX"</js>, 76638, <jk>true</jk>);
+	Address a = client.doPost(p.<jf>uri</jf> + <js>"/addresses"</js>, ca).getResponse(Address.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>);
+				
+	ca = <jk>new</jk> CreateAddress(<js>"1600 Pennsylvania Ave"</js>, <js>"Washington"</js>, <js>"DC"</js>, 20500, <jk>false</jk>);
+	a = client.doPost(p.<jf>uri</jf> + "/addresses"</js>, ca).getResponse(Address.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Created address "</js> + a.<jf>uri</jf>);
+	
+	<jc>// Find 1st person, and change name</jc>
+	Person[] pp = client.doGet(root + <js>"?q={name:\"'Barack+Obama'\"}"</js>).getResponse(Person[].<jk>class</jk>);
+	String r = client.doPut(pp[0].<jf>uri</jf> + <js>"/name"</js>, <js>"Barack Hussein Obama"</js>).getResponse(String.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"Changed name, response = "</js> + r);
+	p = client.doGet(pp[0].<jf>uri</jf>).getResponse(Person.<jk>class</jk>);
+	System.<jsm>out</jsm>.println(<js>"New name = "</js> + p.<jf>name</jf>);
+		</p>
+		<h6 class='figure'>Results</h6>
+		<p class='bcode'>
+	Number of entries = 2
+	Deleted person Barack Obama, response = DELETE successful
+	Deleted person George Walker Bush, response = DELETE successful
+	Number of entries = 0
+	Created person Barack Obama, uri = http://localhost:9080/sample/addressBook/people/3
+	Created person George Walker Bush, uri = http://localhost:9080/sample/addressBook/people/4
+	Created address http://localhost:9080/sample/addressBook/addresses/7
+	Created address http://localhost:9080/sample/addressBook/addresses/8
+	Changed name, response = PUT successful
+	New name = Barack Hussein Obama
+		</p>
+	</div>
+</div>
+<p align="center"><i><b>*** f�n ***</b></i></p>
+
+</body>
+</html>
\ No newline at end of file


[04/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
new file mode 100644
index 0000000..bacbe66
--- /dev/null
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -0,0 +1,1864 @@
+// ***************************************************************************************************************************
+// * 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.client;
+
+import static org.apache.juneau.parser.ParserContext.*;
+import static org.apache.juneau.serializer.SerializerContext.*;
+
+import java.lang.reflect.*;
+import java.net.*;
+import java.security.*;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.logging.*;
+
+import javax.net.ssl.*;
+
+import org.apache.http.*;
+import org.apache.http.auth.*;
+import org.apache.http.client.*;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.config.*;
+import org.apache.http.client.entity.*;
+import org.apache.http.config.*;
+import org.apache.http.conn.*;
+import org.apache.http.conn.routing.*;
+import org.apache.http.conn.socket.*;
+import org.apache.http.conn.ssl.*;
+import org.apache.http.conn.util.*;
+import org.apache.http.cookie.*;
+import org.apache.http.impl.client.*;
+import org.apache.http.impl.conn.*;
+import org.apache.http.protocol.*;
+import org.apache.juneau.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+
+/**
+ * Builder class for {@link RestClient} class.
+ */
+@SuppressWarnings("hiding")
+public class RestClientBuilder extends CoreObjectBuilder {
+
+	private HttpClientConnectionManager httpClientConnectionManager;
+	private HttpClientBuilder httpClientBuilder = createHttpClientBuilder();
+	private CloseableHttpClient httpClient;
+	private boolean keepHttpClientOpen;
+
+	private Class<? extends Serializer> serializerClass = JsonSerializer.class;
+	private Class<? extends Parser> parserClass = JsonParser.class;
+	private Serializer serializer;
+	private Parser parser;
+
+	private Map<String,String> headers = new TreeMap<String,String>(String.CASE_INSENSITIVE_ORDER);
+
+	private List<RestCallInterceptor> interceptors = new ArrayList<RestCallInterceptor>();
+
+	private String remoteableServletUri;
+	private Map<Method,String> remoteableServiceUriMap = new ConcurrentHashMap<Method,String>();
+	private String rootUrl;
+	private SSLOpts sslOpts;
+	private boolean pooled;
+
+	private int retries = 1;
+	private long retryInterval = -1;
+	private RetryOn retryOn = RetryOn.DEFAULT;
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public RestClientBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor, default settings.
+	 * <p>
+	 * Shortcut for calling <code><jk>new</jk> RestClientBuilder().serializer(s).parser(p);</code>
+	 *
+	 * @param s The serializer to use for output.
+	 * @param p The parser to use for input.
+	 */
+	public RestClientBuilder(Serializer s, Parser p) {
+		super();
+		serializer(s);
+		parser(p);
+	}
+
+	/**
+	 * Constructor, default settings.
+	 * <p>
+	 * Shortcut for calling <code><jk>new</jk> RestClientBuilder().serializer(s).parser(p);</code>
+	 *
+	 * @param s The serializer class to use for output.
+	 * @param p The parser class to use for input.
+	 */
+	public RestClientBuilder(Class<? extends Serializer> s, Class<? extends Parser> p) {
+		super();
+		serializer(s);
+		parser(p);
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public RestClientBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClient build() {
+		try {
+			CloseableHttpClient httpClient = this.httpClient;
+			if (httpClient == null)
+				httpClient = createHttpClient();
+
+			Serializer s =
+				this.serializer != null
+				? this.serializer.builder().apply(propertyStore).build()
+				: new SerializerBuilder(propertyStore).build(this.serializerClass);
+
+			Parser p =
+				this.parser != null
+				? this.parser.builder().apply(propertyStore).build()
+				: new ParserBuilder(propertyStore).build(this.parserClass);
+
+			UrlEncodingSerializer us = new SerializerBuilder(propertyStore).build(UrlEncodingSerializer.class);
+
+			return new RestClient(propertyStore, httpClient, keepHttpClientOpen, s, p, us, headers, interceptors, remoteableServletUri, remoteableServiceUriMap, rootUrl, retryOn, retries, retryInterval);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Creates an instance of an {@link HttpClient} to be used to handle all HTTP communications with the target server.
+	 * <p>
+	 * This HTTP client is used when the HTTP client is not specified through one of the constructors or the
+	 * 	{@link #httpClient(CloseableHttpClient, boolean)} method.
+	 * <p>
+	 * Subclasses can override this method to provide specially-configured HTTP clients to handle
+	 * 	stuff such as SSL/TLS certificate handling, authentication, etc.
+	 * <p>
+	 * The default implementation returns an instance of {@link HttpClient} using the client builder
+	 * 	returned by {@link #createHttpClientBuilder()}.
+	 *
+	 * @return The HTTP client to use.
+	 * @throws Exception
+	 */
+	protected CloseableHttpClient createHttpClient() throws Exception {
+		// Don't call createConnectionManager() if RestClient.setConnectionManager() was called.
+		if (httpClientConnectionManager == null)
+			httpClientBuilder.setConnectionManager(createConnectionManager());
+		return httpClientBuilder.build();
+	}
+
+	/**
+	 * Creates an instance of an {@link HttpClientBuilder} to be used to create
+	 * 	the {@link HttpClient}.
+	 * <p>
+	 * Subclasses can override this method to provide their own client builder.
+	 * <p>
+	 * The predefined method returns an {@link HttpClientBuilder} with the following settings:
+	 * <ul>
+	 * 	<li>Lax redirect strategy.
+	 * 	<li>The connection manager returned by {@link #createConnectionManager()}.
+	 * </ul>
+	 *
+	 * @return The HTTP client builder to use to create the HTTP client.
+	 */
+	protected HttpClientBuilder createHttpClientBuilder() {
+		HttpClientBuilder b = HttpClientBuilder.create();
+		b.setRedirectStrategy(new AllowAllRedirects());
+		return b;
+	}
+
+	/**
+	 * Creates the {@link HttpClientConnectionManager} returned by {@link #createConnectionManager()}.
+	 * <p>
+	 * Subclasses can override this method to provide their own connection manager.
+	 * <p>
+	 * The default implementation returns an instance of a {@link PoolingHttpClientConnectionManager}.
+	 *
+	 * @return The HTTP client builder to use to create the HTTP client.
+	 */
+	protected HttpClientConnectionManager createConnectionManager() {
+		if (sslOpts != null) {
+			HostnameVerifier hv = null;
+			switch (sslOpts.getHostVerify()) {
+				case LAX: hv = new NoopHostnameVerifier(); break;
+				case DEFAULT: hv = new DefaultHostnameVerifier(); break;
+			}
+
+			for (String p : StringUtils.split(sslOpts.getProtocols(), ',')) {
+				try {
+					TrustManager tm = new SimpleX509TrustManager(sslOpts.getCertValidate() == SSLOpts.CertValidate.LAX);
+
+					SSLContext ctx = SSLContext.getInstance(p);
+					ctx.init(null, new TrustManager[] { tm }, null);
+
+					// Create a socket to ensure this algorithm is acceptable.
+					// This will correctly disallow certain configurations (such as SSL_TLS under FIPS)
+					ctx.getSocketFactory().createSocket().close();
+					SSLConnectionSocketFactory sf = new SSLConnectionSocketFactory(ctx, hv);
+					setSSLSocketFactory(sf);
+
+					Registry<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sf).build();
+
+					return (pooled ? new PoolingHttpClientConnectionManager(r) : new BasicHttpClientConnectionManager(r));
+				} catch (Throwable t) {}
+			}
+		}
+
+			// Using pooling connection so that this client is threadsafe.
+		return (pooled ? new PoolingHttpClientConnectionManager() : new BasicHttpClientConnectionManager());
+	}
+
+	/**
+	 * Sets the URI of the remoteable services REST servlet for invoking remoteable services.
+	 *
+	 * @param remoteableServletUri The URI of the REST resource implementing a remoteable services servlet.
+	 * 	(typically an instance of <code>RemoteableServlet</code>).
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder remoteableServletUri(String remoteableServletUri) {
+		this.remoteableServletUri = remoteableServletUri;
+		return this;
+	}
+
+	/**
+	 * Set a root URL for this client.
+	 * <p>
+	 * When set, URL strings passed in through the various rest call methods (e.g. {@link RestClient#doGet(Object)}
+	 * 	will be prefixed with the specified root.
+	 * This root URL is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URL string.
+	 *
+	 * @param rootUrl The root URL to prefix to relative URL strings.  Trailing slashes are trimmed.
+	 * Usually a <code>String<code> but you can also pass in <code>URI</code> and <code>URL</code> objects as well.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder rootUrl(Object rootUrl) {
+		String s = rootUrl.toString();
+		if (s.endsWith("/"))
+			s = s.replaceAll("\\/$", "");
+		this.rootUrl = s;
+		return this;
+	}
+
+	/**
+	 * Enable SSL support on this client.
+	 *
+	 * @param opts The SSL configuration options.  See {@link SSLOpts} for details.
+	 * This method is a no-op if <code>sslConfig</code> is <jk>null</jk>.
+	 * @return This object (for method chaining).
+	 * @throws KeyStoreException
+	 * @throws NoSuchAlgorithmException
+	 */
+	public RestClientBuilder enableSSL(SSLOpts opts) throws KeyStoreException, NoSuchAlgorithmException {
+		this.sslOpts = opts;
+		return this;
+	}
+
+	/**
+	 * Enable LAX SSL support.
+	 * <p>
+	 * Certificate chain validation and hostname verification is disabled.
+	 *
+	 * @return This object (for method chaining).
+	 * @throws KeyStoreException
+	 * @throws NoSuchAlgorithmException
+	 */
+	public RestClientBuilder enableLaxSSL() throws KeyStoreException, NoSuchAlgorithmException {
+		return enableSSL(SSLOpts.LAX);
+	}
+
+	/**
+	 * Sets the client version by setting the value for the <js>"X-Client-Version"</js> header.
+	 *
+	 * @param version The version string (e.g. <js>"1.2.3"</js>)
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder clientVersion(String version) {
+		return header("X-Client-Version", version);
+	}
+
+	/**
+	 * Adds an interceptor that gets called immediately after a connection is made.
+	 *
+	 * @param interceptor The interceptor.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder interceptor(RestCallInterceptor interceptor) {
+		interceptors.add(interceptor);
+		return this;
+	}
+
+	/**
+	 * Adds a {@link RestCallLogger} to the list of interceptors on this class.
+	 *
+	 * @param level The log level to log messsages at.
+	 * @param log The logger to log messages to.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder logTo(Level level, Logger log) {
+		interceptor(new RestCallLogger(level, log));
+		return this;
+	}
+
+	/**
+	 * Make HTTP calls retryable if an error response (>=400) is received.
+	 *
+	 * @param retries The number of retries to attempt.
+	 * @param interval The time in milliseconds between attempts.
+	 * @param retryOn Optional object used for determining whether a retry should be attempted.
+	 * If <jk>null</jk>, uses {@link RetryOn#DEFAULT}.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder retryable(int retries, long interval, RetryOn retryOn) {
+		this.retries = retries;
+		this.retryInterval = interval;
+		this.retryOn = retryOn;
+		return this;
+	}
+
+	/**
+	 * When called, the {@link #createConnectionManager()} method will return a {@link PoolingHttpClientConnectionManager}
+	 * 	instead of a {@link BasicHttpClientConnectionManager}.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder pooled() {
+		this.pooled = true;
+		return this;
+	}
+
+	/**
+	 * Sets the serializer used for serializing POJOs to the HTTP request message body.
+	 *
+	 * @param serializer The serializer.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder serializer(Serializer serializer) {
+		this.serializer = serializer;
+		return this;
+	}
+
+	/**
+	 * Same as {@link #serializer(Serializer)}, except takes in a serializer class that
+	 * 	will be instantiated through a no-arg constructor.
+	 *
+	 * @param serializerClass The serializer class.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder serializer(Class<? extends Serializer> serializerClass) {
+		this.serializerClass = serializerClass;
+		return this;
+	}
+
+	/**
+	 * Sets the parser used for parsing POJOs from the HTTP response message body.
+	 *
+	 * @param parser The parser.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder parser(Parser parser) {
+		this.parser = parser;
+		return this;
+	}
+
+	/**
+	 * Same as {@link #parser(Parser)}, except takes in a parser class that
+	 * 	will be instantiated through a no-arg constructor.
+	 *
+	 * @param parserClass The parser class.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder parser(Class<? extends Parser> parserClass) {
+		this.parserClass = parserClass;
+		return this;
+	}
+
+	/**
+	 * Set up this client to use BASIC auth.
+	 *
+	 * @param host The auth scope hostname.
+	 * @param port The auth scope port.
+	 * @param user The username.
+	 * @param pw The password.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder basicAuth(String host, int port, String user, String pw) {
+		AuthScope scope = new AuthScope(host, port);
+		Credentials up = new UsernamePasswordCredentials(user, pw);
+		CredentialsProvider p = new BasicCredentialsProvider();
+		p.setCredentials(scope, up);
+		setDefaultCredentialsProvider(p);
+		return this;
+	}
+
+	/**
+	 * Sets the internal {@link HttpClient} to use for handling HTTP communications.
+	 *
+	 * @param httpClient The HTTP client.
+	 * @param keepHttpClientOpen Don't close this client when the {@link RestClient#close()} method is called.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder httpClient(CloseableHttpClient httpClient, boolean keepHttpClientOpen) {
+		this.httpClient = httpClient;
+		this.keepHttpClientOpen = keepHttpClientOpen;
+		return this;
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// HTTP headers
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Specifies a request header property to add to all requests created by this client.
+	 *
+	 * @param name The HTTP header name.
+	 * @param value The HTTP header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder header(String name, Object value) {
+		this.headers.put(name, value == null ? null : value.toString());
+		return this;
+	}
+
+	/**
+	 * Sets the value for the <code>Accept</code> request header.
+	 * <p>
+	 * This overrides the media type specified on the parser, but is overridden by calling <code>header(<js>"Accept"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder accept(Object value) {
+		return header("Accept", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Charset</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Charset"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder acceptCharset(Object value) {
+		return header("Accept-Charset", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Encoding</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Encoding"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder acceptEncoding(Object value) {
+		return header("Accept-Encoding", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Accept-Language</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Accept-Language"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder acceptLanguage(Object value) {
+		return header("Accept-Language", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Authorization</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Authorization"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder authorization(Object value) {
+		return header("Authorization", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Cache-Control</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Cache-Control"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder cacheControl(Object value) {
+		return header("Cache-Control", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Connection</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Connection"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder connection(Object value) {
+		return header("Connection", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Content-Length</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Content-Length"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder contentLength(Object value) {
+		return header("Content-Length", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Content-Type</code> request header.
+	 * <p>
+	 * This overrides the media type specified on the serializer, but is overridden by calling <code>header(<js>"Content-Type"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder contentType(Object value) {
+		return header("Content-Type", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Date</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Date"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder date(Object value) {
+		return header("Date", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Expect</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Expect"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder expect(Object value) {
+		return header("Expect", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Forwarded</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Forwarded"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder forwarded(Object value) {
+		return header("Forwarded", value);
+	}
+
+	/**
+	 * Sets the value for the <code>From</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"From"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder from(Object value) {
+		return header("From", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Host</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Host"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder host(Object value) {
+		return header("Host", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Match</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Match"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder ifMatch(Object value) {
+		return header("If-Match", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Modified-Since</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Modified-Since"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder ifModifiedSince(Object value) {
+		return header("If-Modified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-None-Match</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-None-Match"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder ifNoneMatch(Object value) {
+		return header("If-None-Match", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Range</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Range"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder ifRange(Object value) {
+		return header("If-Range", value);
+	}
+
+	/**
+	 * Sets the value for the <code>If-Unmodified-Since</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"If-Unmodified-Since"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder ifUnmodifiedSince(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Max-Forwards</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Max-Forwards"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder maxForwards(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Origin</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Origin"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder origin(Object value) {
+		return header("If-Unmodified-Since", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Pragma</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Pragma"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder pragma(Object value) {
+		return header("Pragma", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Proxy-Authorization</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Proxy-Authorization"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder proxyAuthorization(Object value) {
+		return header("Proxy-Authorization", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Range</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Range"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder range(Object value) {
+		return header("Range", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Referer</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Referer"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder referer(Object value) {
+		return header("Referer", value);
+	}
+
+	/**
+	 * Sets the value for the <code>TE</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"TE"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder te(Object value) {
+		return header("TE", value);
+	}
+
+	/**
+	 * Sets the value for the <code>User-Agent</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"User-Agent"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder userAgent(Object value) {
+		return header("User-Agent", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Upgrade</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Upgrade"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder upgrade(Object value) {
+		return header("Upgrade", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Via</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Via"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder via(Object value) {
+		return header("Via", value);
+	}
+
+	/**
+	 * Sets the value for the <code>Warning</code> request header.
+	 * <p>
+	 * This is a shortcut for calling <code>header(<js>"Warning"</js>, value);</code>
+	 *
+	 * @param value The new header value.
+	 * @return This object (for method chaining).
+	 */
+	public RestClientBuilder warning(Object value) {
+		return header("Warning", value);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// CoreObject properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_maxDepth} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_maxDepth
+	 */
+	public RestClientBuilder maxDepth(int value) {
+		return property(SERIALIZER_maxDepth, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_initialDepth} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_initialDepth
+	 */
+	public RestClientBuilder initialDepth(int value) {
+		return property(SERIALIZER_initialDepth, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_detectRecursions} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_detectRecursions
+	 */
+	public RestClientBuilder detectRecursions(boolean value) {
+		return property(SERIALIZER_detectRecursions, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_ignoreRecursions} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_ignoreRecursions
+	 */
+	public RestClientBuilder ignoreRecursions(boolean value) {
+		return property(SERIALIZER_ignoreRecursions, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_useWhitespace} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_useWhitespace
+	 */
+	public RestClientBuilder useWhitespace(boolean value) {
+		return property(SERIALIZER_useWhitespace, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_addBeanTypeProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_addBeanTypeProperties
+	 */
+	public RestClientBuilder addBeanTypeProperties(boolean value) {
+		return property(SERIALIZER_addBeanTypeProperties, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_quoteChar} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_quoteChar
+	 */
+	public RestClientBuilder quoteChar(char value) {
+		return property(SERIALIZER_quoteChar, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimNullProperties} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimNullProperties
+	 */
+	public RestClientBuilder trimNullProperties(boolean value) {
+		return property(SERIALIZER_trimNullProperties, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimEmptyCollections} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyCollections
+	 */
+	public RestClientBuilder trimEmptyCollections(boolean value) {
+		return property(SERIALIZER_trimEmptyCollections, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimEmptyMaps} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyMaps
+	 */
+	public RestClientBuilder trimEmptyMaps(boolean value) {
+		return property(SERIALIZER_trimEmptyMaps, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_trimStrings} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimStrings
+	 */
+	public RestClientBuilder trimStringsS(boolean value) {
+		return property(SERIALIZER_trimStrings, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_relativeUriBase} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_relativeUriBase
+	 */
+	public RestClientBuilder relativeUriBase(String value) {
+		return property(SERIALIZER_relativeUriBase, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_absolutePathUriBase} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_absolutePathUriBase
+	 */
+	public RestClientBuilder absolutePathUriBase(String value) {
+		return property(SERIALIZER_absolutePathUriBase, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_sortCollections} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortCollections
+	 */
+	public RestClientBuilder sortCollections(boolean value) {
+		return property(SERIALIZER_sortCollections, value);
+	}
+
+	/**
+	 * Sets the {@link SerializerContext#SERIALIZER_sortMaps} property on all serializers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortMaps
+	 */
+	public RestClientBuilder sortMaps(boolean value) {
+		return property(SERIALIZER_sortMaps, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_trimStrings} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_trimStrings
+	 */
+	public RestClientBuilder trimStringsP(boolean value) {
+		return property(PARSER_trimStrings, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_strict} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_strict
+	 */
+	public RestClientBuilder strict(boolean value) {
+		return property(PARSER_strict, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_inputStreamCharset} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_inputStreamCharset
+	 */
+	public RestClientBuilder inputStreamCharset(String value) {
+		return property(PARSER_inputStreamCharset, value);
+	}
+
+	/**
+	 * Sets the {@link ParserContext#PARSER_fileCharset} property on all parsers in this group.
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see ParserContext#PARSER_fileCharset
+	 */
+	public RestClientBuilder fileCharset(String value) {
+		return property(PARSER_fileCharset, value);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> RestClientBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RestClientBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+
+
+	//------------------------------------------------------------------------------------------------
+	// Passthrough methods for HttpClientBuilder.
+	//------------------------------------------------------------------------------------------------
+
+	/**
+	 * @param redirectStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setRedirectStrategy(RedirectStrategy)
+	 */
+	public RestClientBuilder setRedirectStrategy(RedirectStrategy redirectStrategy) {
+		httpClientBuilder.setRedirectStrategy(redirectStrategy);
+		return this;
+	}
+
+	/**
+	 * @param cookieSpecRegistry
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultCookieSpecRegistry(Lookup)
+	 */
+	public RestClientBuilder setDefaultCookieSpecRegistry(Lookup<CookieSpecProvider> cookieSpecRegistry) {
+		httpClientBuilder.setDefaultCookieSpecRegistry(cookieSpecRegistry);
+		return this;
+	}
+
+	/**
+	 * @param requestExec
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setRequestExecutor(HttpRequestExecutor)
+	 */
+	public RestClientBuilder setRequestExecutor(HttpRequestExecutor requestExec) {
+		httpClientBuilder.setRequestExecutor(requestExec);
+		return this;
+	}
+
+	/**
+	 * @param hostnameVerifier
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setSSLHostnameVerifier(HostnameVerifier)
+	 */
+	public RestClientBuilder setSSLHostnameVerifier(HostnameVerifier hostnameVerifier) {
+		httpClientBuilder.setSSLHostnameVerifier(hostnameVerifier);
+		return this;
+	}
+
+	/**
+	 * @param publicSuffixMatcher
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setPublicSuffixMatcher(PublicSuffixMatcher)
+	 */
+	public RestClientBuilder setPublicSuffixMatcher(PublicSuffixMatcher publicSuffixMatcher) {
+		httpClientBuilder.setPublicSuffixMatcher(publicSuffixMatcher);
+		return this;
+	}
+
+	/**
+	 * @param sslContext
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setSSLContext(SSLContext)
+	 */
+	public RestClientBuilder setSSLContext(SSLContext sslContext) {
+		httpClientBuilder.setSSLContext(sslContext);
+		return this;
+	}
+
+	/**
+	 * @param sslSocketFactory
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setSSLSocketFactory(LayeredConnectionSocketFactory)
+	 */
+	public RestClientBuilder setSSLSocketFactory(LayeredConnectionSocketFactory sslSocketFactory) {
+		httpClientBuilder.setSSLSocketFactory(sslSocketFactory);
+		return this;
+	}
+
+	/**
+	 * @param maxConnTotal
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setMaxConnTotal(int)
+	 */
+	public RestClientBuilder setMaxConnTotal(int maxConnTotal) {
+		httpClientBuilder.setMaxConnTotal(maxConnTotal);
+		return this;
+	}
+
+	/**
+	 * @param maxConnPerRoute
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setMaxConnPerRoute(int)
+	 */
+	public RestClientBuilder setMaxConnPerRoute(int maxConnPerRoute) {
+		httpClientBuilder.setMaxConnPerRoute(maxConnPerRoute);
+		return this;
+	}
+
+	/**
+	 * @param config
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultSocketConfig(SocketConfig)
+	 */
+	public RestClientBuilder setDefaultSocketConfig(SocketConfig config) {
+		httpClientBuilder.setDefaultSocketConfig(config);
+		return this;
+	}
+
+	/**
+	 * @param config
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultConnectionConfig(ConnectionConfig)
+	 */
+	public RestClientBuilder setDefaultConnectionConfig(ConnectionConfig config) {
+		httpClientBuilder.setDefaultConnectionConfig(config);
+		return this;
+	}
+
+	/**
+	 * @param connTimeToLive
+	 * @param connTimeToLiveTimeUnit
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setConnectionTimeToLive(long,TimeUnit)
+	 */
+	public RestClientBuilder setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
+		httpClientBuilder.setConnectionTimeToLive(connTimeToLive, connTimeToLiveTimeUnit);
+		return this;
+	}
+
+	/**
+	 * @param connManager
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setConnectionManager(HttpClientConnectionManager)
+	 */
+	public RestClientBuilder setConnectionManager(HttpClientConnectionManager connManager) {
+		this.httpClientConnectionManager = connManager;
+		httpClientBuilder.setConnectionManager(connManager);
+		return this;
+	}
+
+	/**
+	 * @param shared
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setConnectionManagerShared(boolean)
+	 */
+	public RestClientBuilder setConnectionManagerShared(boolean shared) {
+		httpClientBuilder.setConnectionManagerShared(shared);
+		return this;
+	}
+
+	/**
+	 * @param reuseStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setConnectionReuseStrategy(ConnectionReuseStrategy)
+	 */
+	public RestClientBuilder setConnectionReuseStrategy(ConnectionReuseStrategy reuseStrategy) {
+		httpClientBuilder.setConnectionReuseStrategy(reuseStrategy);
+		return this;
+	}
+
+	/**
+	 * @param keepAliveStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setKeepAliveStrategy(ConnectionKeepAliveStrategy)
+	 */
+	public RestClientBuilder setKeepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy) {
+		httpClientBuilder.setKeepAliveStrategy(keepAliveStrategy);
+		return this;
+	}
+
+	/**
+	 * @param targetAuthStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setTargetAuthenticationStrategy(AuthenticationStrategy)
+	 */
+	public RestClientBuilder setTargetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
+		httpClientBuilder.setTargetAuthenticationStrategy(targetAuthStrategy);
+		return this;
+	}
+
+	/**
+	 * @param proxyAuthStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setProxyAuthenticationStrategy(AuthenticationStrategy)
+	 */
+	public RestClientBuilder setProxyAuthenticationStrategy(AuthenticationStrategy proxyAuthStrategy) {
+		httpClientBuilder.setProxyAuthenticationStrategy(proxyAuthStrategy);
+		return this;
+	}
+
+	/**
+	 * @param userTokenHandler
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setUserTokenHandler(UserTokenHandler)
+	 */
+	public RestClientBuilder setUserTokenHandler(UserTokenHandler userTokenHandler) {
+		httpClientBuilder.setUserTokenHandler(userTokenHandler);
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableConnectionState()
+	 */
+	public RestClientBuilder disableConnectionState() {
+		httpClientBuilder.disableConnectionState();
+		return this;
+	}
+
+	/**
+	 * @param schemePortResolver
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setSchemePortResolver(SchemePortResolver)
+	 */
+	public RestClientBuilder setSchemePortResolver(SchemePortResolver schemePortResolver) {
+		httpClientBuilder.setSchemePortResolver(schemePortResolver);
+		return this;
+	}
+
+	/**
+	 * @param userAgent
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setUserAgent(String)
+	 */
+	public RestClientBuilder setUserAgent(String userAgent) {
+		httpClientBuilder.setUserAgent(userAgent);
+		return this;
+	}
+
+	/**
+	 * @param defaultHeaders
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultHeaders(Collection)
+	 */
+	public RestClientBuilder setDefaultHeaders(Collection<? extends Header> defaultHeaders) {
+		httpClientBuilder.setDefaultHeaders(defaultHeaders);
+		return this;
+	}
+
+	/**
+	 * @param itcp
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#addInterceptorFirst(HttpResponseInterceptor)
+	 */
+	public RestClientBuilder addInterceptorFirst(HttpResponseInterceptor itcp) {
+		httpClientBuilder.addInterceptorFirst(itcp);
+		return this;
+	}
+
+	/**
+	 * @param itcp
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#addInterceptorLast(HttpResponseInterceptor)
+	 */
+	public RestClientBuilder addInterceptorLast(HttpResponseInterceptor itcp) {
+		httpClientBuilder.addInterceptorLast(itcp);
+		return this;
+	}
+
+	/**
+	 * @param itcp
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#addInterceptorFirst(HttpRequestInterceptor)
+	 */
+	public RestClientBuilder addInterceptorFirst(HttpRequestInterceptor itcp) {
+		httpClientBuilder.addInterceptorFirst(itcp);
+		return this;
+	}
+
+	/**
+	 * @param itcp
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#addInterceptorLast(HttpRequestInterceptor)
+	 */
+	public RestClientBuilder addInterceptorLast(HttpRequestInterceptor itcp) {
+		httpClientBuilder.addInterceptorLast(itcp);
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableCookieManagement()
+	 */
+	public RestClientBuilder disableCookieManagement() {
+		httpClientBuilder.disableCookieManagement();
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableContentCompression()
+	 */
+	public RestClientBuilder disableContentCompression() {
+		httpClientBuilder.disableContentCompression();
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableAuthCaching()
+	 */
+	public RestClientBuilder disableAuthCaching() {
+		httpClientBuilder.disableAuthCaching();
+		return this;
+	}
+
+	/**
+	 * @param httpprocessor
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setHttpProcessor(HttpProcessor)
+	 */
+	public RestClientBuilder setHttpProcessor(HttpProcessor httpprocessor) {
+		httpClientBuilder.setHttpProcessor(httpprocessor);
+		return this;
+	}
+
+	/**
+	 * @param retryHandler
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setRetryHandler(HttpRequestRetryHandler)
+	 */
+	public RestClientBuilder setRetryHandler(HttpRequestRetryHandler retryHandler) {
+		httpClientBuilder.setRetryHandler(retryHandler);
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableAutomaticRetries()
+	 */
+	public RestClientBuilder disableAutomaticRetries() {
+		httpClientBuilder.disableAutomaticRetries();
+		return this;
+	}
+
+	/**
+	 * @param proxy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setProxy(HttpHost)
+	 */
+	public RestClientBuilder setProxy(HttpHost proxy) {
+		httpClientBuilder.setProxy(proxy);
+		return this;
+	}
+
+	/**
+	 * @param routePlanner
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setRoutePlanner(HttpRoutePlanner)
+	 */
+	public RestClientBuilder setRoutePlanner(HttpRoutePlanner routePlanner) {
+		httpClientBuilder.setRoutePlanner(routePlanner);
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#disableRedirectHandling()
+	 */
+	public RestClientBuilder disableRedirectHandling() {
+		httpClientBuilder.disableRedirectHandling();
+		return this;
+	}
+
+	/**
+	 * @param connectionBackoffStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setConnectionBackoffStrategy(ConnectionBackoffStrategy)
+	 */
+	public RestClientBuilder setConnectionBackoffStrategy(ConnectionBackoffStrategy connectionBackoffStrategy) {
+		httpClientBuilder.setConnectionBackoffStrategy(connectionBackoffStrategy);
+		return this;
+	}
+
+	/**
+	 * @param backoffManager
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setBackoffManager(BackoffManager)
+	 */
+	public RestClientBuilder setBackoffManager(BackoffManager backoffManager) {
+		httpClientBuilder.setBackoffManager(backoffManager);
+		return this;
+	}
+
+	/**
+	 * @param serviceUnavailStrategy
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)
+	 */
+	public RestClientBuilder setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy serviceUnavailStrategy) {
+		httpClientBuilder.setServiceUnavailableRetryStrategy(serviceUnavailStrategy);
+		return this;
+	}
+
+	/**
+	 * @param cookieStore
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultCookieStore(CookieStore)
+	 */
+	public RestClientBuilder setDefaultCookieStore(CookieStore cookieStore) {
+		httpClientBuilder.setDefaultCookieStore(cookieStore);
+		return this;
+	}
+
+	/**
+	 * @param credentialsProvider
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultCredentialsProvider(CredentialsProvider)
+	 */
+	public RestClientBuilder setDefaultCredentialsProvider(CredentialsProvider credentialsProvider) {
+		httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+		return this;
+	}
+
+	/**
+	 * @param authSchemeRegistry
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultAuthSchemeRegistry(Lookup)
+	 */
+	public RestClientBuilder setDefaultAuthSchemeRegistry(Lookup<AuthSchemeProvider> authSchemeRegistry) {
+		httpClientBuilder.setDefaultAuthSchemeRegistry(authSchemeRegistry);
+		return this;
+	}
+
+	/**
+	 * @param contentDecoderMap
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setContentDecoderRegistry(Map)
+	 */
+	public RestClientBuilder setContentDecoderRegistry(Map<String,InputStreamFactory> contentDecoderMap) {
+		httpClientBuilder.setContentDecoderRegistry(contentDecoderMap);
+		return this;
+	}
+
+	/**
+	 * @param config
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#setDefaultRequestConfig(RequestConfig)
+	 */
+	public RestClientBuilder setDefaultRequestConfig(RequestConfig config) {
+		httpClientBuilder.setDefaultRequestConfig(config);
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#useSystemProperties()
+	 */
+	public RestClientBuilder useSystemProperties() {
+		httpClientBuilder.useSystemProperties();
+		return this;
+	}
+
+	/**
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#evictExpiredConnections()
+	 */
+	public RestClientBuilder evictExpiredConnections() {
+		httpClientBuilder.evictExpiredConnections();
+		return this;
+	}
+
+	/**
+	 * @param maxIdleTime
+	 * @param maxIdleTimeUnit
+	 * @return This object (for method chaining).
+	 * @see HttpClientBuilder#evictIdleConnections(long,TimeUnit)
+	 */
+	public RestClientBuilder evictIdleConnections(long maxIdleTime, TimeUnit maxIdleTimeUnit) {
+		httpClientBuilder.evictIdleConnections(maxIdleTime, maxIdleTimeUnit);
+		return this;
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
index 34024c7..6a1c542 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
@@ -28,6 +28,16 @@ public interface RetryOn {
 	};
 
 	/**
+	 * Default RetryOn that returns <jk>true</jk> if the HTTP connection could not be made.
+	 */
+	public static final RetryOn CONNECTION_LOST = new RetryOn() {
+		@Override /* RetryOn */
+		public boolean onCode(int httpResponseCode) {
+			return httpResponseCode <= 0;
+		}
+	};
+
+	/**
 	 * Subclasses should override this method to determine whether the HTTP response is retryable.
 	 *
 	 * @param httpResponseCode The HTTP response code.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SSLOpts.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SSLOpts.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SSLOpts.java
index 52f5766..e0041da 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SSLOpts.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SSLOpts.java
@@ -15,7 +15,7 @@ package org.apache.juneau.rest.client;
 import org.apache.juneau.internal.*;
 
 /**
- * SSL configuration options that get passed to {@link RestClient#enableSSL(SSLOpts)}.
+ * SSL configuration options that get passed to {@link RestClientBuilder#enableSSL(SSLOpts)}.
  */
 public class SSLOpts {
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
index 17a7dde..f90c393 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
@@ -12,12 +12,13 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.client;
 
-import static org.apache.juneau.urlencoding.UonSerializerContext.*;
+import static org.apache.juneau.uon.UonSerializerContext.*;
 
 import java.io.*;
 
 import org.apache.http.*;
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html
----------------------------------------------------------------------
diff --git a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html
index 55797bb..8e30aaa 100644
--- a/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html
+++ b/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/package.html
@@ -115,7 +115,7 @@
 	<jc>// Examples below use the Juneau Address Book resource example</jc>
 
 	<jc>// Create a reusable client with JSON support</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>);
+	RestClient client = <jk>new</jk> RestClientBuilder().build();
 	
 	<jc>// GET request, ignoring output</jc>
 	<jk>try</jk> {
@@ -185,7 +185,7 @@
 		.getResponse(Boolean.<jk>class</jk>);
 			
 	<jc>// GET request, getting a filtered object</jc>
-	client.getParser().addPojoSwaps(CalendarSwap.<jsf>ISO8601</jsf>.<jk>class</jk>);
+	client = <jk>new</jk> RestClientBuilder().pojoSwaps(CalendarSwap.<jsf>ISO8601</jsf>.<jk>class</jk>).build();
 	Calendar birthDate = client.doGet(<js>"http://localhost:9080/sample/addressBook/0/birthDate"</js>)
 		.getResponse(GregorianCalendar.<jk>class</jk>);
 
@@ -213,7 +213,7 @@
 	<h3 class='topic' onclick='toggle(this)'>1.1 - SSL Support</h3>
 	<div class='topic'>
 		<p>
-			The simplest way to enable SSL support in the client is to use the {@link org.apache.juneau.rest.client.RestClient#enableSSL(SSLOpts)} method
+			The simplest way to enable SSL support in the client is to use the {@link org.apache.juneau.rest.client.RestClientBuilder#enableSSL(SSLOpts)} method
 			and one of the predefined {@link org.apache.juneau.rest.client.SSLOpts} instances:
 		</p>
 		<ul>
@@ -223,18 +223,18 @@
 		<h6 class='topic'>Example:</h6>
 		<p class='bcode'>
 	<jc>// Create a client that ignores self-signed or otherwise invalid certificates.</jc>
-	RestClient restClient = <jk>new</jk> RestClient() 
+	RestClientBuilder builder = <jk>new</jk> RestClientBuilder() 
 		.enableSSL(SSLOpts.<jsf>LAX</jsf>);
 		
 	<jc>// ...or...</jc>
-	RestClient restClient = <jk>new</jk> RestClient() 
+	RestClientBuilder builder = <jk>new</jk> RestClientBuilder() 
 		.enableLaxSSL();
 		</p>
 		<p>
 			This is functionally equivalent to the following:
 		</p>
 		<p class='bcode'>
-	RestClient restClient = <jk>new</jk> RestClient();
+	RestClientBuilder builder = <jk>new</jk> RestClientBuilder();
 	
 	HostnameVerifier hv = <jk>new</jk> NoopHostnameVerifier();
 	TrustManager tm = <jk>new</jk> SimpleX509TrustManager(<jk>true</jk>);
@@ -243,9 +243,9 @@
 		SSLContext ctx = SSLContext.<jsm>getInstance</jsm>(p);
 		ctx.init(<jk>null</jk>, <jk>new</jk> TrustManager[] { tm }, <jk>null</jk>);
 		SSLConnectionSocketFactory sf = <jk>new</jk> SSLConnectionSocketFactory(ctx, hv);
-		restClient.setSSLSocketFactory(sf);
+		builder.setSSLSocketFactory(sf);
 		Registry&lt;ConnectionSocketFactory&gt; r = RegistryBuilder.&lt;ConnectionSocketFactory&gt;<jsm>.create</jsm>().register(<js>"https"</js>, sf).build();
-		restClient.setConnectionManager(<jk>new</jk> PoolingHttpClientConnectionManager(r));
+		builder.setConnectionManager(<jk>new</jk> PoolingHttpClientConnectionManager(r));
 	}
 		</p>
 		<p>
@@ -289,25 +289,26 @@
 		<h4 class='topic' onclick='toggle(this)'>1.2.1 - BASIC Authentication</h4>
 		<div class='topic'>
 			<p>
-				The {@link org.apache.juneau.rest.client.RestClient#setBasicAuth(String,int,String,String)} method can be used to quickly enable
+				The {@link org.apache.juneau.rest.client.RestClientBuilder#basicAuth(String,int,String,String)} method can be used to quickly enable
 				BASIC authentication support.
 			</p>
 			<h6 class='topic'>Example:</h6>
 			<p class='bcode'>
 	<jc>// Create a client that performs BASIC authentication using the specified user/pw.</jc>
-	RestClient restClient = <jk>new</jk> RestClient() 
-		.setBasicAuth(<jsf>HOST</jsf>, <jsf>PORT</jsf>, <jsf>USER</jsf>, <jsf>PW</jsf>);
+	RestClient restClient = <jk>new</jk> RestClientBuilder() 
+		.setBasicAuth(<jsf>HOST</jsf>, <jsf>PORT</jsf>, <jsf>USER</jsf>, <jsf>PW</jsf>)
+		.build();
 		</p>
 		<p>
 			This is functionally equivalent to the following:
 		</p>
 		<p class='bcode'>
-	RestClient restClient = <jk>new</jk> RestClient();
+	RestClientBuilder builder = <jk>new</jk> RestClientBuilder();
 	AuthScope scope = <jk>new</jk> AuthScope(<jsf>HOST</jsf>, <jsf>PORT</jsf>);
 	Credentials up = <jk>new</jk> UsernamePasswordCredentials(<jsf>USER</jsf>, <jsf>PW</jsf>);
 	CredentialsProvider p = <jk>new</jk> BasicCredentialsProvider();
 	p.setCredentials(scope, up);
-	restClient.setDefaultCredentialsProvider(p);
+	builder.setDefaultCredentialsProvider(p);
 			</p>
 		</div>
 	
@@ -316,10 +317,10 @@
 		<h4 class='topic' onclick='toggle(this)'>1.2.2 - FORM-based Authentication</h4>
 		<div class='topic'>
 			<p>
-				The {@link org.apache.juneau.rest.client.RestClient} class does not itself provide FORM-based authentication since there
+				The {@link org.apache.juneau.rest.client.RestClientBuilder} class does not itself provide FORM-based authentication since there
 				is no standard way of providing such support. 
 				Typically, to perform FORM-based or other types of authentication, you'll want to create your own
-				subclass of {@link org.apache.juneau.rest.client.RestClient} and override the {@link org.apache.juneau.rest.client.RestClient#createHttpClient()}
+				subclass of {@link org.apache.juneau.rest.client.RestClientBuilder} and override the {@link org.apache.juneau.rest.client.RestClientBuilder#createHttpClient()}
 				method to provide an authenticated client.
 			</p>
 			<p>
@@ -330,14 +331,14 @@
 	<jd>/**
 	 * Constructor.
 	 */</jd>
-	<jk>public</jk> JazzRestClient(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+	<jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
 		...
 	}
 
 	<jd>/**
 	 * Override the createHttpClient() method to return an authenticated client.
 	 */</jd>
-	<ja>@Override</ja> <jc>/* RestClient */</jc>
+	<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
 	<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
 		CloseableHttpClient client = <jk>super</jk>.createHttpClient();
 		formBasedAuthenticate(client);
@@ -411,14 +412,14 @@
 	<jd>/**
 	 * Constructor.
 	 */</jd>
-	<jk>public</jk> JazzRestClient(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
+	<jk>public</jk> JazzRestClientBuilder(URI jazzUri, String user, String pw) <jk>throws</jk> IOException {
 		...
 	}
 
 	<jd>/**
 	 * Override the createHttpClient() method to return an authenticated client.
 	 */</jd>
-	<ja>@Override</ja> <jc>/* RestClient */</jc>
+	<ja>@Override</ja> <jc>/* RestClientBuilder */</jc>
 	<jk>protected</jk> CloseableHttpClient createHttpClient() <jk>throws</jk> Exception {
 		CloseableHttpClient client = <jk>super</jk>.createHttpClient();
 		oidcAuthenticate(client);
@@ -557,7 +558,7 @@
 		.run();
 		</p>
 		<p>
-			These convenience methods are specialized methods that use the {@link org.apache.juneau.rest.client.RestCall#addResponsePattern(ResponsePattern)}
+			These convenience methods are specialized methods that use the {@link org.apache.juneau.rest.client.RestCall#responsePattern(ResponsePattern)}
 				method which uses regular expression matching against the response body.
 			This method can be used to search for arbitrary patterns in the response body.
 		</p>
@@ -631,7 +632,7 @@
 	<h3 class='topic' onclick='toggle(this)'>1.5 - Logging</h3>
 	<div class='topic'>
 		<p>
-			Use the {@link org.apache.juneau.rest.client.RestClient#logTo(Level,Logger)} and {@link org.apache.juneau.rest.client.RestCall#logTo(Level,Logger)} methods
+			Use the {@link org.apache.juneau.rest.client.RestClientBuilder#logTo(Level,Logger)} and {@link org.apache.juneau.rest.client.RestCall#logTo(Level,Logger)} methods
 			to log HTTP calls.
 			These methods will cause the HTTP request and response headers and body to be logged to the specified logger.  
 		</p>
@@ -645,7 +646,7 @@
 		</p>
 		<p>
 			Customized logging can be handled by subclassing the {@link org.apache.juneau.rest.client.RestCallLogger} class and using the 
-			{@link org.apache.juneau.rest.client.RestCall#addInterceptor(RestCallInterceptor)} method.
+			{@link org.apache.juneau.rest.client.RestCall#interceptor(RestCallInterceptor)} method.
 		</p>
 	</div>
 	
@@ -654,7 +655,7 @@
 	<h3 class='topic' onclick='toggle(this)'>1.6 - Interceptors</h3>
 	<div class='topic'>
 		<p>
-			The {@link org.apache.juneau.rest.client.RestClient#addInterceptor(RestCallInterceptor)} and {@link org.apache.juneau.rest.client.RestCall#addInterceptor(RestCallInterceptor)} methods
+			The {@link org.apache.juneau.rest.client.RestClientBuilder#interceptor(RestCallInterceptor)} and {@link org.apache.juneau.rest.client.RestCall#interceptor(RestCallInterceptor)} methods
 			can be used to intercept responses during specific connection lifecycle events.
 		</p>
 		<p>
@@ -763,7 +764,7 @@
 		</p>
 		<p>
 			Proxy interfaces are retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method.
-			The {@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String)} method is used to specify the location
+			The {@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String)} method is used to specify the location
 				of the remoteable services servlet running on the server.
 			The remoteable servlet is a specialized subclass of {@link org.apache.juneau.rest.RestServlet} that provides a full-blown
 				REST interface for calling interfaces remotely. 
@@ -781,8 +782,9 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>)
-		.setRemoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>);
+	RestClient client = <jk>new</jk> RestClientBuilder()
+		.remoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>)
+		.build();
 	
 	<jc>// Create a proxy interface.</jc>
 	IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>);
@@ -818,28 +820,30 @@
 	<h3 class='topic' onclick='toggle(this)'>1.8 - Other Useful Methods</h3>
 	<div class='topic'>
 		<p>
-			The {@link org.apache.juneau.rest.client.RestClient#setRootUrl(Object)} method can be used to specify a root URL on 
+			The {@link org.apache.juneau.rest.client.RestClientBuilder#rootUrl(Object)} method can be used to specify a root URL on 
 				all requests so that you don't have to use absolute paths on individual calls.
 		</p>
 		<p class='bcode'>
 	<jc>// Create a rest client with a root URL</jc>
-	RestClient rc = <jk>new</jk> RestClient().setRootUrl(<js>"http://localhost:9080/foobar"</js>);
+	RestClient rc = <jk>new</jk> RestClientBuilder().rootUrl(<js>"http://localhost:9080/foobar"</js>).build();
 	String r = rc.doGet(<js>"/baz"</js>).getResponseAsString();  <jc>// Gets "http://localhost:9080/foobar/baz"</jc>
 		</p>
 		<p>
-			The {@link org.apache.juneau.rest.client.RestClient#setProperty(String,Object)} method can be used to set serializer
+			The {@link org.apache.juneau.rest.client.RestClientBuilder#property(String,Object)} method can be used to set serializer
 			and parser properties.
 			For example, if you're parsing a response into POJOs and you want to ignore fields that aren't on the
 			POJOs, you can use the {@link org.apache.juneau.BeanContext#BEAN_ignoreUnknownBeanProperties} property.
 		</p>
 		<p class='bcode'>
 	<jc>// Create a rest client that ignores unknown fields in the response</jc>
-	RestClient rc = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>)
-		.setProperty(<jsf>BEAN_ignoreUnknownBeanProperties</jsf>, <jk>true</jk>);
+	RestClient rc = <jk>new</jk> RestClientBuilder()
+		.property(<jsf>BEAN_ignoreUnknownBeanProperties</jsf>, <jk>true</jk>)
+		<jc>// or .ignoreUnknownBeanProperties(true)</jc>
+		.build();
 	MyPojo myPojo = rc.doGet(<jsf>URL</jsf>).getResponse(MyPojo.<jk>class</jk>);
 		</p>
 		<p>
-			The {@link org.apache.juneau.rest.client.RestCall#setRetryable(int,long,RetryOn)} method can be used to automatically
+			The {@link org.apache.juneau.rest.client.RestCall#retryable(int,long,RetryOn)} method can be used to automatically
 				retry requests on failures.
 			This can be particularly useful if you're attempting to connect to a REST resource that may be in
 				the process of still initializing.
@@ -848,7 +852,7 @@
 	<jc>// Create a rest call that retries every 10 seconds for up to 30 minutes as long as a connection fails
 	// or a 400+ is received.</jc>
 	restClient.doGet(<jsf>URL</jsf>)
-		.setRetryable(180, 10000, RetryOn.<jsf>DEFAULT</jsf>)
+		.retryable(180, 10000, RetryOn.<jsf>DEFAULT</jsf>)
 		.run();
 	</p>
 	</div>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
----------------------------------------------------------------------
diff --git a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
index 1a26708..4ee84be 100644
--- a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
+++ b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/BaseProvider.java
@@ -35,8 +35,8 @@ import org.apache.juneau.serializer.*;
  */
 public class BaseProvider implements MessageBodyReader<Object>, MessageBodyWriter<Object> {
 
-	private SerializerGroup serializers = new SerializerGroup();
-	private ParserGroup parsers = new ParserGroup();
+	private SerializerGroup serializers;
+	private ParserGroup parsers;
 	private ObjectMap properties = new ObjectMap();
 
 	/**
@@ -46,14 +46,24 @@ public class BaseProvider implements MessageBodyReader<Object>, MessageBodyWrite
 		try {
 			properties = new ObjectMap();
 			JuneauProvider jp = getClass().getAnnotation(JuneauProvider.class);
-			serializers.append(jp.serializers());
-			parsers.append(jp.parsers());
+			
 			for (Property p : jp.properties())
 				properties.put(p.name(), p.value());
-			serializers.addBeanFilters(jp.beanFilters());
-			parsers.addBeanFilters(jp.beanFilters());
-			serializers.addPojoSwaps(jp.pojoSwaps());
-			parsers.addPojoSwaps(jp.pojoSwaps());
+
+			serializers = new SerializerGroupBuilder()
+				.append(jp.serializers())
+				.beanFilters(jp.beanFilters())
+				.pojoSwaps(jp.pojoSwaps())
+				.properties(properties)
+				.build();
+
+			parsers = new ParserGroupBuilder() 
+				.append(jp.parsers())
+				.beanFilters(jp.beanFilters())
+				.pojoSwaps(jp.pojoSwaps())
+				.properties(properties)
+				.build();
+					
 		} catch (Exception e) {
 			throw new RuntimeException(e);
 		}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/DefaultProvider.java
----------------------------------------------------------------------
diff --git a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/DefaultProvider.java b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/DefaultProvider.java
index 92cc4a1..1407508 100644
--- a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/DefaultProvider.java
+++ b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/DefaultProvider.java
@@ -31,8 +31,8 @@ import org.apache.juneau.xml.*;
 	"application/json", "text/json",                 // JsonSerializer
 	"application/json+simple", "text/json+simple",   // JsonSerializer.Simple
 	"application/json+schema",                       // JsonSchemaSerializer
-	"text/xml",                                      // XmlDocSerializer
-	"text/xml+simple",                               // XmlDocSerializer.Simple
+	"text/xml",                                      // XmlDocSerializer.Ns
+	"text/xml+simple",                               // XmlDocSerializer
 	"text/xml+schema",                               // XmlSchemaDocSerializer
 	"text/html",                                     // HtmlDocSerializer
 	"application/x-www-form-urlencoded",             // UrlEncodingSerializer
@@ -51,20 +51,19 @@ import org.apache.juneau.xml.*;
 		JsonSerializer.class,
 		JsonSerializer.Simple.class,
 		JsonSchemaSerializer.class,
+		XmlDocSerializer.Ns.class,
 		XmlDocSerializer.class,
-		XmlDocSerializer.Simple.class,
 		XmlSchemaDocSerializer.class,
 		HtmlDocSerializer.class,
 		UrlEncodingSerializer.class,
 		SoapXmlSerializer.class,
-		JavaSerializedObjectSerializer.class
+		JsoSerializer.class
 	},
 	parsers={
 		JsonParser.class,
 		XmlParser.class,
 		HtmlParser.class,
 		UrlEncodingParser.class,
-		JavaSerializedObjectParser.class
 	}
 )
 public final class DefaultProvider extends BaseProvider {}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/rdf/DefaultJenaProvider.java
----------------------------------------------------------------------
diff --git a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/rdf/DefaultJenaProvider.java b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/rdf/DefaultJenaProvider.java
index e4208c9..5c60247 100644
--- a/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/rdf/DefaultJenaProvider.java
+++ b/juneau-rest-jaxrs/src/main/java/org/apache/juneau/rest/jaxrs/rdf/DefaultJenaProvider.java
@@ -33,8 +33,8 @@ import org.apache.juneau.xml.*;
 	"application/json", "text/json",                 // JsonSerializer
 	"application/json+simple","text/json+simple",    // JsonSerializer.Simple
 	"application/json+schema","text/json+schema",    // JsonSchemaSerializer
-	"text/xml",                                      // XmlDocSerializer
-	"text/xml+simple",                               // XmlDocSerializer.Simple
+	"text/xml",                                      // XmlDocSerializer.Ns
+	"text/xml+simple",                               // XmlDocSerializer
 	"text/xml+schema",                               // XmlSchemaDocSerializer
 	"text/html",                                     // HtmlDocSerializer
 	"application/x-www-form-urlencoded",             // UrlEncodingSerializer
@@ -62,8 +62,7 @@ import org.apache.juneau.xml.*;
 		JsonSerializer.class,
 		JsonSerializer.Simple.class,
 		JsonSchemaSerializer.class,
-		XmlDocSerializer.class,
-		XmlDocSerializer.Simple.class,
+		XmlDocSerializer.Ns.class,
 		XmlSchemaDocSerializer.class,
 		HtmlDocSerializer.class,
 		UrlEncodingSerializer.class,
@@ -73,7 +72,7 @@ import org.apache.juneau.xml.*;
 		RdfSerializer.NTriple.class,
 		RdfSerializer.Turtle.class,
 		RdfSerializer.N3.class,
-		JavaSerializedObjectSerializer.class
+		JsoSerializer.class
 	},
 	parsers={
 		JsonParser.class,
@@ -83,8 +82,7 @@ import org.apache.juneau.xml.*;
 		RdfParser.Xml.class,
 		RdfParser.NTriple.class,
 		RdfParser.Turtle.class,
-		RdfParser.N3.class,
-		JavaSerializedObjectParser.class,
+		RdfParser.N3.class
 	}
 )
 public final class DefaultJenaProvider extends BaseProvider {}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
index f1d04fa..ee3a172 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/AcceptCharsetResource.java
@@ -56,6 +56,11 @@ public class AcceptCharsetResource extends RestServlet {
 
 	@Consumes("text/plain")
 	public static class TestParser extends InputStreamParser {
+
+		public TestParser(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -65,6 +70,11 @@ public class AcceptCharsetResource extends RestServlet {
 
 	@Produces("text/plain")
 	public static class TestSerializer extends OutputStreamSerializer {
+
+		public TestSerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			Writer w = new OutputStreamWriter(session.getOutputStream());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
index 539f88d..4f9e6f3 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/CharsetEncodingsResource.java
@@ -33,6 +33,11 @@ public class CharsetEncodingsResource extends RestServlet {
 
 	@Consumes("text/p")
 	public static class CtParser extends ReaderParser {
+
+		public CtParser(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -42,6 +47,11 @@ public class CharsetEncodingsResource extends RestServlet {
 
 	@Produces("text/s")
 	public static class ASerializer extends WriterSerializer {
+
+		public ASerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write(o.toString());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
index 01dd128..73544e7 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/DefaultContentTypesResource.java
@@ -34,22 +34,22 @@ public class DefaultContentTypesResource extends RestServlet {
 	private static final long serialVersionUID = 1L;
 
 	@Consumes("text/p1")
-	public static class P1 extends DummyParser { public P1() {super("p1");}}
+	public static class P1 extends DummyParser { public P1(PropertyStore ps) {super(ps, "p1");}}
 
 	@Consumes("text/p2")
-	public static class P2 extends DummyParser { public P2() {super("p2");}}
+	public static class P2 extends DummyParser { public P2(PropertyStore ps) {super(ps, "p2");}}
 
 	@Consumes("text/p3")
-	public static class P3 extends DummyParser { public P3() {super("p3");}}
+	public static class P3 extends DummyParser { public P3(PropertyStore ps) {super(ps, "p3");}}
 
 	@Produces("text/s1")
-	public static class S1 extends DummySerializer { public S1() {super("s1");}}
+	public static class S1 extends DummySerializer { public S1(PropertyStore ps) {super(ps, "s1");}}
 
 	@Produces("text/s2")
-	public static class S2 extends DummySerializer { public S2() {super("s2");}}
+	public static class S2 extends DummySerializer { public S2(PropertyStore ps) {super(ps, "s2");}}
 
 	@Produces("text/s3")
-	public static class S3 extends DummySerializer { public S3() {super("s3");}}
+	public static class S3 extends DummySerializer { public S3(PropertyStore ps) {super(ps, "s3");}}
 
 	/**
 	 * Test that default Accept and Content-Type headers on servlet annotation are picked up.
@@ -104,10 +104,14 @@ public class DefaultContentTypesResource extends RestServlet {
 	}
 
 	public static class DummyParser extends ReaderParser {
+
 		private String name;
-		private DummyParser(String name) {
+
+		private DummyParser(PropertyStore propertyStore, String name) {
+			super(propertyStore);
 			this.name = name;
 		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -116,10 +120,14 @@ public class DefaultContentTypesResource extends RestServlet {
 	}
 
 	public static class DummySerializer extends WriterSerializer {
+
 		private String name;
-		private DummySerializer(String name) {
+
+		private DummySerializer(PropertyStore propertyStore, String name) {
+			super(propertyStore);
 			this.name = name;
 		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object output) throws Exception {
 			session.getWriter().write(name + "/" + output);



[16/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
index abd00f5..a655048 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/Serializer.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.serializer;
 
-import static org.apache.juneau.serializer.SerializerContext.*;
-
 import java.io.*;
 import java.lang.reflect.*;
 import java.text.*;
@@ -39,18 +37,18 @@ import org.apache.juneau.soap.*;
  * <p>
  * However, the media types can also be specified programmatically by overriding the {@link #getMediaTypes()}
  * 	and {@link #getResponseContentType()} methods.
- *
- * <h5 class='section'>Configurable properties:</h5>
- * See {@link SerializerContext} for a list of configurable properties that can be set on this class
- * 	using the {@link #setProperty(String, Object)} method.
  */
-public abstract class Serializer extends CoreApi {
+public abstract class Serializer extends CoreObject {
 
 	private final MediaType[] mediaTypes;
 	private final MediaType contentType;
+	private final SerializerContext ctx;
 
 	// Hidden constructors to force subclass from OuputStreamSerializer or WriterSerializer.
-	Serializer() {
+	Serializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(SerializerContext.class);
+
 		Produces p = ReflectionUtils.getAnnotation(Produces.class, getClass());
 		if (p == null)
 			throw new RuntimeException(MessageFormat.format("Class ''{0}'' is missing the @Produces annotation", getClass().getName()));
@@ -65,10 +63,15 @@ public abstract class Serializer extends CoreApi {
 		contentType = ct.isEmpty() ? null : MediaType.forString(ct);
 	}
 
+	@Override /* CoreObject */
+	public SerializerBuilder builder() {
+		return new SerializerBuilder(propertyStore);
+	}
+
 	/**
-	 * Returns <jk>true</jk> if this parser subclasses from {@link WriterSerializer}.
+	 * Returns <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
 	 *
-	 * @return <jk>true</jk> if this parser subclasses from {@link WriterSerializer}.
+	 * @return <jk>true</jk> if this serializer subclasses from {@link WriterSerializer}.
 	 */
 	public abstract boolean isWriterSerializer();
 
@@ -182,7 +185,7 @@ public abstract class Serializer extends CoreApi {
 	 * @return The new session.
 	 */
 	public SerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new SerializerSession(getContext(SerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new SerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 
 	/**
@@ -245,7 +248,7 @@ public abstract class Serializer extends CoreApi {
 	}
 
 	/**
-	 * Returns the first media type specified on this parser via the {@link Produces} annotation.
+	 * Returns the first media type specified on this serializer via the {@link Produces} annotation.
 	 *
 	 * @return The media type.
 	 */
@@ -284,863 +287,4 @@ public abstract class Serializer extends CoreApi {
 	public MediaType getResponseContentType() {
 		return contentType;
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Max serialization depth.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.maxDepth"</js>
-	 * 	<li><b>Data type:</b> <code>Integer</code>
-	 * 	<li><b>Default:</b> <code>100</code>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Abort serialization if specified depth is reached in the POJO tree.
-	 * If this depth is exceeded, an exception is thrown.
-	 * This prevents stack overflows from occurring when trying to serialize models with recursive references.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_maxDepth</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_maxDepth
-	 */
-	public Serializer setMaxDepth(int value) throws LockedException {
-		return setProperty(SERIALIZER_maxDepth, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Initial depth.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.initialDepth"</js>
-	 * 	<li><b>Data type:</b> <code>Integer</code>
-	 * 	<li><b>Default:</b> <code>0</code>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * The initial indentation level at the root.
-	 * Useful when constructing document fragments that need to be indented at a certain level.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_initialDepth</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_initialDepth
-	 */
-	public Serializer setInitialDepth(int value) throws LockedException {
-		return setProperty(SERIALIZER_initialDepth, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Automatically detect POJO recursions.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.detectRecursions"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Specifies that recursions should be checked for during serialization.
-	 * <p>
-	 * Recursions can occur when serializing models that aren't true trees, but rather contain loops.
-	 * <p>
-	 * The behavior when recursions are detected depends on the value for {@link SerializerContext#SERIALIZER_ignoreRecursions}.
-	 * <p>
-	 * For example, if a model contains the links A-&gt;B-&gt;C-&gt;A, then the JSON generated will look like
-	 * 	the following when <jsf>SERIALIZER_ignoreRecursions</jsf> is <jk>true</jk>...
-	 * <code>{A:{B:{C:null}}}</code><br>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_detectRecursions</jsf>, value)</code>.
-	 * 	<li>Checking for recursion can cause a small performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_detectRecursions
-	 */
-	public Serializer setDetectRecursions(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_detectRecursions, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Ignore recursion errors.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.ignoreRecursions"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Used in conjunction with {@link SerializerContext#SERIALIZER_detectRecursions}.
-	 * Setting is ignored if <jsf>SERIALIZER_detectRecursions</jsf> is <jk>false</jk>.
-	 * <p>
-	 * If <jk>true</jk>, when we encounter the same object when serializing a tree,
-	 * 	we set the value to <jk>null</jk>.
-	 * Otherwise, an exception is thrown.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_ignoreRecursions</jsf>, value)</code>.
-	 * 	<li>Checking for recursion can cause a small performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_ignoreRecursions
-	 */
-	public Serializer setIgnoreRecursions(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_ignoreRecursions, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Use whitespace.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.useWhitepace"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, newlines and indentation and spaces are added to the output to improve readability.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_useWhitespace</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_useWhitespace
-	 */
-	public Serializer setUseWhitespace(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_useWhitespace, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add <js>"_type"</js> properties when needed.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.addBeanTypeProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred through reflection.
-	 * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
-	 * For example, when serializing a {@code Map<String,Object>} field, where the bean class cannot be determined from the value type.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_addBeanTypeProperties</jsf>, value)</code>.
-	 * 	<li>Checking for recursion can cause a small performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_addBeanTypeProperties
-	 */
-	public Serializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_addBeanTypeProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Quote character.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.quoteChar"</js>
-	 * 	<li><b>Data type:</b> <code>Character</code>
-	 * 	<li><b>Default:</b> <js>'"'</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * This is the character used for quoting attributes and values.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_quoteChar</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_quoteChar
-	 */
-	public Serializer setQuoteChar(char value) throws LockedException {
-		return setProperty(SERIALIZER_quoteChar, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Trim null bean property values.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.trimNullProperties"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, null bean values will not be serialized to the output.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_trimNullProperties</jsf>, value)</code>.
-	 * 	<li>Enabling this setting has the following effects on parsing:
-	 * 	<ul>
-	 * 		<li>Map entries with <jk>null</jk> values will be lost.
-	 * 	</ul>
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimNullProperties
-	 */
-	public Serializer setTrimNullProperties(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_trimNullProperties, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Trim empty lists and arrays.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.trimEmptyLists"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, empty list values will not be serialized to the output.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_trimEmptyCollections</jsf>, value)</code>.
-	 * 	<li>Enabling this setting has the following effects on parsing:
-	 * 	<ul>
-	 * 		<li>Map entries with empty list values will be lost.
-	 * 		<li>Bean properties with empty list values will not be set.
-	 * 	</ul>
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimEmptyCollections
-	 */
-	public Serializer setTrimEmptyCollections(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_trimEmptyCollections, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Trim empty maps.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.trimEmptyMaps"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, empty map values will not be serialized to the output.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_trimEmptyMaps</jsf>, value)</code>.
-	 * 	<li>Enabling this setting has the following effects on parsing:
-	 * 	<ul>
-	 * 		<li>Bean properties with empty map values will not be set.
-	 * 	</ul>
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimEmptyMaps
-	 */
-	public Serializer setTrimEmptyMaps(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_trimEmptyMaps, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Trim strings.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.trimStrings"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_trimStrings</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_trimStrings
-	 */
-	public Serializer setTrimStrings(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_trimStrings, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  URI base for relative URIs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.relativeUriBase"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>""</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Prepended to relative URIs during serialization (along with the {@link SerializerContext#SERIALIZER_absolutePathUriBase} if specified.
-	 * (i.e. URIs not containing a schema and not starting with <js>'/'</js>).
-	 * (e.g. <js>"foo/bar"</js>)
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <table class='styled'>
-	 * 	<tr><th>SERIALIZER_relativeUriBase</th><th>URI</th><th>Serialized URI</th></tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>mywebapp</code></td>
-	 * 		<td><code>http://foo:9080/bar/baz/mywebapp</code></td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>/mywebapp</code></td>
-	 * 		<td><code>/mywebapp</code></td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>http://mywebapp</code></td>
-	 * 		<td><code>http://mywebapp</code></td>
-	 * 	</tr>
-	 * </table>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_relativeUriBase</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_relativeUriBase
-	 */
-	public Serializer setRelativeUriBase(String value) throws LockedException {
-		return setProperty(SERIALIZER_relativeUriBase, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  URI base for relative URIs with absolute paths.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.absolutePathUriBase"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>""</js>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Prepended to relative absolute-path URIs during serialization.
-	 * (i.e. URIs starting with <js>'/'</js>).
-	 * (e.g. <js>"/foo/bar"</js>)
-	 *
-	 * <h5 class='section'>Examples:</h5>
-	 * <table class='styled'>
-	 * 	<tr><th>SERIALIZER_absolutePathUriBase</th><th>URI</th><th>Serialized URI</th></tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>mywebapp</code></td>
-	 * 		<td><code>mywebapp</code></td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>/mywebapp</code></td>
-	 * 		<td><code>http://foo:9080/bar/baz/mywebapp</code></td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td><code>http://foo:9080/bar/baz</code></td>
-	 * 		<td><code>http://mywebapp</code></td>
-	 * 		<td><code>http://mywebapp</code></td>
-	 * 	</tr>
-	 * </table>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_absolutePathUriBase</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_absolutePathUriBase
-	 */
-	public Serializer setAbsolutePathUriBase(String value) throws LockedException {
-		return setProperty(SERIALIZER_absolutePathUriBase, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Sort arrays and collections alphabetically.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.sortCollections"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_sortCollections</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_sortCollections
-	 */
-	public Serializer setSortCollections(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_sortCollections, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Sort maps alphabetically.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Serializer.sortMaps"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>SERIALIZER_sortMaps</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_sortMaps
-	 */
-	public Serializer setSortMaps(boolean value) throws LockedException {
-		return setProperty(SERIALIZER_sortMaps, value);
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public Serializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public Serializer clone() throws CloneNotSupportedException {
-		Serializer c = (Serializer)super.clone();
-		return c;
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
new file mode 100644
index 0000000..a059d46
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerBuilder.java
@@ -0,0 +1,896 @@
+// ***************************************************************************************************************************
+// * 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.serializer;
+
+import static org.apache.juneau.serializer.SerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+
+/**
+ * Builder class for building instances of serializers.
+ */
+public class SerializerBuilder extends CoreObjectBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public SerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public SerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public Serializer build() {
+		return null;
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Max serialization depth.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.maxDepth"</js>
+	 * 	<li><b>Data type:</b> <code>Integer</code>
+	 * 	<li><b>Default:</b> <code>100</code>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Abort serialization if specified depth is reached in the POJO tree.
+	 * If this depth is exceeded, an exception is thrown.
+	 * This prevents stack overflows from occurring when trying to serialize models with recursive references.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_maxDepth</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_maxDepth
+	 */
+	public SerializerBuilder maxDepth(int value) {
+		return property(SERIALIZER_maxDepth, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Initial depth.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.initialDepth"</js>
+	 * 	<li><b>Data type:</b> <code>Integer</code>
+	 * 	<li><b>Default:</b> <code>0</code>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * The initial indentation level at the root.
+	 * Useful when constructing document fragments that need to be indented at a certain level.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_initialDepth</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_initialDepth
+	 */
+	public SerializerBuilder initialDepth(int value) {
+		return property(SERIALIZER_initialDepth, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Automatically detect POJO recursions.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.detectRecursions"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Specifies that recursions should be checked for during serialization.
+	 * <p>
+	 * Recursions can occur when serializing models that aren't true trees, but rather contain loops.
+	 * <p>
+	 * The behavior when recursions are detected depends on the value for {@link SerializerContext#SERIALIZER_ignoreRecursions}.
+	 * <p>
+	 * For example, if a model contains the links A-&gt;B-&gt;C-&gt;A, then the JSON generated will look like
+	 * 	the following when <jsf>SERIALIZER_ignoreRecursions</jsf> is <jk>true</jk>...
+	 * <code>{A:{B:{C:null}}}</code><br>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_detectRecursions</jsf>, value)</code>.
+	 * 	<li>Checking for recursion can cause a small performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_detectRecursions
+	 */
+	public SerializerBuilder detectRecursions(boolean value) {
+		return property(SERIALIZER_detectRecursions, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Ignore recursion errors.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.ignoreRecursions"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Used in conjunction with {@link SerializerContext#SERIALIZER_detectRecursions}.
+	 * Setting is ignored if <jsf>SERIALIZER_detectRecursions</jsf> is <jk>false</jk>.
+	 * <p>
+	 * If <jk>true</jk>, when we encounter the same object when serializing a tree,
+	 * 	we set the value to <jk>null</jk>.
+	 * Otherwise, an exception is thrown.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_ignoreRecursions</jsf>, value)</code>.
+	 * 	<li>Checking for recursion can cause a small performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_ignoreRecursions
+	 */
+	public SerializerBuilder ignoreRecursions(boolean value) {
+		return property(SERIALIZER_ignoreRecursions, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Use whitespace.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.useWhitepace"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, newlines and indentation and spaces are added to the output to improve readability.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_useWhitespace</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_useWhitespace
+	 */
+	public SerializerBuilder useWhitespace(boolean value) {
+		return property(SERIALIZER_useWhitespace, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>useWhitespace(<jk>true</jk>)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public SerializerBuilder ws() {
+		return useWhitespace(true);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add <js>"_type"</js> properties when needed.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.addBeanTypeProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, then <js>"_type"</js> properties will be added to beans if their type cannot be inferred through reflection.
+	 * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
+	 * For example, when serializing a {@code Map<String,Object>} field, where the bean class cannot be determined from the value type.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_addBeanTypeProperties</jsf>, value)</code>.
+	 * 	<li>Checking for recursion can cause a small performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_addBeanTypeProperties
+	 */
+	public SerializerBuilder addBeanTypeProperties(boolean value) {
+		return property(SERIALIZER_addBeanTypeProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Quote character.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.quoteChar"</js>
+	 * 	<li><b>Data type:</b> <code>Character</code>
+	 * 	<li><b>Default:</b> <js>'"'</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * This is the character used for quoting attributes and values.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_quoteChar</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_quoteChar
+	 */
+	public SerializerBuilder quoteChar(char value) {
+		return property(SERIALIZER_quoteChar, value);
+	}
+
+	/**
+	 * Shortcut for calling <code>quoteChar(<js>'\''</js>)</code>.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public SerializerBuilder sq() {
+		return quoteChar('\'');
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Trim null bean property values.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.trimNullProperties"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, null bean values will not be serialized to the output.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_trimNullProperties</jsf>, value)</code>.
+	 * 	<li>Enabling this setting has the following effects on parsing:
+	 * 	<ul>
+	 * 		<li>Map entries with <jk>null</jk> values will be lost.
+	 * 	</ul>
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimNullProperties
+	 */
+	public SerializerBuilder trimNullProperties(boolean value) {
+		return property(SERIALIZER_trimNullProperties, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Trim empty lists and arrays.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.trimEmptyLists"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, empty list values will not be serialized to the output.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_trimEmptyCollections</jsf>, value)</code>.
+	 * 	<li>Enabling this setting has the following effects on parsing:
+	 * 	<ul>
+	 * 		<li>Map entries with empty list values will be lost.
+	 * 		<li>Bean properties with empty list values will not be set.
+	 * 	</ul>
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyCollections
+	 */
+	public SerializerBuilder trimEmptyCollections(boolean value) {
+		return property(SERIALIZER_trimEmptyCollections, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Trim empty maps.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.trimEmptyMaps"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, empty map values will not be serialized to the output.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_trimEmptyMaps</jsf>, value)</code>.
+	 * 	<li>Enabling this setting has the following effects on parsing:
+	 * 	<ul>
+	 * 		<li>Bean properties with empty map values will not be set.
+	 * 	</ul>
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimEmptyMaps
+	 */
+	public SerializerBuilder trimEmptyMaps(boolean value) {
+		return property(SERIALIZER_trimEmptyMaps, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Trim strings.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.trimStrings"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_trimStrings</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_trimStrings
+	 */
+	public SerializerBuilder trimStrings(boolean value) {
+		return property(SERIALIZER_trimStrings, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  URI base for relative URIs.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.relativeUriBase"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>""</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Prepended to relative URIs during serialization (along with the {@link SerializerContext#SERIALIZER_absolutePathUriBase} if specified.
+	 * (i.e. URIs not containing a schema and not starting with <js>'/'</js>).
+	 * (e.g. <js>"foo/bar"</js>)
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <table class='styled'>
+	 * 	<tr><th>SERIALIZER_relativeUriBase</th><th>URI</th><th>Serialized URI</th></tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>mywebapp</code></td>
+	 * 		<td><code>http://foo:9080/bar/baz/mywebapp</code></td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>/mywebapp</code></td>
+	 * 		<td><code>/mywebapp</code></td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>http://mywebapp</code></td>
+	 * 		<td><code>http://mywebapp</code></td>
+	 * 	</tr>
+	 * </table>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_relativeUriBase</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_relativeUriBase
+	 */
+	public SerializerBuilder relativeUriBase(String value) {
+		return property(SERIALIZER_relativeUriBase, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  URI base for relative URIs with absolute paths.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.absolutePathUriBase"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>""</js>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Prepended to relative absolute-path URIs during serialization.
+	 * (i.e. URIs starting with <js>'/'</js>).
+	 * (e.g. <js>"/foo/bar"</js>)
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <table class='styled'>
+	 * 	<tr><th>SERIALIZER_absolutePathUriBase</th><th>URI</th><th>Serialized URI</th></tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>mywebapp</code></td>
+	 * 		<td><code>mywebapp</code></td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>/mywebapp</code></td>
+	 * 		<td><code>http://foo:9080/bar/baz/mywebapp</code></td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td><code>http://foo:9080/bar/baz</code></td>
+	 * 		<td><code>http://mywebapp</code></td>
+	 * 		<td><code>http://mywebapp</code></td>
+	 * 	</tr>
+	 * </table>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_absolutePathUriBase</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_absolutePathUriBase
+	 */
+	public SerializerBuilder absolutePathUriBase(String value) {
+		return property(SERIALIZER_absolutePathUriBase, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Sort arrays and collections alphabetically.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.sortCollections"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_sortCollections</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortCollections
+	 */
+	public SerializerBuilder sortCollections(boolean value) {
+		return property(SERIALIZER_sortCollections, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Sort maps alphabetically.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Serializer.sortMaps"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SERIALIZER_sortMaps</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortMaps
+	 */
+	public SerializerBuilder sortMaps(boolean value) {
+		return property(SERIALIZER_sortMaps, value);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CoreObjectBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
index ba93403..f3ea90f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/SerializerContext.java
@@ -332,25 +332,25 @@ public class SerializerContext extends BeanContext {
 	/**
 	 * Constructor.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public SerializerContext(ContextFactory cf) {
-		super(cf);
-		maxDepth = cf.getProperty(SERIALIZER_maxDepth, int.class, 100);
-		initialDepth = cf.getProperty(SERIALIZER_initialDepth, int.class, 0);
-		detectRecursions = cf.getProperty(SERIALIZER_detectRecursions, boolean.class, false);
-		ignoreRecursions = cf.getProperty(SERIALIZER_ignoreRecursions, boolean.class, false);
-		useWhitespace = cf.getProperty(SERIALIZER_useWhitespace, boolean.class, false);
-		addBeanTypeProperties = cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true);
-		trimNulls = cf.getProperty(SERIALIZER_trimNullProperties, boolean.class, true);
-		trimEmptyCollections = cf.getProperty(SERIALIZER_trimEmptyCollections, boolean.class, false);
-		trimEmptyMaps = cf.getProperty(SERIALIZER_trimEmptyMaps, boolean.class, false);
-		trimStrings = cf.getProperty(SERIALIZER_trimStrings, boolean.class, false);
-		sortCollections = cf.getProperty(SERIALIZER_sortCollections, boolean.class, false);
-		sortMaps = cf.getProperty(SERIALIZER_sortMaps, boolean.class, false);
-		quoteChar = cf.getProperty(SERIALIZER_quoteChar, String.class, "\"").charAt(0);
-		relativeUriBase = resolveRelativeUriBase(cf.getProperty(SERIALIZER_relativeUriBase, String.class, ""));
-		absolutePathUriBase = resolveAbsolutePathUriBase(cf.getProperty(SERIALIZER_absolutePathUriBase, String.class, ""));
+	public SerializerContext(PropertyStore ps) {
+		super(ps);
+		maxDepth = ps.getProperty(SERIALIZER_maxDepth, int.class, 100);
+		initialDepth = ps.getProperty(SERIALIZER_initialDepth, int.class, 0);
+		detectRecursions = ps.getProperty(SERIALIZER_detectRecursions, boolean.class, false);
+		ignoreRecursions = ps.getProperty(SERIALIZER_ignoreRecursions, boolean.class, false);
+		useWhitespace = ps.getProperty(SERIALIZER_useWhitespace, boolean.class, false);
+		addBeanTypeProperties = ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true);
+		trimNulls = ps.getProperty(SERIALIZER_trimNullProperties, boolean.class, true);
+		trimEmptyCollections = ps.getProperty(SERIALIZER_trimEmptyCollections, boolean.class, false);
+		trimEmptyMaps = ps.getProperty(SERIALIZER_trimEmptyMaps, boolean.class, false);
+		trimStrings = ps.getProperty(SERIALIZER_trimStrings, boolean.class, false);
+		sortCollections = ps.getProperty(SERIALIZER_sortCollections, boolean.class, false);
+		sortMaps = ps.getProperty(SERIALIZER_sortMaps, boolean.class, false);
+		quoteChar = ps.getProperty(SERIALIZER_quoteChar, String.class, "\"").charAt(0);
+		relativeUriBase = resolveRelativeUriBase(ps.getProperty(SERIALIZER_relativeUriBase, String.class, ""));
+		absolutePathUriBase = resolveAbsolutePathUriBase(ps.getProperty(SERIALIZER_absolutePathUriBase, String.class, ""));
 	}
 
 	private String resolveRelativeUriBase(String s) {


[06/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/javadoc/overview.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/javadoc/overview.html b/juneau-core/src/main/javadoc/overview.html
index b7a5b01..bab4158 100644
--- a/juneau-core/src/main/javadoc/overview.html
+++ b/juneau-core/src/main/javadoc/overview.html
@@ -341,13 +341,10 @@
 	String json = JsonSerializer.<jsf>DEFAULT</jsf>.serialize(someObject);
 
 	<jc>// Create a custom serializer for lax syntax using single quote characters</jc>
-	JsonSerializer serializer = <jk>new</jk> JsonSerializer()
-		.setSimpleMode(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	JsonSerializer serializer = <jk>new</jk> JsonSerializerBuilder().simple().sq().build();
 	
 	<jc>// Clone an existing serializer and modify it to use single-quotes</jc>
-	JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.clone()
-		.setQuoteChar(<js>'\''</js>);
+	JsonSerializer serializer = JsonSerializer.<jsf>DEFAULT</jsf>.builder().sq().build();
 	
 	<jc>// Serialize a POJO to JSON</jc>
 	String json = serializer.serialize(someObject);
@@ -454,19 +451,21 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Construct a new serializer group with configuration parameters that get applied to all serializers.</jc>
-	SerializerGroup sg = <jk>new</jk> SerializerGroup()
+	SerializerGroup sg = <jk>new</jk> SerializerGroupBuilder()
 		.append(JsonSerializer.<jk>class</jk>, UrlEncodingSerializer.<jk>class</jk>);
-		.setUseIndentation(<jk>true</jk>)
-		.addPojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>);
+		.ws   <jc>// or .useWhitespace(true)</jc>
+		.pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>)
+		.build();
 
 	<jc>// Find the appropriate serializer by Accept type and serialize our POJO to the specified writer.</jc>
 	sg.getSerializer(<js>"text/invalid, text/json;q=0.8, text/*;q:0.6, *\/*;q=0.0"</js>)
 		.serialize(myPersonObject, myWriter);
 		
 	<jc>// Construct a new parser group with configuration parameters that get applied to all parsers.</jc>
-	ParserGroup pg = <jk>new</jk> ParserGroup()
+	ParserGroup pg = <jk>new</jk> ParserGroupBuilder()
 		.append(JsonSerializer.<jk>class</jk>, UrlEncodingSerializer.<jk>class</jk>);
- 		.addTransforms(CalendarSwap.ISO8601DT.<jk>class</jk>);
+ 		.pojoSwaps(CalendarSwap.ISO8601DT.<jk>class</jk>)
+ 		.build();
 
 	Person p = pg.getParser(<js>"text/json"</js>).parse(myReader, Person.<jk>class</jk>);
 		</p>
@@ -556,11 +555,7 @@
 			For example, the following code shows how to configure a JSON serializer:
 		</p>
 		<p class='bcode'>
-	JsonSerializer s = <jk>new</jk> JsonSerializer()
-		.setUseIndentation(<jk>true</jk>)
-		.setUseWhitespace(<jk>true</jk>)
-		.setSimpleMode(<jk>true</jk>)
-		.setQuoteChar(<js>'\''</js>);
+	JsonSerializer s = <jk>new</jk> JsonSerializerBuilder().simple().ws().sq().build();
 		</p>
 		<p>
 			However, each of the serializers and parsers already contain reusable instances with common configurations.<br>
@@ -594,8 +589,9 @@
 		<p class='bcode'>
 	<jc>// Clone and customize an existing serializer.</jc>
 	JsonSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>
-		.clone()
-		.setQuoteChar(<js>'"'</js>);
+		.builder()
+		.quoteChar(<js>'"'</js>)
+		.build();
 
 	<jc>// Lock it so that the configuration cannot be changed.</jc>
 	s.lock();
@@ -721,11 +717,11 @@
 	}
 
 	<jc>// Create a new JSON serializer, associate our date swap with it, and serialize a sample bean.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build();
 	String json = serializer.serialize(<jk>new</jk> MyBean());	<jc>// == "{date:'2012-03-03T04:05:06-0500'}"</jc>
 	
 	<jc>// Create a JSON parser, associate our date swap with it, and reconstruct our bean (including the date).</jc>
-	ReaderParser parser = <jk>new</jk> JsonParser().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+	ReaderParser parser = <jk>new</jk> JsonParserBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build();
 	MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
 	<jk>int</jk> day = bean.<jf>date</jf>.getDay(); 						<jc>// == 3</jc>
 			</p>
@@ -921,12 +917,12 @@
 	}	
 			</p>		
 			<p>
-				Bean filters are added to serializers and parsers using the <code>addBeanFilters(Class...)</code> method.
+				Bean filters are added to serializers and parsers using the <code>*BeanFilters(Class...)</code> methods.
 				For example:
 			</p>
 			<p class='bcode'>			
 	<jc>// Create a new JSON serializer and associate a bean filter with it.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addBeanFilters(MyAddressBeanFilter.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyAddressBeanFilter.<jk>class</jk>).build();
 			</p>
 			<p>
 				Note that if you use the annotation, you do NOT need to set anything on the serializers/parsers.
@@ -952,7 +948,7 @@
 	}
 	
 	<jc>// Create a new JSON serializer that only exposes street,city,state on Address bean.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addBeanFilters(AddressInterface.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().beanFilters(AddressInterface.<jk>class</jk>).build();
 			</p>
 			
 			<h6 class='topic'>Additional Information</h6>
@@ -1031,7 +1027,7 @@
 		</p>
 		<ul>
 			<li>On individual bean properties through the {@link org.apache.juneau.annotation.BeanProperty#beanDictionary() @BeanProperty.beanDictionary()} annotation.
-			<li>Globally for a parser using the {@link org.apache.juneau.parser.Parser#addToBeanDictionary(Class...)} method.
+			<li>Globally for a parser using the {@link org.apache.juneau.parser.ParserBuilder#beanDictionary(Class...)} method.
 		</ul>
 		<p class='info'>
 			Type names do not need to be universally unique.  
@@ -1142,8 +1138,8 @@
 				<td style='text-align:center'>2a</td>
 				<td>
 					<b>With standard keys/values</b><br>
-					Map keys are group [1, 4a, 5] objects.<br>
-					Map, Collection, and array values are group [1, 2, 3a, 4a, 5] objects.	
+					Map keys are group [1, 4a, 5a] objects.<br>
+					Map, Collection, and array values are group [1, 2, 3a, 4a, 5a] objects.	
 				</td>
 				<td>
 					<ul class='normal'>
@@ -1160,8 +1156,8 @@
 				<td style='text-align:center'>2b</td>
 				<td>
 					<b>With non-standard keys/values</b><br>
-					Map keys are group [2, 3, 4b, 5, 6] objects.<br>
-					Map, Collection, and array values are group [3b, 4, 5, 6] objects.	
+					Map keys are group [2, 3, 4b, 5b, 6] objects.<br>
+					Map, Collection, and array values are group [3b, 4b, 5b, 6] objects.	
 				</td>
 				<td>
 					<ul class='normal'>
@@ -1184,7 +1180,7 @@
 				<td>
 					<b>With standard properties</b><br>
 					These are beans that have no-arg constructors and one or more properties defined by public getter and setter methods or public fields.<br>
-					Property values are group [1, 2, 3a, 4a, 5] objects.
+					Property values are group [1, 2, 3a, 4a, 5a] objects.
 				</td>
 				<td>&nbsp;</td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
@@ -1195,7 +1191,7 @@
 				<td>
 					<b>With non-standard properties or not true beans</b><br>
 					These include true beans that have no-arg constructors and one or more properties defined by getter and setter methods or properties, 
-						but property types include group [3b, 4b, 5, 6] objects.<br>
+						but property types include group [3b, 4b, 5b, 6] objects.<br>
 					This also includes classes that look like beans but aren't true beans.  
 					For example, classes that have getters but not setters, or classes without no-arg constructors.	
 				</td>
@@ -1222,7 +1218,12 @@
 					<b>2-way swapped to group [1, 2a, 3a] objects</b><br>
 					For example, a swap that converts a {@code Date} to a {@code String}.
 				</td>
-				<td>&nbsp;</td>
+				<td>
+					<ul class='normal'>
+						<li><code>java.util.Date</code>
+						<li><code>java.util.GregorianCalendar</code>
+					</ul>
+				</td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
 			</tr>			
@@ -1233,14 +1234,18 @@
 					For example, a swap that converts an {@code Iterator} to a {@code List}.  
 					This would be one way, since you cannot reconstruct an {@code Iterator}.
 				</td>
-				<td>&nbsp;</td>
+				<td>
+					<ul class='normal'>
+						<li><code>java.util.Iterator</code>
+					</ul>
+				</td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
 				<td style='background-color:salmon;text-align:center'><b>no</b></td>
 			</tr>		
 			<tr class='dark bb' style='background-color:lightyellow'>
 				<td style='text-align:center'>5</td>
 				<td>
-					<b>Objects with standardized static methods and/or constructors for converting to another POJO that's serializable.</b><br>
+					<b>Non-serializable objects with standard methods for converting to a serializable form</b><br>
 				</td>
 				<td>&nbsp;</td>
 				<td>&nbsp;</td>
@@ -1249,25 +1254,51 @@
 			<tr class='light bb' style='background-color:lightyellow'>
 				<td style='text-align:center'>5a</td>
 				<td>
-					<b>Objects with standardized <code>static T valueOf(String)</code>/<code>static T fromString(String)</code> methods, or constructors with a <code>String</code> argument.</b><br>
-					During serialization, objects are converted to strings using the <code>toString()</code> method.
-					During parsing, strings are converted to objects using one of these static methods or constructors.				
+					Classes with a method that converts it to a serializable form:
+					<ul>
+						<li><code><jk>public</jk> X swap(BeanSession);</code> where <code>X</code> is in groups [1, 2a, 3a].
+						<li><code><jk>public</jk> String toString();</code> where the string is any meaningful data.
+					</ul>
+					And a method that converts it back into the original object:
+					<ul>
+						<li><code><jk>public static</jk> T fromString(String);</code>		
+						<li><code><jk>public static</jk> T valueOf(String);</code>		
+						<li><code><jk>public static</jk> T parse(String);</code>		
+						<li><code><jk>public static</jk> T parseString(String);</code>		
+						<li><code><jk>public static</jk> T forName(String);</code>		
+						<li><code><jk>public static</jk> T forString(String);</code>		
+						<li><code><jk>public</jk> T(X);</code> where <code>X</code> is in groups [1, 2a, 3a].
+						<li><code><jk>public static</jk> T unswap(BeanSession,X);</code> where <code>X</code> is in groups [1, 2a, 3a].		
+					</ul>
+				</td>
+				<td>
+					<ul class='normal'>
+						<li><code>java.lang.Class</code>
+						<li><code>java.sql.Time</code>
+						<li><code>java.sql.Timestamp</code>
+						<li><code>java.text.MessageFormat</code>
+						<li><code>java.text.NumberFormat</code>
+						<li><code>java.util.Date</code>
+						<li><code>java.util.UUID</code>
+						<li><code>java.util.logging.Level</code>
+						<li><code>javax.xml.bind.DatatypeConverter</code>
+					</ul>
 				</td>
-				<td><code>java.util.UUID</code></td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
 			</tr>		
 			<tr class='light bb' style='background-color:lightyellow'>
 				<td style='text-align:center'>5b</td>
 				<td>
-					<b>Objects with standardized <code>Object swap(BeanSession)</code>/<code>static T unswap(BeanSession,Object)</code> methods, or constructors with an <code>Object</code> argument
-					where the objects are any object on this list.</b><br> 
-					During serialization, normal objects are converted to swapped objects using the <code>swap()</code> method.
-					During parsing, swapped objects are converted to normal objects using the static method or constructor.				
+					Classes that only have a method to convert to a serializable form:
+					<ul>
+						<li><code><jk>public</jk> X swap(BeanSession);</code> where <code>X</code> is in groups [1, 2, 3].
+						<li><code><jk>public</jk> String toString();</code> where the string is any meaningful data.
+					</ul>
 				</td>
 				<td>&nbsp;</td>
 				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
-				<td style='background-color:lightgreen;text-align:center'><b>yes</b></td>
+				<td style='background-color:salmon;text-align:center'><b>no</b></td>
 			</tr>			
 			<tr class='dark' style='background-color:lightyellow'>
 				<td style='text-align:center'>6</td>
@@ -1692,7 +1723,7 @@
 		<h6 class='figure'>Example with no namespaces</h6>
 		<p class='bcode'>
 	<jc>// Create a serializer with readable output, no namespaces yet.</jc>
-	XmlSerializer s = <jk>new</jk> XmlSerializer.SqReadable();
+	XmlSerializer s = <jk>new</jk> XmlSerializerBuilder().sq().ws().build();
 
 	<jc>// Serialize to ATOM/XML</jc>
 	String atomXml = s.serialize(feed);
@@ -2180,7 +2211,7 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a reusable JSON client.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>);
+	RestClient client = <jk>new</jk> RestClientBuilder().build();
 	
 	<jc>// The address of the root resource.</jc>
 	String url = <js>"http://localhost:9080/sample/addressBook"</js>;
@@ -2194,7 +2225,7 @@
 	
 	<jc>// Add a person to the address book.
 	// Use XML as the transport medium.</jc>
-	client = <jk>new</jk> RestClient(XmlSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>);
+	client = <jk>new</jk> RestClientBuilder(XmlSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>).build();
 	Person p = <jk>new</jk> Person(<js>"Joe Smith"</js>, 21);
 	<jk>int</jk> returnCode = client.doPost(url + <js>"/entries"</js>, p).run();
 	</p>
@@ -2223,7 +2254,7 @@
 	</p>
 	<ul class='spaced-list'>
 		<li>Proxy interfaces are retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method.
-		<li>The {@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String)} method is used to specify the location
+		<li>The {@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String)} method is used to specify the location
 			of the remoteable services servlet running on the server.
 		<li>The {@link org.apache.juneau.rest.remoteable.RemoteableServlet} class is a specialized subclass of {@link org.apache.juneau.rest.RestServlet} that provides a full-blown
 			REST interface for calling interfaces remotely. 
@@ -2241,8 +2272,9 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>,JsonParser.<jk>class</jk>)
-		.setRemoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>);
+	RestClient client = <jk>new</jk> RestClientBuilder()
+		.remoteableServletUri(<js>"https://localhost:9080/juneau/sample/remoteable"</js>)
+		.build();
 	
 	<jc>// Create a proxy interface.</jc>
 	IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>);
@@ -3182,25 +3214,25 @@
 		<p class='bcode'>
 	<jd>/** Override the default rest serializers to add some transforms */</jd>
 	<ja>@Override</ja>
-	<jk>protected</jk> SerializerGroup createSerializers(ObjectMap properties, Class[] beanFilters, Class[] pojoSwaps) {
+	<jk>protected</jk> SerializerGroupBuilder createSerializers(ObjectMap properties, Class[] beanFilters, Class[] pojoSwaps) {
 
 		<jc>// You'll just reuse the parent serializer group</jc>
-		SerializerGroup serializerGroup = <jk>super</jk>.createSerializers(properties, beanFilters, pojoSwaps);
+		SerializerGroupBuilder b = <jk>super</jk>.createSerializers(properties, beanFilters, pojoSwaps);
 		
 		<jc>// Add bean filters for the HttpServletRequest, HttpSession, and ServletContext objects
 		//		so that you don't show vendor-specific properties on subclasses.
 		// Add Enumeration POJO swap to be able to render the contents of Enumeration properties.
 		// The max depth and detect recursion options prevent any possible runaway serializations.  
 		// This shouldn't happen, but future JEE APIs may introduce deep hierarchies or loops.</jc>
-		serializerGroup
-			.addBeanFilters(HttpServletRequest.<jk>class</jk>, HttpSession.<jk>class</jk>, ServletContext.<jk>class</jk>)
-			.addPojoSwaps(EnumerationSwap.<jk>class</jk>)
-			.setMaxDepth(10)
-			.setDetectRecursions(<jk>true</jk>);
-			.setProperty(<jsf>HTMLDOC_links</jsf>, <js>"{...}"</js>);
+		b
+			.beanFilters(HttpServletRequest.<jk>class</jk>, HttpSession.<jk>class</jk>, ServletContext.<jk>class</jk>)
+			.pojoSwaps(EnumerationSwap.<jk>class</jk>)
+			.maxDepth(10)
+			.detectRecursions(<jk>true</jk>);
+			.property(<jsf>HTMLDOC_links</jsf>, <js>"{...}"</js>);
 		
 		<jc>// Return the updated group</jc>
-		<jk>return</jk> serializerGroup;
+		<jk>return</jk> b;
 	}
 		</p>
 		<p>
@@ -4101,8 +4133,8 @@
 				System.<jsf>out</jsf>.println(<js>"Running client test..."</js>); 
 				
 				<jc>// Create a client to handle XML requests and responses.</jc> 
-				RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jsf>DEFAULT</jsf>, JsonParser.<jsf>DEFAULT</jsf>); 
-				RestClient xmlClient = <jk>new</jk> RestClient(XmlSerializer.<jsf>DEFAULT</jsf>, XmlParser.<jsf>DEFAULT</jsf>); 
+				RestClient client = <jk>new</jk> RestClientBuilder().build(); 
+				RestClient xmlClient = <jk>new</jk> RestClientBuilder(XmlSerializer.<jsf>DEFAULT</jsf>, XmlParser.<jsf>DEFAULT</jsf>).build(); 
 				
 				String root = <js>"http://localhost:10000/addressBook"</js>; 
 				
@@ -4287,7 +4319,7 @@
 			As good practice, you'll want to use interfaces to prevent all public methods from being exposed.
 		</p>
 		<p>
-			The {@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String)} method is used to specify the location
+			The {@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String)} method is used to specify the location
 				of the remoteable services servlet running on the server.
 			Proxy interfaces are then retrieved using the {@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)} method.
 		</p>
@@ -4296,8 +4328,9 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a RestClient using JSON for serialization, and point to the server-side remoteable servlet.</jc>
-	RestClient client = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>,JsonParser.<jk>class</jk>)
-		.setRemoteableServletUri(<js>"http://localhost:10000/remoteable"</js>);
+	RestClient client = <jk>new</jk> RestClientBuilder()
+		.remoteableServletUri(<js>"http://localhost:10000/remoteable"</js>)
+		.build();
 	
 	<jc>// Create a proxy interface.</jc>
 	IAddressBook ab = client.getRemoteableProxy(IAddressBook.<jk>class</jk>);
@@ -4314,7 +4347,7 @@
 			<li class='a'>{@link org.apache.juneau.rest.remoteable.RemoteableServlet}
 			<li class='c'>{@link org.apache.juneau.rest.client.RestClient}
 			<ul>
-				<li class='m'>{@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String) setRemoteableServletUri(String)}
+				<li class='m'>{@link org.apache.juneau.rest.client.RestClientBuilder#remoteableServletUri(String) remoteableServletUri(String)}
 				<li class='m'>{@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class) getRemoteableProxy(Class)}
 			</ul>
 		</ul>
@@ -4584,7 +4617,7 @@
 		
 		<jc>// Get registry URL from examples.cfg file.</jc>
 		<jk>private</jk> String <jf>registryUrl</jf> = getConfig().getString(<js>"DockerRegistry/url"</js>); 
-		RestClient <jf>rc</jf> = <jk>new</jk> RestClient(JsonSerializer.<jsf>DEFAULT</jsf>, JsonParser.<jsf>DEFAULT</jsf>); 
+		RestClient <jf>rc</jf> = <jk>new</jk> RestClientBuilder().build(); 
 		
 		<jd>/** [GET /] - Show child resources. */</jd> 
 		<ja>@SuppressWarnings</ja>(<js>"nls"</js>) 
@@ -4673,7 +4706,7 @@
 		<ja>@RestMethod</ja>(name=<js>"GET"</js>, path=<js>"/{blogName}"</js>) 
 		<jk>public</jk> ObjectList parseBlog(<ja>@Path</ja> String blogName) <jk>throws</jk> Exception { 
 			ObjectList l = <jk>new</jk> ObjectList(); 
-			RestClient rc = <jk>new</jk> RestClient(JsonSerializer.<jk>class</jk>, JsonParser.<jk>class</jk>); 
+			RestClient rc = <jk>new</jk> RestClientBuilder().build(); 
 			String site = <js>"http:<jc>//"</js> + blogName + <js>".tumblr.com/api/read/json"</js>;</jc> 
 			ObjectMap m = rc.doGet(site).getResponse(ObjectMap.<jk>class</jk>); 
 			<jk>int</jk> postsTotal = m.getInt(<js>"posts-total"</js>); 
@@ -5429,7 +5462,7 @@
 	<ja>@Override</ja>
 	<jk>protected</jk> SerializerGroup createSerializers(ObjectMap properties, Class[] beanFilters, Class[] pojoSwaps) <jk>throws</jk> Exception {
 		SerializerGroup g = <jk>super</jk>.createSerializers(properties, beanFilters, pojoSwaps);
-		g.getSerializer(<js>"text/html"</js>).addPojoSwaps(DoubleSwap.<jk>class</jk>); 
+		g.getSerializer(<js>"text/html"</js>).pojoSwaps(DoubleSwap.<jk>class</jk>); 
 		<jk>return</jk> g;
 	}
 			</p>
@@ -5637,17 +5670,46 @@
 
 		<h6 class='topic'>org.apache.juneau</h6>
 		<ul class='spaced-list'>
+			<li>Revamped the serializer and parser classes to use builders for creation.
+				Serializers and parsers are now unmodifiable objects once they are created.
+				This is a breaking code change that will require adoption.
+				<p class='bcode'>
+	<jc>/* Creating a new serializer or parser */ </jc>
+	
+	<jc>// Old way</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializer().setUseWhitespace(<jk>true</jk>).pojoSwaps(BSwap.<jk>class</jk>).lock();
+
+	<jc>// New way</jc>
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().ws().pojoSwaps(BSwap.<jk>class</jk>).build();
+
+	<jc>/* Cloning an existing serializer or parser */ </jc>
+	
+	<jc>// Old way</jc>
+	WriterSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.clone().setUseWhitespace(<jk>true</jk>).pojoSwaps(BSwap.<jk>class</jk>).lock();
+
+	<jc>// New way</jc>
+	WriterSerializer s = JsonSerializer.<jsf>DEFAULT_LAX</jsf>.builder().ws().pojoSwaps(BSwap.<jk>class</jk>).build();
+				</p>	
+			<li>Also introduced the following builder classes and related architecture changes to make the built objects unmodifiable:
+			<ul>
+				<li>{@link org.apache.juneau.serializer.SerializerGroupBuilder}
+				<li>{@link org.apache.juneau.parser.ParserGroupBuilder}
+				<li>{@link org.apache.juneau.encoders.EncoderGroupBuilder}
+			</ul>
+				Also introduced 			
+			<li>Removed the <code><del>Lockable</del></code> interface.
 			<li>New <code>addBeanTypeProperties</code> setting added to serializers to override the 
-			{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties} setting
-			for individual serializers in a serializer group:
+				{@link org.apache.juneau.serializer.SerializerContext#SERIALIZER_addBeanTypeProperties} setting
+				for individual serializers in a serializer group:
 			<ul>
 				<li>{@link org.apache.juneau.html.HtmlSerializerContext#HTML_addBeanTypeProperties}
 				<li>{@link org.apache.juneau.json.JsonSerializerContext#JSON_addBeanTypeProperties}
 				<li>{@link org.apache.juneau.msgpack.MsgPackSerializerContext#MSGPACK_addBeanTypeProperties}
-				<li>{@link org.apache.juneau.urlencoding.UonSerializerContext#UON_addBeanTypeProperties}
+				<li>{@link org.apache.juneau.uon.UonSerializerContext#UON_addBeanTypeProperties}
 				<li>{@link org.apache.juneau.xml.XmlSerializerContext#XML_addBeanTypeProperties}
 				<li>{@link org.apache.juneau.jena.RdfSerializerContext#RDF_addBeanTypeProperties}
 			</ul>
+			<li>UON notation serializers and parsers moved into the new <code>org.apache.juneau.uon</code> package.
 			<li>New {@link org.apache.juneau.xml.annotation.XmlFormat#VOID} format to identify HTML void elements.
 			<li>Tweaks to HTML5 support.
 			<ul>
@@ -5677,7 +5739,7 @@
 
 		<h6 class='topic'>org.apache.juneau.rest.client</h6>
 		<ul class='spaced-list'>
-			<li>{@link org.apache.juneau.rest.client.RestClient#setRootUrl(Object)} can now take in <code>URI</code> and <code>URL</code> objects.
+			<li>Revamped the client API to use builders.
 		</ul>
 		
 		<h6 class='topic'>org.apache.juneau.microservice</h6>
@@ -5703,7 +5765,7 @@
 		</p>
 		<p>
 			In particular, this release cleans up the {@link org.apache.juneau.BeanContext} API to match
-			the {@link org.apache.juneau.ContextFactory}/{@link org.apache.juneau.Context}/{@link org.apache.juneau.Session} paradigm
+			the {@link org.apache.juneau.PropertyStore}/{@link org.apache.juneau.Context}/{@link org.apache.juneau.Session} paradigm
 			previously used in the serializer and parser APIs.
 			It also makes several improvements to the HTML and XML serialization support and introduces HTML5 DTO beans.
 		</p>
@@ -5876,7 +5938,7 @@
 				<li>The new specification is considerably cleaner and eliminates the need for separate normal/simple modes.
 					<br>It also allows for arbitrary whitespace to be added to the output without any confusion.
 				<li>Eliminated the <code>UonParser.<jsf>DEFAULT_WS_AWARE</jsf></code> and <code>UrlEncodingParser.<jsf>DEFAULT_WS_AWARE</jsf></code> parsers.
-					<br>The normal {@link org.apache.juneau.urlencoding.UonParser#DEFAULT} and {@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} parsers will now handle whitespace.
+					<br>The normal {@link org.apache.juneau.uon.UonParser#DEFAULT} and {@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} parsers will now handle whitespace.
 				<li>Eliminated the <code>UonParserContext.<jsf>UON_whitespaceAware</jsf></code> configuration setting.
 				<li>Eliminated the <code>UonSerializer.<jsf>DEFAULT_SIMPLE</jsf></code>, <code>UonSerializer.<jsf>DEFAULT_SIMPLE_ENCODING</jsf></code>
 					and <code>UrlEncodingSerializer.<jsf>DEFAULT_SIMPLE</jsf></code>
@@ -5969,7 +6031,7 @@
 			<li>Major changes around how serializer and parser class properties are defined to improve performance
 				and concurrency.
 				<ul>
-					<li>New {@link org.apache.juneau.ContextFactory} class - Used for creating context objects.
+					<li>New {@link org.apache.juneau.PropertyStore} class - Used for creating context objects.
 					<li>New {@link org.apache.juneau.Context} class - Read-only configurations for serializers and parsers.
 					<li>New {@link org.apache.juneau.Session} class - One-time use objects used by serializers and parsers.
 					<li>All context context properties can now also be specified via system properties.
@@ -5994,7 +6056,7 @@
 				The following features were added to enable this support:
 				<ul>
 					<li>{@link org.apache.juneau.annotation.Bean#typeName() @Bean.typeName()} - Annotation that defines an identifying name for a bean class.
-					<li>{@link org.apache.juneau.transform.BeanFilterBuilder#setTypeName(String)} - Programmatic equivalent to annotation above.
+					<li>{@link org.apache.juneau.transform.BeanFilterBuilder#typeName(String)} - Programmatic equivalent to annotation above.
 					<li>{@link org.apache.juneau.BeanContext#BEAN_beanDictionary} - List of bean classes that make up the bean dictionary for lookup
 						during parsing. 
 					<li>{@link org.apache.juneau.BeanContext#BEAN_beanTypePropertyName} - The overridable type property name.  Default is <js>"_type"</js>.
@@ -6112,7 +6174,7 @@
 		<h6 class='topic'>org.apache.juneau.rest.client</h6>
 		<ul class='spaced-list'>
 			<li>Removed the <code>JazzRestClient</code> class.
-			<li>New method {@link org.apache.juneau.rest.client.RestClient#setClientVersion(String)}.
+			<li>New method <code><del>RestClient.setClientVersion(String)</del></code>.
 		</ul>		
 	</div>
 
@@ -6387,7 +6449,7 @@
 			<li>Removed <code>org.apache.juneau.rest.client.LaxRedirectStrategy</code>.  Use HTTP Client equivalent.
 			<li>New methods on {@link org.apache.juneau.rest.client.RestCall}:
 				<ul>
-					<li>{@link org.apache.juneau.rest.client.RestCall#addInterceptor(RestCallInterceptor)}
+					<li><code><del>RestCall#addInterceptor(RestCallInterceptor)</del></code>
 					<li>{@link org.apache.juneau.rest.client.RestCall#pipeTo(Writer)}
 					<li>{@link org.apache.juneau.rest.client.RestCall#pipeTo(Writer,boolean)}
 					<li>{@link org.apache.juneau.rest.client.RestCall#pipeTo(String,Writer,boolean)}
@@ -6400,7 +6462,7 @@
 					<li>{@link org.apache.juneau.rest.client.RestCall#captureResponse()}
 					<li>{@link org.apache.juneau.rest.client.RestCall#successPattern(String)}
 					<li>{@link org.apache.juneau.rest.client.RestCall#failurePattern(String)}
-					<li>{@link org.apache.juneau.rest.client.RestCall#addResponsePattern(ResponsePattern)}
+					<li><code><del>RestCall#addResponsePattern(ResponsePattern)</del></code>
 					<li>{@link org.apache.juneau.rest.client.RestCall#run()} - Renamed from <code>execute()</code>.
 					<li>{@link org.apache.juneau.rest.client.RestCall#getCapturedResponse()}
 					<li>{@link org.apache.juneau.rest.client.RestCall#getResponsePojoRest(Class)}
@@ -6415,63 +6477,63 @@
 				</ul>
 			<li>New methods on {@link org.apache.juneau.rest.client.RestClient}:
 				<ul>
-					<li>{@link org.apache.juneau.rest.client.RestClient#setBasicAuth(String,int,String,String)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#logTo(Level,Logger)}
+					<li><code><del>RestClient.setBasicAuth(String,int,String,String)</del></code>
+					<li><code><del>RestClient.logTo(Level,Logger)</del></code>
 					<li><code><del>RestClient.setRootUrl(String)</del></code>
-					<li>{@link org.apache.juneau.rest.client.RestClient#enableSSL(SSLOpts)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#enableLaxSSL()}
+					<li><code><del>RestClient.enableSSL(SSLOpts)</del></code>
+					<li><code><del>RestClient.enableLaxSSL()</del></code>
 					<li>{@link org.apache.juneau.rest.client.RestClient#doCall(HttpMethod,Object,Object)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#createHttpClientBuilder()}
+					<li><code><del>RestClient.createHttpClientBuilder()</del></code>
 				</ul>
 			<li>New passthrough methods on {@link org.apache.juneau.rest.client.RestClient} defined on <code>HttpClientBuilder</code>:
 				<ul>
-					<li>{@link org.apache.juneau.rest.client.RestClient#setRedirectStrategy(RedirectStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultCookieSpecRegistry(Lookup)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setRequestExecutor(HttpRequestExecutor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setSSLHostnameVerifier(HostnameVerifier)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setPublicSuffixMatcher(PublicSuffixMatcher)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setSSLContext(SSLContext)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setSSLSocketFactory(LayeredConnectionSocketFactory)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setMaxConnTotal(int)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setMaxConnPerRoute(int)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultSocketConfig(SocketConfig)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultConnectionConfig(ConnectionConfig)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setConnectionTimeToLive(long,TimeUnit)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setConnectionManager(HttpClientConnectionManager)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setConnectionManagerShared(boolean)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setConnectionReuseStrategy(ConnectionReuseStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setKeepAliveStrategy(ConnectionKeepAliveStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setTargetAuthenticationStrategy(AuthenticationStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setProxyAuthenticationStrategy(AuthenticationStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setUserTokenHandler(UserTokenHandler)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableConnectionState()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setSchemePortResolver(SchemePortResolver)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setUserAgent(String userAgent)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultHeaders(Collection)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#addInterceptorFirst(HttpResponseInterceptor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#addInterceptorLast(HttpResponseInterceptor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#addInterceptorFirst(HttpRequestInterceptor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#addInterceptorLast(HttpRequestInterceptor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableCookieManagement()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableContentCompression()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableAuthCaching()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setHttpProcessor(HttpProcessor)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setRetryHandler(HttpRequestRetryHandler)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableAutomaticRetries()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setProxy(HttpHost)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setRoutePlanner(HttpRoutePlanner)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#disableRedirectHandling()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setConnectionBackoffStrategy(ConnectionBackoffStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setBackoffManager(BackoffManager)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultCookieStore(CookieStore)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultCredentialsProvider(CredentialsProvider)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultAuthSchemeRegistry(Lookup)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setContentDecoderRegistry(Map)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#setDefaultRequestConfig(RequestConfig)}
-					<li>{@link org.apache.juneau.rest.client.RestClient#useSystemProperties()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#evictExpiredConnections()}
-					<li>{@link org.apache.juneau.rest.client.RestClient#evictIdleConnections(long,TimeUnit)}
+					<li><code><del>RestClient.setRedirectStrategy(RedirectStrategy)</del></code>
+					<li><code><del>RestClient.setDefaultCookieSpecRegistry(Lookup)</del></code>
+					<li><code><del>RestClient.setRequestExecutor(HttpRequestExecutor)</del></code>
+					<li><code><del>RestClient.setSSLHostnameVerifier(HostnameVerifier)</del></code>
+					<li><code><del>RestClient.setPublicSuffixMatcher(PublicSuffixMatcher)</del></code>
+					<li><code><del>RestClient.setSSLContext(SSLContext)</del></code>
+					<li><code><del>RestClient.setSSLSocketFactory(LayeredConnectionSocketFactory)</del></code>
+					<li><code><del>RestClient.setMaxConnTotal(int)</del></code>
+					<li><code><del>RestClient.setMaxConnPerRoute(int)</del></code>
+					<li><code><del>RestClient.setDefaultSocketConfig(SocketConfig)</del></code>
+					<li><code><del>RestClient.setDefaultConnectionConfig(ConnectionConfig)</del></code>
+					<li><code><del>RestClient.setConnectionTimeToLive(long,TimeUnit)</del></code>
+					<li><code><del>RestClient.setConnectionManager(HttpClientConnectionManager)</del></code>
+					<li><code><del>RestClient.setConnectionManagerShared(boolean)</del></code>
+					<li><code><del>RestClient.setConnectionReuseStrategy(ConnectionReuseStrategy)</del></code>
+					<li><code><del>RestClient.setKeepAliveStrategy(ConnectionKeepAliveStrategy)</del></code>
+					<li><code><del>RestClient.setTargetAuthenticationStrategy(AuthenticationStrategy)</del></code>
+					<li><code><del>RestClient.setProxyAuthenticationStrategy(AuthenticationStrategy)</del></code>
+					<li><code><del>RestClient.setUserTokenHandler(UserTokenHandler)</del></code>
+					<li><code><del>RestClient.disableConnectionState()</del></code>
+					<li><code><del>RestClient.setSchemePortResolver(SchemePortResolver)</del></code>
+					<li><code><del>RestClient.setUserAgent(String userAgent)</del></code>
+					<li><code><del>RestClient.setDefaultHeaders(Collection)</del></code>
+					<li><code><del>RestClient.addInterceptorFirst(HttpResponseInterceptor)</del></code>
+					<li><code><del>RestClient.addInterceptorLast(HttpResponseInterceptor)</del></code>
+					<li><code><del>RestClient.addInterceptorFirst(HttpRequestInterceptor)</del></code>
+					<li><code><del>RestClient.addInterceptorLast(HttpRequestInterceptor)</del></code>
+					<li><code><del>RestClient.disableCookieManagement()</del></code>
+					<li><code><del>RestClient.disableContentCompression()</del></code>
+					<li><code><del>RestClient.disableAuthCaching()</del></code>
+					<li><code><del>RestClient.setHttpProcessor(HttpProcessor)</del></code>
+					<li><code><del>RestClient.setRetryHandler(HttpRequestRetryHandler)</del></code>
+					<li><code><del>RestClient.disableAutomaticRetries()</del></code>
+					<li><code><del>RestClient.setProxy(HttpHost)</del></code>
+					<li><code><del>RestClient.setRoutePlanner(HttpRoutePlanner)</del></code>
+					<li><code><del>RestClient.disableRedirectHandling()</del></code>
+					<li><code><del>RestClient.setConnectionBackoffStrategy(ConnectionBackoffStrategy)</del></code>
+					<li><code><del>RestClient.setBackoffManager(BackoffManager)</del></code>
+					<li><code><del>RestClient.setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)</del></code>
+					<li><code><del>RestClient.setDefaultCookieStore(CookieStore)</del></code>
+					<li><code><del>RestClient.setDefaultCredentialsProvider(CredentialsProvider)</del></code>
+					<li><code><del>RestClient.setDefaultAuthSchemeRegistry(Lookup)</del></code>
+					<li><code><del>RestClient.setContentDecoderRegistry(Map)</del></code>
+					<li><code><del>RestClient.setDefaultRequestConfig(RequestConfig)</del></code>
+					<li><code><del>RestClient.useSystemProperties()</del></code>
+					<li><code><del>RestClient.evictExpiredConnections()</del></code>
+					<li><code><del>RestClient.evictIdleConnections(long,TimeUnit)</del></code>
 				</ul>
 			<li><code>JazzRestClient</code> now supports OIDC authentication.
 			<li>These classes are now deprecated and will be removed in a future release:
@@ -6517,7 +6579,7 @@
 					<li>{@link org.apache.juneau.rest.RestServlet#createStaticFilesMap()} 
 					<li>{@link org.apache.juneau.rest.RestServlet#getConfigMgr()} 
 				</ul>
-			<li>Removed {@link org.apache.juneau.jso.JavaSerializedObjectParser}
+			<li>Removed {@link org.apache.juneau.jso.JsoParser}
 				from {@link org.apache.juneau.rest.RestServletDefault} and {@link org.apache.juneau.rest.jena.RestServletJenaDefault}.  
 				These may represent a security risk if not handled correctly, so removed
 				them as a precaution.
@@ -6626,7 +6688,7 @@
 			<li>New {@link org.apache.juneau.utils.ProcBuilder} class for calling external processes.
 			<li>New {@link org.apache.juneau.ObjectMap#remove(Class,String,Object)} method.
 			<li><js>"class='link'"</js> added to links generated by {@link org.apache.juneau.html.HtmlDocSerializer}.
-			<li>New {@link org.apache.juneau.encoders.EncoderGroup#append(EncoderGroup)} method.
+			<li>New <code><del>EncoderGroup#append(EncoderGroup)</del></code> method.
 			<li>New <code>HtmlDocSerializerContext.HTMLDOC_addLinks</code> configuration property.
 			<li>Modified the <code>Parser.createContext(ObjectMap,Method,Object)</code> method.  
 				Outer context objects can be passed in to create instances of non-static inner classes.
@@ -6648,7 +6710,7 @@
 				<ul>
 					<li>New methods for accessing external INI config files:<br>  
 						{@link org.apache.juneau.rest.RestServlet#getConfig()}<br>
-						{@link org.apache.juneau.rest.RestServlet#createConfigFile()}
+						<code><del>RestServlet.createConfigFile()</del></code>
 					<li>New <js>"$C{...}"</js> variable that resolve to INI config file values.
 					<li>New <js>"$UE{...}"</js> variable that  URL-encodes the value inside the variable.
 					<li>New convenience methods for retrieving classpath resource files:<br>  
@@ -7011,7 +7073,7 @@
 		<ul class='spaced-list'>
 			<li>New methods in {@link org.apache.juneau.rest.client.RestClient} for working with remoteable services:
 			<ul>
-				<li>{@link org.apache.juneau.rest.client.RestClient#setRemoteableServletUri(String)}
+				<li><code><del>RestClient.setRemoteableServletUri(String)</del></code>
 				<li>{@link org.apache.juneau.rest.client.RestClient#getRemoteableProxy(Class)}
 			</ul>
 		</ul>
@@ -7044,7 +7106,7 @@
 			<li>New date filters:  <code>org.apache.juneau.transforms.Datefilter.ISO8601DTZP</code> and <code>org.apache.juneau.transforms.Datefilter.SimpleP</code>.
 			<li>New {@link org.apache.juneau.html.HtmlDocSerializerContext#HTMLDOC_nowrap} setting for {@link org.apache.juneau.html.HtmlDocSerializer} class.  
 				Adds <js>"* {white-space:nowrap}"</js> to the style header to prevent word wrapping.
-			<li>Fixed bug in {@link org.apache.juneau.urlencoding.UonParser} where passing in a blank value on an array or collection type in a form post would cause a <code>ClassCastException</code>.  
+			<li>Fixed bug in {@link org.apache.juneau.uon.UonParser} where passing in a blank value on an array or collection type in a form post would cause a <code>ClassCastException</code>.  
 				New behavior creates an empty array or <code>Collection</code>.
 			<li>Improved implementation of {@link org.apache.juneau.urlencoding.UrlEncodingSerializer#serializeUrlPart(Object)} method.
 		</ul>
@@ -7060,8 +7122,8 @@
 		
 		<h6 class='topic'>Client</h6>		
 		<ul class='spaced-list'>	
-			<li>New {@link org.apache.juneau.rest.client.RestCall#setRedirectMaxAttempts(int)} method to prevent endless redirection loops.
-			<li>New {@link org.apache.juneau.rest.client.RestCall#setRetryable(int,long,RetryOn)} method to automatically retry on failed connection attempts.
+			<li>New <code><del>RestCall.setRedirectMaxAttempts(int)</del></code> method to prevent endless redirection loops.
+			<li>New <code><del>RestCall#setRetryable(int,long,RetryOn)</del></code> method to automatically retry on failed connection attempts.
 			<li>New <code>RestCallInterceptor.onRetry(RestCall,int,HttpRequest,HttpResponse)</code> method for listening in on retry attempts.		
 		</ul>
 	</div>
@@ -7077,7 +7139,7 @@
 		<h6 class='topic'>Core</h6>		
 		<ul class='spaced-list'>
 			<li>Fixed {@link org.apache.juneau.ini.ConfigFile#isEmpty()} method.
-			<li>Changed behavior on {@link org.apache.juneau.urlencoding.UonParser} to not treat <js>'~'</js> characters as escapes
+			<li>Changed behavior on {@link org.apache.juneau.uon.UonParser} to not treat <js>'~'</js> characters as escapes
 				unless followed by one of the following characters:  <code>( ) , $ = ~</code>.
 		</ul>
 
@@ -7110,7 +7172,7 @@
 			</li>
 			<li>Several improvements to URL-Encoding support.
 				<ul>
-					<li>Improved whitespace handling in {@link org.apache.juneau.urlencoding.UonParser}.
+					<li>Improved whitespace handling in {@link org.apache.juneau.uon.UonParser}.
 					<li>New <code><del>UonParserContext.UON_whitespaceAware</del></code> property for controlling whether whitespace is ignored.
 					<li>New {@link org.apache.juneau.urlencoding.UrlEncodingContext#URLENC_expandedParams} property for controlling whether arrays/Collections 
 						should be serialized/parsed as multi-part parameters.
@@ -7167,7 +7229,7 @@
 				Shows all request/response headers and bodies.
 			<li>{@link org.apache.juneau.rest.client.RestCallException} now includes <code>HttpResponse</code> object for easier debugging.
 			<li>New method <code>RestClient.addListener(RestClientListener)</code> for registering request/response listeners.
-			<li>New {@link org.apache.juneau.rest.client.RestClient#setClassLoader(ClassLoader)} method.
+			<li>New <code><del>RestClient.setClassLoader(ClassLoader)</del></code> method.
 			<li>TLS support in <code>JazzRestClient</code>.
 		</ul>
 
@@ -7191,7 +7253,7 @@
 			<li>Major changes to URL-Encoded serializer and parser.
 				<ul>
 					<li>Logic for serializing and parsing URL-Encoded key-value pairs moved to {@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.urlencoding.UrlEncodingParser} classes.
-					<li>Logic for serializing and parsing URL-Encoded values moved to new {@link org.apache.juneau.urlencoding.UonSerializer} and {@link org.apache.juneau.urlencoding.UonParser} classes.
+					<li>Logic for serializing and parsing URL-Encoded values moved to new {@link org.apache.juneau.uon.UonSerializer} and {@link org.apache.juneau.uon.UonParser} classes.
 				</ul>
 			</li>
 			<li>Fix bug where <code>BeanRuntimeExceptions</code> weren't being thrown on subsequent calls to {@link org.apache.juneau.BeanContext#getClassMeta(Class)}.
@@ -7214,7 +7276,7 @@
 			<li><code>&amp;plainText</code> parameter can now specify a false value.
 			<li>Removed properties parameters from {@link org.apache.juneau.rest.RestServlet#onPreCall(RestRequest)} and {@link org.apache.juneau.rest.RestServlet#onPostCall(RestRequest,RestResponse)} methods
 				since the properties are already accessible through <code>RestRequest.getProperties()</code>.
-			<li>Added {@link org.apache.juneau.urlencoding.UonSerializer} and {@link org.apache.juneau.urlencoding.UonParser} to serializer and parser lists on 
+			<li>Added {@link org.apache.juneau.uon.UonSerializer} and {@link org.apache.juneau.uon.UonParser} to serializer and parser lists on 
 				{@link org.apache.juneau.rest.RestServletDefault} and {@link org.apache.juneau.rest.jena.RestServletJenaDefault}.
 		</ul>
 		
@@ -7225,11 +7287,11 @@
 			<li>Improved performance on URL-Encoded form posts by serializing directly to output stream instead of serialized to string first.
 			<li>New methods on {@link org.apache.juneau.rest.client.RestClient} class that makes it easier to associate serializer and parser attributes with registered serializer and parser:
 				<ul>
-					<li>{@link org.apache.juneau.rest.client.RestClient#setProperty(String,Object)}			
-					<li>{@link org.apache.juneau.rest.client.RestClient#setProperties(ObjectMap)}			
-					<li>{@link org.apache.juneau.rest.client.RestClient#addNotBeanClasses(Class[])}			
+					<li><code><del>RestClient#setProperty(String,Object)</del></code>			
+					<li><code><del>RestClient#setProperties(ObjectMap)</del></code>	
+					<li><code><del>RestClient#addNotBeanClasses(Class[])</del></code>		
 					<li><del><code>RestClient.addTransforms(Class[])</code></del>		
-					<li>{@link org.apache.juneau.rest.client.RestClient#addImplClass(Class,Class)}	
+					<li><code><del>RestClient#addImplClass(Class,Class)</del></code>	
 				</ul>
 			<li>Renamed <code>RestClient.shutdown()</code> to {@link org.apache.juneau.rest.client.RestClient#close()} to mirror change in Apache API.		
 		</ul>
@@ -7292,7 +7354,7 @@
 			</li>
 			<li>Revamped the {@link org.apache.juneau.BeanContext} API to perform better in multi-threaded environments.
 				<ul>
-					<li>Introduced a new <code>BeanContextFactory</code> class that handles creation of {@link org.apache.juneau.BeanContext} objects.
+					<li>Introduced a new <code>BeanPropertyStore</code> class that handles creation of {@link org.apache.juneau.BeanContext} objects.
 						This allows <code>BeanContext</code> objects to be considered immutable, and therefore cacheable/reusable by the framework.
 						While this was technically possible to cache these objects beforehand, it relied on a locking mechanism to prevent bean contexts
 							from being modified after being created.  The new mechanism is much more straightforward.
@@ -7300,7 +7362,7 @@
 			</li>
 			<li>Modifications to the <a class='doclink' href='org/apache/juneau/rest/client/package-summary.html#TOC'>org.apache.juneau.rest.client</a> APIs to make it easier to work with custom Apache HTTP clients.
 				<ul>
-					<li>Added overridable {@link org.apache.juneau.rest.client.RestClient#createHttpClient()} to allow customized subclasses to construct customized HTTP clients.
+					<li>Added overridable <code><del>RestClient#createHttpClient()</del></code> to allow customized subclasses to construct customized HTTP clients.
 					<li>Removed the <code>DefaultRestClient</code> class since it's now fully redundant with <code>RestClient</code>.
 					<li>Added <code>RestClient.shutdown()</code> method for cleaning up the internal HTTP client when you're done using a REST client.
 				</ul>
@@ -7375,7 +7437,7 @@
 			<li>New method {@link org.apache.juneau.rest.RestRequest#getServletURIBuilder()} for construcing servlet-based URLs more efficiently.
 			<li>New method {@link org.apache.juneau.rest.RestResponse#getNegotiatedOutputStream()} that uses encoders if a match is found, 
 				and {@link org.apache.juneau.rest.RestResponse#getOutputStream()} that just return the underlying output stream without any modifications.
-			<li>Fixed bug where some properties were not being propagated correctly when using {@link org.apache.juneau.CoreApi#setProperties(ObjectMap)}
+			<li>Fixed bug where some properties were not being propagated correctly when using <code><del>CoreObject.setProperties(ObjectMap)</del></code>
 				on serializer and parser subclasses.
 			<li>Fixed bug in {@link org.apache.juneau.html.HtmlSerializer} where URL keys in Maps were not being serialized as hyperlinks.
 			<li>Fixed bug in {@link org.apache.juneau.json.JsonSerializer} where <js>"_class"</js> and <js>"items"</js> attributes were not quoted in strict mode when using SERIALIZER_addClassAttrs feature.	
@@ -7402,7 +7464,7 @@
 			<li>Better behavior on overriding of filters in <code>BeanContext.addTransforms(Class[])</code>.
 				Previously, adding multiple conflicting filters resulted in random behavior.  
 				Now filters are overridden when multiple matching filters are applied.
-			<li>Allow {@link org.apache.juneau.html.HtmlDocSerializerContext} properties to be set via {@link org.apache.juneau.serializer.Serializer#setProperty(String,Object)}.
+			<li>Allow {@link org.apache.juneau.html.HtmlDocSerializerContext} properties to be set via <code><del>Serializer.setProperty(String,Object)</del></code>.
 				Previously, these could only be defined through override properties (e.g. through REST class and method annotations).
 			<li>Fixed memory leak in XML parser.	
 		</ul>
@@ -8211,7 +8273,7 @@
 		<h6 class='topic'>Other changes</h6>
 		<ul class='spaced-list'>
 			<li>
-				New {@link org.apache.juneau.jso.JavaSerializedObjectParser} class.  
+				New {@link org.apache.juneau.jso.JsoParser} class.  
 			</li>
 		</ul>
 	</div>
@@ -8328,7 +8390,7 @@
 			<li>
 				New <a class='doclink' href='org/apache/juneau/jso/package-summary.html#TOC'>org.apache.juneau.jso</a> package.
 				<ul>
-					<li>New {@link org.apache.juneau.jso.JavaSerializedObjectSerializer} class for serializing <code>application/x-java-serialized-object</code> content.</li>
+					<li>New {@link org.apache.juneau.jso.JsoSerializer} class for serializing <code>application/x-java-serialized-object</code> content.</li>
 				</ul>
 			</li>
 			<li>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
index 34ae3bc..eab51fa 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/DockerRegistryResource.java
@@ -18,7 +18,6 @@ import java.util.*;
 
 import javax.servlet.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -46,7 +45,7 @@ public class DockerRegistryResource extends Resource {
 	@Override /* Servlet */
 	public void init() throws ServletException {
 		super.init();
-		rc = new RestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		rc = new RestClientBuilder().build();
 	}
 
 	@Override /* Servlet */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
index 782a72b..ff5c242 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/PhotosResource.java
@@ -122,6 +122,15 @@ public class PhotosResource extends Resource {
 	/** Serializer for converting images to byte streams */
 	@Produces("image/png,image/jpeg")
 	public static class ImageSerializer extends OutputStreamSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public ImageSerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			RenderedImage image = (RenderedImage)o;
@@ -133,6 +142,15 @@ public class PhotosResource extends Resource {
 	/** Parser for converting byte streams to images */
 	@Consumes("image/png,image/jpeg")
 	public static class ImageParser extends InputStreamParser {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public ImageParser(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Parser */
 		@SuppressWarnings("unchecked")
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
index b055f27..f147905 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SqlQueryResource.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.examples.rest;
 
 import static javax.servlet.http.HttpServletResponse.*;
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.io.*;
 import java.sql.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
index 2703f92..06bb64b 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/SystemPropertiesResource.java
@@ -12,8 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.util.*;
 import java.util.Map;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
index 9851b94..1bfe76b 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TempDirResource.java
@@ -12,8 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 import static org.apache.juneau.dto.html5.HtmlBuilder.*;
+import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
 import java.io.*;
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
index 72b03a2..282fa04 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/TumblrParserResource.java
@@ -14,12 +14,9 @@ package org.apache.juneau.examples.rest;
 
 import static org.apache.juneau.html.HtmlDocSerializerContext.*;
 
-import java.lang.Object;
-
 import org.apache.juneau.*;
 import org.apache.juneau.dto.Link;
 import org.apache.juneau.dto.html5.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.microservice.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.rest.client.*;
@@ -44,7 +41,7 @@ public class TumblrParserResource extends Resource {
 	@RestMethod(name="GET", path="/{blogName}")
 	public ObjectList parseBlog(@Path String blogName) throws Exception {
 		ObjectList l = new ObjectList();
-		RestClient rc = new RestClient(JsonSerializer.class, JsonParser.class);
+		RestClient rc = new RestClientBuilder().build();
 		try {
 			String site = "http://" + blogName + ".tumblr.com/api/read/json";
 			ObjectMap m = rc.doGet(site).getResponse(ObjectMap.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/ClientTest.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/ClientTest.java b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/ClientTest.java
index ebf86e9..4470f1d 100644
--- a/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/ClientTest.java
+++ b/juneau-examples-rest/src/main/java/org/apache/juneau/examples/rest/addressbook/ClientTest.java
@@ -16,7 +16,6 @@ import java.text.*;
 import java.util.*;
 
 import org.apache.juneau.examples.addressbook.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.apache.juneau.xml.*;
 
@@ -31,8 +30,8 @@ public class ClientTest {
 			System.out.println("Running client test...");
 
 			// Create a client to handle XML requests and responses.
-			RestClient client = new RestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
-			RestClient xmlClient = new RestClient(XmlSerializer.DEFAULT_NS, XmlParser.DEFAULT);
+			RestClient client = new RestClientBuilder().build();
+			RestClient xmlClient = new RestClientBuilder(XmlSerializer.DEFAULT_NS, XmlParser.DEFAULT).build();
 			try {
 				String root = "http://localhost:10000/addressBook";
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/AddressBookResourceTest.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/AddressBookResourceTest.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/AddressBookResourceTest.java
index da66ac3..5f3f602 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/AddressBookResourceTest.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/AddressBookResourceTest.java
@@ -13,8 +13,8 @@
 package org.apache.juneau.examples.rest;
 
 import static org.apache.juneau.examples.rest.TestUtils.*;
-import static org.junit.Assert.*;
 import static org.apache.juneau.xml.XmlSerializerContext.*;
+import static org.junit.Assert.*;
 
 import java.util.*;
 
@@ -37,16 +37,31 @@ public class AddressBookResourceTest extends RestTestcase {
 	@BeforeClass
 	public static void beforeClass() throws Exception {
 		clients = new RestClient[] {
-			new SamplesRestClient(JsonSerializer.class, JsonParser.class),
-			new SamplesRestClient(XmlSerializer.class, XmlParser.class),
-			new SamplesRestClient(HtmlSerializer.class, HtmlParser.class).setAccept("text/html+stripped"),
-			new SamplesRestClient(XmlSerializer.class,  HtmlParser.class).setAccept("text/html+stripped")
+			SamplesMicroservice.client()
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.property(XML_autoDetectNamespaces, true)
+				.build(),
+			SamplesMicroservice.client()
+				.serializer(XmlSerializer.class)
+				.parser(XmlParser.class)
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.property(XML_autoDetectNamespaces, true)
+				.build(),
+			SamplesMicroservice.client()
+				.serializer(HtmlSerializer.class)
+				.parser(HtmlParser.class)
+				.accept("text/html+stripped")
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.property(XML_autoDetectNamespaces, true)
+				.build(),
+			SamplesMicroservice.client()
+				.serializer(XmlSerializer.class)
+				.parser(HtmlParser.class)
+				.accept("text/html+stripped")
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.property(XML_autoDetectNamespaces, true)
+				.build(),
 		};
-		for (RestClient c : clients) {
-			c.getSerializer().addPojoSwaps(CalendarSwap.DateMedium.class);
-			c.getParser().addPojoSwaps(CalendarSwap.DateMedium.class);
-			c.getSerializer().setProperty(XML_autoDetectNamespaces, true);
-		}
 	}
 
 	@AfterClass
@@ -56,6 +71,7 @@ public class AddressBookResourceTest extends RestTestcase {
 		}
 	}
 
+	
 	//====================================================================================================
 	// Get AddressBookResource as JSON
 	//====================================================================================================
@@ -76,7 +92,7 @@ public class AddressBookResourceTest extends RestTestcase {
 		+"\n		}"
 		+"\n	]"
 		+"\n}";			
-		JsonParser p = new JsonParser().addPojoSwaps(CalendarSwap.DateMedium.class);
+		JsonParser p = new JsonParserBuilder().pojoSwaps(CalendarSwap.DateMedium.class).build();
 		Person person = p.parse(in, Person.class);
 		if (debug) System.err.println(person);
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RestTestcase.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RestTestcase.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RestTestcase.java
index 0b79f66..8b7471a 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RestTestcase.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RestTestcase.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import org.apache.juneau.examples.rest.TestMicroservice;
 import org.junit.*;
 
 /**
@@ -26,12 +25,12 @@ public class RestTestcase {
 
 	@BeforeClass
 	public static void setUp() {
-		microserviceStarted = TestMicroservice.startMicroservice();
+		microserviceStarted = SamplesMicroservice.startMicroservice();
 	}
 
 	@AfterClass
 	public static void tearDown() {
 		if (microserviceStarted)
-			TestMicroservice.stopMicroservice();
+			SamplesMicroservice.stopMicroservice();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
index 0133292..80a4aa9 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
@@ -25,27 +25,18 @@ import org.junit.*;
 
 public class RootResourcesTest extends RestTestcase {
 
-	private static String path = TestMicroservice.getURI().getPath();              // /jazz/juneau/sample
+	private static String path = SamplesMicroservice.getURI().getPath();              // /jazz/juneau/sample
 	private static boolean debug = false;
 
-	private static RestClient jsonClient;
+	private RestClient jsonClient = SamplesMicroservice.DEFAULT_CLIENT;
 
-	@BeforeClass
-	public static void beforeClass() {
-		jsonClient = new SamplesRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
-	}
-
-	@AfterClass
-	public static void afterClass() {
-		jsonClient.closeQuietly();
-	}
 
 	//====================================================================================================
 	// text/json
 	//====================================================================================================
 	@Test
 	public void testJson() throws Exception {
-		RestClient client = new SamplesRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = SamplesMicroservice.DEFAULT_CLIENT;
 		RestCall r = client.doGet("");
 		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
 		assertEquals("helloWorld", x[0].getName().getName());
@@ -57,8 +48,6 @@ public class RootResourcesTest extends RestTestcase {
 		String s = x2.getObjectMap("info").getString("description");
 		if (debug) System.err.println(s);
 		assertTrue(s, s.startsWith("This is an example"));
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -66,7 +55,7 @@ public class RootResourcesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testXml() throws Exception {
-		RestClient client = new SamplesRestClient().setParser(XmlParser.DEFAULT);
+		RestClient client = SamplesMicroservice.client().parser(XmlParser.DEFAULT).build();
 		RestCall r = client.doGet("");
 		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
 		assertEquals("helloWorld", x[0].getName().getName());
@@ -78,7 +67,7 @@ public class RootResourcesTest extends RestTestcase {
 		String s = x2.getObjectMap("info").getString("description");
 		if (debug) System.err.println(s);
 		assertTrue(s, s.startsWith("This is an example"));
-
+		
 		client.closeQuietly();
 	}
 
@@ -87,19 +76,19 @@ public class RootResourcesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testHtmlStripped() throws Exception {
-		RestClient client = new SamplesRestClient().setParser(HtmlParser.DEFAULT).setAccept("text/html+stripped");
+		RestClient client = SamplesMicroservice.client().parser(HtmlParser.DEFAULT).accept("text/html+stripped").build();
 		RestCall r = client.doGet("");
 		ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
 		assertEquals("helloWorld", x[0].getName().getName());
 		assertTrue(x[0].getName().getHref().endsWith("/helloWorld"));
 		assertEquals("Hello World sample resource", x[0].getDescription());
 
-		r = jsonClient.doOptions("").setHeader("Accept", "text/json");
+		r = jsonClient.doOptions("").accept("text/json");
 		ObjectMap x2 = r.getResponse(ObjectMap.class);
 		String s = x2.getObjectMap("info").getString("description");
 		if (debug) System.err.println(s);
 		assertTrue(s, s.startsWith("This is an example"));
-
+		
 		client.closeQuietly();
 	}
 
@@ -108,12 +97,11 @@ public class RootResourcesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testStyleSheet() throws Exception {
-		RestClient client = new SamplesRestClient().setAccept("text/css");
+		RestClient client = SamplesMicroservice.client().accept("text/css").build();
 		RestCall r = client.doGet("/style.css");
 		String css = r.getResponseAsString();
 		if (debug) System.err.println(css);
 		assertTrue(css, css.indexOf("table {") != -1);
-
 		client.closeQuietly();
 	}
 
@@ -122,13 +110,12 @@ public class RootResourcesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testJsonSchema() throws Exception {
-		RestClient client = new SamplesRestClient().setParser(JsonParser.DEFAULT).setAccept("text/json+schema");
+		RestClient client = SamplesMicroservice.client().parser(JsonParser.DEFAULT).accept("text/json+schema").build();
 		RestCall r = client.doGet("");
 		ObjectMap m = r.getResponse(ObjectMap.class);
 		if (debug) System.err.println(m);
 		assertEquals("org.apache.juneau.rest.labels.ChildResourceDescriptions<org.apache.juneau.rest.labels.ResourceDescription>", m.getString("description"));
 		assertEquals("org.apache.juneau.rest.labels.ResourceDescription", m.getObjectMap("items").getString("description"));
-
 		client.closeQuietly();
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SampleRemoteableServicesResourceTest.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SampleRemoteableServicesResourceTest.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SampleRemoteableServicesResourceTest.java
index 28f38fe..1eca174 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SampleRemoteableServicesResourceTest.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SampleRemoteableServicesResourceTest.java
@@ -12,14 +12,14 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.examples.rest;
 
-import static org.junit.Assert.*;
 import static org.apache.juneau.xml.XmlSerializerContext.*;
+import static org.junit.Assert.*;
 
 import org.apache.juneau.examples.addressbook.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.apache.juneau.transforms.*;
-import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
 
@@ -30,16 +30,20 @@ public class SampleRemoteableServicesResourceTest extends RestTestcase {
 	@BeforeClass
 	public static void beforeClass() throws Exception {
 		clients = new RestClient[] {
-			new SamplesRestClient(JsonSerializer.class, JsonParser.class),
-			new SamplesRestClient(XmlSerializer.class, XmlParser.class),
-//	TODO - broken?		new TestRestClient(HtmlSerializer.class, HtmlParser.class).setAccept("text/html+stripped"),
-			new SamplesRestClient(UonSerializer.class, UonParser.class),
+			SamplesMicroservice.client()
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.remoteableServletUri("/remoteable")
+				.build(),
+			SamplesMicroservice.client(XmlSerializer.class, XmlParser.class)
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.remoteableServletUri("/remoteable")
+				.property(XML_autoDetectNamespaces, true)
+				.build(),
+			SamplesMicroservice.client(UonSerializer.class, UonParser.class)
+				.pojoSwaps(CalendarSwap.DateMedium.class)
+				.remoteableServletUri("/remoteable")
+				.build(),
 		};
-		for (RestClient c : clients) {
-			c.addPojoSwaps(CalendarSwap.DateMedium.class);
-			c.setRemoteableServletUri("/remoteable");
-			c.setProperty(XML_autoDetectNamespaces, true);
-		}
 	}
 
 	@AfterClass

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
new file mode 100644
index 0000000..21538ed
--- /dev/null
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
@@ -0,0 +1,110 @@
+// ***************************************************************************************************************************
+// * 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.net.*;
+import java.util.*;
+
+import org.apache.juneau.microservice.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.plaintext.*;
+import org.apache.juneau.rest.client.*;
+import org.apache.juneau.serializer.*;
+
+/**
+ * Utility class for starting up the examples microservice.
+ * <p>
+ * This class is NOT thread safe.
+ */
+public class SamplesMicroservice {
+	static RestMicroservice microservice;
+	static URI microserviceURI;
+
+	// Reusable HTTP clients that get created and shut down with the microservice.
+	public static RestClient DEFAULT_CLIENT;
+	public static RestClient DEFAULT_CLIENT_PLAINTEXT;
+
+	/**
+	 * Starts the microservice.
+	 * @return <jk>true</jk> if the service started, <jk>false</jk> if it's already started.
+	 * If this returns <jk>false</jk> then don't call stopMicroservice()!.
+	 */
+	public static boolean startMicroservice() {
+		if (microservice != null)
+			return false;
+		try {
+			Locale.setDefault(Locale.US);
+			microservice = new RestMicroservice().setConfig("examples.cfg", false);
+			microserviceURI = microservice.start().getURI();
+			DEFAULT_CLIENT = client().build();
+			DEFAULT_CLIENT_PLAINTEXT = client(PlainTextSerializer.class, PlainTextParser.class).build();
+			return true;
+		} catch (Throwable e) {
+			// Probably already started.
+			e.printStackTrace();
+			System.err.println(e); // NOT DEBUG
+			return false;
+		}
+	}
+
+	/**
+	 * Returns the URI of the microservice.
+	 * @return The URI of the microservice.
+	 */
+	public static URI getURI() {
+		if (microservice == null)
+			startMicroservice();
+		return microserviceURI;
+	}
+	
+	/**
+	 * Stops the microservice.
+	 */
+	public static void stopMicroservice() {
+		try {
+			microservice.stop();
+			microservice = null;
+			DEFAULT_CLIENT.closeQuietly();
+			DEFAULT_CLIENT_PLAINTEXT.closeQuietly();
+		} catch (Exception e) {
+			System.err.println(e); // NOT DEBUG
+		}
+	}
+	
+	/**
+	 * Create a new HTTP client.
+	 */
+	public static RestClientBuilder client() {
+		try {
+			return new RestClientBuilder()
+				.rootUrl(microserviceURI)
+			;
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Create a new HTTP client using the specified serializer and parser.
+	 */
+	public static RestClientBuilder client(Serializer s, Parser p) {
+		return client().serializer(s).parser(p);
+	}
+
+	/**
+	 * Create a new HTTP client using the specified serializer and parser.
+	 */
+	public static RestClientBuilder client(Class<? extends Serializer> s, Class<? extends Parser> p) {
+		return client().serializer(s).parser(p);
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesRestClient.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesRestClient.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesRestClient.java
deleted file mode 100644
index b3abd2b..0000000
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/SamplesRestClient.java
+++ /dev/null
@@ -1,69 +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.examples.rest;
-
-import java.security.*;
-
-import javax.net.ssl.*;
-
-import org.apache.http.conn.ssl.*;
-import org.apache.http.impl.client.*;
-import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
-import org.apache.juneau.serializer.*;
-
-/**
- * REST client with lenient SSL support and lax redirection strategy.
- */
-public class SamplesRestClient extends RestClient {
-
-	public SamplesRestClient(Class<? extends Serializer> s, Class<? extends Parser> p) throws InstantiationException {
-		super(s,p);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public SamplesRestClient(Serializer s, Parser p) {
-		super(s,p);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public SamplesRestClient() {
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public SamplesRestClient(CloseableHttpClient c) {
-		super(c);
-		setRootUrl(TestMicroservice.getURI());
-	}
-
-	public static SSLConnectionSocketFactory getSSLSocketFactory() throws Exception {
-		SSLContext sslContext = SSLContext.getInstance("SSL");
-		TrustManager tm = new SimpleX509TrustManager(true);
-		sslContext.init(null, new TrustManager[]{tm}, new SecureRandom());
-		return new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
-	}
-
-	@Override /* RestClient */
-	protected CloseableHttpClient createHttpClient() throws Exception {
-		try {
-			return HttpClients.custom().setSSLSocketFactory(getSSLSocketFactory()).setRedirectStrategy(new LaxRedirectStrategy()).build();
-		} catch (KeyStoreException e) {
-			throw new RuntimeException(e);
-		} catch (NoSuchAlgorithmException e) {
-			throw new RuntimeException(e);
-		} catch (Throwable e) {
-			e.printStackTrace();
-			return null;
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMicroservice.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMicroservice.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMicroservice.java
deleted file mode 100644
index c7877d7..0000000
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMicroservice.java
+++ /dev/null
@@ -1,72 +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.examples.rest;
-
-import java.net.*;
-import java.util.*;
-
-import org.apache.juneau.microservice.*;
-
-/**
- * Utility class for starting up the examples microservice.
- * <p>
- * This class is NOT thread safe.
- * 
- * @author james.bognar
- */
-public class TestMicroservice {
-	static RestMicroservice microservice;
-	static URI microserviceURI;
-
-	/**
-	 * Starts the microservice.
-	 * @return <jk>true</jk> if the service started, <jk>false</jk> if it's already started.
-	 * If this returns <jk>false</jk> then don't call stopMicroservice()!.
-	 */
-	public static boolean startMicroservice() {
-		if (microservice != null)
-			return false;
-		try {
-			Locale.setDefault(Locale.US);
-			microservice = new RestMicroservice().setConfig("examples.cfg", false);
-			microserviceURI = microservice.start().getURI();
-			return true;
-		} catch (Throwable e) {
-			// Probably already started.
-			System.err.println(e); // NOT DEBUG
-			return false;
-		}
-	}
-
-	/**
-	 * Returns the URI of the microservice.
-	 * @return The URI of the microservice.
-	 */
-	public static URI getURI() {
-		if (microservice == null)
-			startMicroservice();
-		return microserviceURI;
-	}
-	
-	/**
-	 * Stops the microservice.
-	 */
-	public static void stopMicroservice() {
-		try {
-			microservice.stop();
-			microservice = null;
-		} catch (Exception e) {
-			System.err.println(e); // NOT DEBUG
-		}
-	}
-}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMultiPartFormPostsTest.java
----------------------------------------------------------------------
diff --git a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMultiPartFormPostsTest.java b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMultiPartFormPostsTest.java
index f41b122..c070408 100644
--- a/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMultiPartFormPostsTest.java
+++ b/juneau-examples-rest/src/test/java/org/apache/juneau/examples/rest/TestMultiPartFormPostsTest.java
@@ -33,7 +33,7 @@ public class TestMultiPartFormPostsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testUpload() throws Exception {
-		RestClient client = new SamplesRestClient();
+		RestClient client = SamplesMicroservice.DEFAULT_CLIENT;
 		File f = FileUtils.createTempFile("testMultiPartFormPosts.txt");
 		IOPipe.create(new StringReader("test!"), new FileWriter(f)).closeOut().run();
 		HttpEntity entity = MultipartEntityBuilder.create().addBinaryBody(f.getName(), f).build();
@@ -41,7 +41,5 @@ public class TestMultiPartFormPostsTest extends RestTestcase {
 
 		String downloaded = client.doGet(URL + '/' + f.getName() + "?method=VIEW").getResponseAsString();
 		assertEquals("test!", downloaded);
-
-		client.closeQuietly();
 	}
 }
\ No newline at end of file


[14/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
index aefcb6e..e84e593 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/WriterSerializer.java
@@ -40,6 +40,14 @@ import org.apache.juneau.annotation.*;
  */
 public abstract class WriterSerializer extends Serializer {
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	protected WriterSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
 	@Override /* Serializer */
 	public boolean isWriterSerializer() {
 		return true;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/serializer/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/serializer/package.html b/juneau-core/src/main/java/org/apache/juneau/serializer/package.html
index 06fcb84..00e5568 100644
--- a/juneau-core/src/main/java/org/apache/juneau/serializer/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/serializer/package.html
@@ -125,7 +125,7 @@
 	}
 	</p>
 	<p>
-		Serializer that take advantage of the entire {@link org.apache.juneau.CoreApi} interface to be able to serialize arbitrary beans and POJOs is
+		Serializer that take advantage of the entire {@link org.apache.juneau.CoreObject} interface to be able to serialize arbitrary beans and POJOs is
 			considerably more complex and outside the scope of this document.<br>  
 		If developing such a serializer, the best course of action would be to replicate what occurs in the {@link org.apache.juneau.json.JsonSerializer} class.
 	</p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
index a3a94b5..707402e 100644
--- a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializer.java
@@ -43,6 +43,15 @@ import org.apache.juneau.xml.*;
 @Produces(value="text/xml+soap",contentType="text/xml")
 public final class SoapXmlSerializer extends XmlSerializer {
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public SoapXmlSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+
 	//--------------------------------------------------------------------------------
 	// Overridden methods
 	//--------------------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
new file mode 100644
index 0000000..cbf8e36
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/soap/SoapXmlSerializerBuilder.java
@@ -0,0 +1,590 @@
+// ***************************************************************************************************************************
+// * 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.soap;
+
+import static org.apache.juneau.soap.SoapXmlSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.xml.*;
+
+/**
+ * Builder class for building instances of soap/xml serializers.
+ */
+public class SoapXmlSerializerBuilder extends XmlSerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public SoapXmlSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public SoapXmlSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializer build() {
+		return new SoapXmlSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  The <code>SOAPAction</code> HTTP header value to set on responses.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"SoapXmlSerializer.SOAPAction"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"http://www.w3.org/2003/05/soap-envelope"</js>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>SOAPXML_SOAPAction</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SoapXmlSerializerContext#SOAPXML_SOAPAction
+	 */
+	public SoapXmlSerializerBuilder uriAnchorText(String value) {
+		return property(SOAPXML_SOAPAction, value);
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder enableNamespaces(boolean value) {
+		super.enableNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder autoDetectNamespaces(boolean value) {
+		super.autoDetectNamespaces(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder addNamespaceUrisToRoot(boolean value) {
+		super.addNamespaceUrisToRoot(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder defaultNamespace(String value) {
+		super.defaultNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder xsNamespace(Namespace value) {
+		super.xsNamespace(value);
+		return this;
+	}
+
+	@Override /* XmlSerializerBuilder */
+	public SoapXmlSerializerBuilder namespaces(Namespace...values) {
+		super.namespaces(values);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public SoapXmlSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> SoapXmlSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public SoapXmlSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/MapVar.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/MapVar.java b/juneau-core/src/main/java/org/apache/juneau/svl/MapVar.java
index c9561e6..85b830f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/MapVar.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/MapVar.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.svl;
 
 import static org.apache.juneau.internal.ThrowableUtils.*;
+
 import java.util.*;
 
 /**

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/Var.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/Var.java b/juneau-core/src/main/java/org/apache/juneau/svl/Var.java
index 026d515..29dc5f2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/Var.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/Var.java
@@ -27,7 +27,7 @@ import java.io.*;
  * 	<li>{@link #resolve(VarResolverSession,String)} - For simple vars.
  * 	<li>{@link #resolveTo(VarResolverSession,Writer,String)} - For streamed vars.
  * </ul>
- * Subclasses MUST implement a no-arg constructor so that class names can be passed to the {@link VarResolver#addVars(Class...)} method.
+ * Subclasses MUST implement a no-arg constructor so that class names can be passed to the {@link VarResolverBuilder#vars(Class...)} method.
  * They must also be thread safe!
  * <p>
  * Two direct abstract subclasses are provided to differentiated between simple and streamed vars:

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/VarResolver.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolver.java b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolver.java
index 55ef915..deb3eb3 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolver.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolver.java
@@ -12,13 +12,10 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.svl;
 
-import static java.text.MessageFormat.*;
-import static org.apache.juneau.svl.VarResolverContext.*;
 
 import java.io.*;
 import java.util.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.ini.*;
 import org.apache.juneau.svl.vars.*;
 
@@ -28,7 +25,7 @@ import org.apache.juneau.svl.vars.*;
  * Variables are of the form <code>$X{key}</code>, where <code>X</code> can consist of zero or more ASCII characters.<br>
  * 	The variable key can contain anything, even nested variables that get recursively resolved.
  * <p>
- * Variables are defined through the {@link #addVars(Class[])} method.
+ * Variables are defined through the {@link VarResolverBuilder#vars(Class[])} method.
  * <p>
  * The {@link Var} interface defines how variables are converted to values.
  * <p>
@@ -60,7 +57,6 @@ import org.apache.juneau.svl.vars.*;
  * <p>
  * Context objects are arbitrary objects associated with this var resolver, such as
  * 	a {@link ConfigFile} object.
- * They are set through the {@link #setContextObject(String, Object)} method.
  * They can be any class type.
  * <p>
  * Context objects can be retrieved by {@link Var} classes through the {@link VarResolverSession#getSessionObject(Class, String)} method.
@@ -78,22 +74,22 @@ import org.apache.juneau.svl.vars.*;
  * 	that are identical to {@link VarResolver#resolve(String)} and {@link VarResolver#resolveTo(String, Writer)} except that the <code>Var</code> objects
  * 	have access to the session objects through the {@link VarResolverSession#getSessionObject(Class, String)} method.
  * <p>
- * Session objects are specified through either the {@link #createSession(Map)} method or the {@link VarResolverSession#setSessionObject(String, Object)} methods.
+ * Session objects are specified through either the {@link #createSession(Map)} method or the {@link VarResolverSession#sessionObject(String, Object)} methods.
  *
  * <h6 class='topic'>Cloning</h6>
  * <p>
- * Var resolvers can be cloned by using the {@link #clone()} method.
+ * Var resolvers can be cloned by using the {@link #builder()} method.
  * Cloning a resolver will copy it's {@link Var} class names and context objects.
  * <p>
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Create a resolver that copies the default resolver and adds $C and $ARG vars.</jc>
- * 	VarResolver myVarResolver = VarResolver.<jsf>DEFAULT</jsf>.clone().addVars(ConfigVar.<jk>class</jk>, ArgsVar.<jk>class</jk>);
+ * 	VarResolver myVarResolver = VarResolver.<jsf>DEFAULT</jsf>.builder().vars(ConfigVar.<jk>class</jk>, ArgsVar.<jk>class</jk>).build();
  * </p>
  *
  * @see org.apache.juneau.svl
  */
-public class VarResolver extends CoreApi {
+public class VarResolver {
 
 	/**
 	 * Default string variable resolver with support for system properties and environment variables:
@@ -108,59 +104,47 @@ public class VarResolver extends CoreApi {
 	 * @see SystemPropertiesVar
 	 * @see EnvVariablesVar
 	 */
-	public static final VarResolver DEFAULT = new VarResolver().addVars(SystemPropertiesVar.class, EnvVariablesVar.class, SwitchVar.class, IfVar.class).lock();
+	public static final VarResolver DEFAULT = new VarResolverBuilder().defaultVars().build();
+
+	final VarResolverContext ctx;
 
 	/**
-	 * Construct an empty var resolver with no vars.
+	 * Constructor.
+	 * @param vars The var classes
+	 * @param contextObjects
 	 */
-	public VarResolver() {}
+	public VarResolver(Class<? extends Var>[] vars, Map<String,Object> contextObjects) {
+		this.ctx = new VarResolverContext(vars, contextObjects);
+	}
 
 	/**
-	 * Register new variables with this resolver.
+	 * Returns a new builder object using the settings in this resolver as a base.
 	 *
-	 * @param vars The variable resolver classes.
-	 * These classes must subclass from {@link Var} and have no-arg constructors.
-	 * @return This object (for method chaining).
+	 * @return A new var resolver builder.
 	 */
-	public VarResolver addVars(Class<?>...vars) {
-		checkLock();
-		ContextFactory cf = getContextFactory();
-		for (Class<?> v : vars) {
-			try {
-				v.newInstance();
-			} catch (InstantiationException e) {
-				throw new UnsupportedOperationException(format("Cannot instantiate variable class {0}.  Must have a public no-arg constructor.", v.getName()));
-			} catch (RuntimeException e) {
-				throw e;
-			} catch (Exception e) {
-				throw new RuntimeException(e);
-			}
-			cf.addToProperty(SVL_vars, v);
-		}
-		return this;
+	public VarResolverBuilder builder() {
+		return new VarResolverBuilder()
+			.vars(ctx.getVars())
+			.contextObjects(ctx.getContextObjects());
 	}
 
 	/**
-	 * Associates a context object with this resolver.
-	 *
-	 * @param name The name of the context object.
-	 * @param object The context object.
-	 * @return This object (for method chaining).
+	 * Returns the read-only properties on this variable resolver.
+	 * @return The read-only properties on this variable resolver.
 	 */
-	public VarResolver setContextObject(String name, Object object) {
-		getContextFactory().putToProperty(SVL_context, name, object);
-		return this;
+	public VarResolverContext getContext() {
+		return ctx;
 	}
 
 	/**
 	 * Creates a new resolver session with no session objects.
 	 * <p>
-	 * Session objects can be associated with the specified session using the {@link VarResolverSession#setSessionObject(String, Object)} method.
+	 * Session objects can be associated with the specified session using the {@link VarResolverSession#sessionObject(String, Object)} method.
 	 *
 	 * @return A new resolver session.
 	 */
 	public VarResolverSession createSession() {
-		return new VarResolverSession(getContext(VarResolverContext.class), null);
+		return new VarResolverSession(ctx, null);
 	}
 
 	/**
@@ -170,7 +154,7 @@ public class VarResolver extends CoreApi {
 	 * @return A new resolver session.
 	 */
 	public VarResolverSession createSession(Map<String,Object> sessionObjects) {
-		return new VarResolverSession(getContext(VarResolverContext.class), sessionObjects);
+		return new VarResolverSession(ctx, sessionObjects);
 	}
 
 	/**
@@ -199,25 +183,4 @@ public class VarResolver extends CoreApi {
 	public void resolveTo(String s, Writer w) throws IOException {
 		createSession(null).resolveTo(s, w);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* Lockable */
-	public VarResolver lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public VarResolver clone() {
-		try {
-			return (VarResolver)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e);
-		}
-	}
-}
-
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverBuilder.java b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverBuilder.java
new file mode 100644
index 0000000..9d6428a
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverBuilder.java
@@ -0,0 +1,109 @@
+// ***************************************************************************************************************************
+// * 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.svl;
+
+import static java.text.MessageFormat.*;
+
+import java.util.*;
+
+import org.apache.juneau.svl.vars.*;
+
+/**
+ * Builder class for building instances of {@link VarResolver}.
+ */
+@SuppressWarnings("hiding")
+public class VarResolverBuilder {
+
+	private final List<Class<? extends Var>> vars = new ArrayList<Class<? extends Var>>();
+	private final Map<String,Object> contextObjects = new HashMap<String,Object>();
+
+	/**
+	 * Create a new var resolver using the settings in this builder.
+	 *
+	 * @return A new var resolver.
+	 */
+	@SuppressWarnings("unchecked")
+	public VarResolver build() {
+		return new VarResolver(vars.toArray(new Class[vars.size()]), contextObjects);
+	}
+
+	/**
+	 * Register new variables with this resolver.
+	 *
+	 * @param vars The variable resolver classes.
+	 * These classes must subclass from {@link Var} and have no-arg constructors.
+	 * @return This object (for method chaining).
+	 */
+	@SuppressWarnings("unchecked")
+	public VarResolverBuilder vars(Class<?>...vars) {
+		for (Class<?> v : vars) {
+			try {
+				v.newInstance();
+			} catch (InstantiationException e) {
+				throw new UnsupportedOperationException(format("Cannot instantiate variable class {0}.  Must have a public no-arg constructor.", v.getName()));
+			} catch (RuntimeException e) {
+				throw e;
+			} catch (Exception e) {
+				throw new RuntimeException(e);
+			}
+			this.vars.add((Class<? extends Var>)v);
+		}
+		return this;
+	}
+
+	/**
+	 * Adds the default variables to this builder.
+	 * <p>
+	 * The default variables are:
+	 * <ul>
+	 * 	<li>{@link SystemPropertiesVar}
+	 * 	<li>{@link EnvVariablesVar}
+	 * 	<li>{@link SwitchVar}
+	 * 	<li>{@link IfVar}
+	 * </ul>
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public VarResolverBuilder defaultVars() {
+		return vars(SystemPropertiesVar.class, EnvVariablesVar.class, SwitchVar.class, IfVar.class);
+	}
+
+	/**
+	 * Associates a context object with this resolver.
+	 * <p>
+	 * A context object is essentially some environmental object that doesn't change
+	 * but is used by vars to customize output.
+	 *
+	 * @param name The name of the context object.
+	 * @param object The context object.
+	 * @return This object (for method chaining).
+	 */
+	public VarResolverBuilder contextObject(String name, Object object) {
+		contextObjects.put(name, object);
+		return this;
+	}
+
+	/**
+	 * Associates multiple context objects with this resolver.
+	 * <p>
+	 * A context object is essentially some environmental object that doesn't change
+	 * but is used by vars to customize output.
+	 *
+	 * @param map A map of context objects keyed by their name.
+	 * @return This object (for method chaining).
+	 */
+	public VarResolverBuilder contextObjects(Map<String,Object> map) {
+		contextObjects.putAll(map);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverContext.java b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverContext.java
index 2767154..b3d0e18 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverContext.java
@@ -15,67 +15,32 @@ package org.apache.juneau.svl;
 import java.util.*;
 import java.util.concurrent.*;
 
-import org.apache.juneau.*;
 import org.apache.juneau.internal.*;
 
 /**
  * Configurable properties on the {@link VarResolver} class.
  * <p>
  * Used to associate {@link Var Vars} and context objects with {@link VarResolver VarResolvers}.
- * <p>
- * See {@link ContextFactory} for more information about context properties.
  *
  * @see org.apache.juneau.svl
  */
-public class VarResolverContext extends Context {
-
-	/**
-	 * An explicit list of Java classes to be excluded from consideration as being beans (<code>Set&lt;Class&gt;</code>).
-	 * <p>
-	 * Not-bean classes are typically converted to <code>Strings</code> during serialization even if they
-	 * appear to be bean-like.
-	 */
-	public static final String SVL_vars = "Svl.vars.set";
-
-	/**
-	 * Add to the list of packages whose classes should not be considered beans.
-	 */
-	public static final String SVL_vars_add = "Svl.vars.set.add";
-
-	/**
-	 * Remove from the list of packages whose classes should not be considered beans.
-	 */
-	public static final String SVL_vars_remove = "Svl.vars.set.remove";
-
-	/**
-	 * Context objects associated with the resolver (<code>Map$lt;String,Object&gt;</code>).
-	 */
-	public static final String SVL_context = "Svl.context.map";
-
-	/**
-	 * Adds a new map entry to the {@link #SVL_context} property.
-	 */
-	public static final String SVL_context_put = "Svl.context.map.put";
-
-
-	// Map of Vars added through addVar() method.
-	private final Map<String,Var> stringVars;
+public class VarResolverContext {
 
+	private final Class<?>[] vars;
+	private final Map<String,Var> varMap;
 	private final Map<String,Object> contextObjects;
 
-
 	/**
 	 * Constructor.
-	 *
-	 * @param cf The context factory to copy from.
+	 * @param vars The Var classes used for resolving string variables.
+	 * @param contextObjects Read-only context objects.
 	 */
-	public VarResolverContext(ContextFactory cf) {
-		super(cf);
-		ContextFactory.PropertyMap pm = cf.getPropertyMap("Svl");
+	public VarResolverContext(Class<? extends Var>[] vars, Map<String,Object> contextObjects) {
+
+		this.vars = Arrays.copyOf(vars, vars.length);
 
-		Class<?>[] varClasses = pm.get(SVL_vars, Class[].class, new Class[0]);
 		Map<String,Var> m = new ConcurrentSkipListMap<String,Var>();
-		for (Class<?> c : varClasses) {
+		for (Class<?> c : vars) {
 			if (! ClassUtils.isParentClass(Var.class, c))
 				throw new RuntimeException("Invalid variable class.  Must extend from Var");
 			try {
@@ -85,9 +50,9 @@ public class VarResolverContext extends Context {
 				throw new RuntimeException(e);
 			}
 		}
-		this.stringVars = Collections.unmodifiableMap(m);
 
-		this.contextObjects = Collections.unmodifiableMap(pm.getMap(SVL_context, String.class, Object.class, Collections.<String,Object>emptyMap()));
+		this.varMap = Collections.unmodifiableMap(m);
+		this.contextObjects = contextObjects == null ? null : Collections.unmodifiableMap(new ConcurrentHashMap<String,Object>(contextObjects));
 	}
 
 	/**
@@ -95,8 +60,17 @@ public class VarResolverContext extends Context {
 	 *
 	 * @return A map whose keys are var names (e.g. <js>"S"</js>) and values are {@link Var} instances.
 	 */
-	protected Map<String,Var> getVars() {
-		return stringVars;
+	protected Map<String,Var> getVarMap() {
+		return varMap;
+	}
+
+	/**
+	 * Returns an array of variables define in this variable resolver context.
+	 *
+	 * @return A new array containing the variables in this context.
+	 */
+	protected Class<?>[] getVars() {
+		return Arrays.copyOf(vars, vars.length);
 	}
 
 	/**
@@ -106,6 +80,15 @@ public class VarResolverContext extends Context {
 	 * @return The context object, or <jk>null</jk> if no context object is specified with that name.
 	 */
 	protected Object getContextObject(String name) {
-		return contextObjects.get(name);
+		return contextObjects == null ? null : contextObjects.get(name);
+	}
+
+	/**
+	 * Returns the context map of this variable resolver context.
+	 *
+	 * @return An unmodifiable map of the context objects of this variable resolver context.
+	 */
+	protected Map<String,Object> getContextObjects() {
+		return contextObjects;
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverSession.java b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverSession.java
index 419fd2a..824e0e2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/VarResolverSession.java
@@ -18,8 +18,6 @@ import static org.apache.juneau.internal.StringUtils.*;
 import java.io.*;
 import java.util.*;
 
-import org.apache.juneau.*;
-
 /**
  * A var resolver session that combines a {@link VarResolver} with one or more session objects.
  * <p>
@@ -34,21 +32,22 @@ import org.apache.juneau.*;
  *
  * @see org.apache.juneau.svl
  */
-public class VarResolverSession extends Session {
+public class VarResolverSession {
 
 	private final VarResolverContext context;
+	private final Map<String,Object> sessionObjects;
 
 	/**
 	 * Constructor.
 	 *
 	 * @param context The {@link VarResolver} context object that contains the {@link Var Vars} and
 	 * 	context objects associated with that resolver.
-	 * @param sessionObjects
+	 * @param sessionObjects The session objects.
+	 *
 	 */
 	public VarResolverSession(VarResolverContext context, Map<String,Object> sessionObjects) {
-		super(context, null);
 		this.context = context;
-		addToCache(sessionObjects);
+		this.sessionObjects = sessionObjects != null ? sessionObjects : new HashMap<String,Object>();
 	}
 
 	/**
@@ -58,8 +57,8 @@ public class VarResolverSession extends Session {
 	 * @param o The session object.
 	 * @return This method (for method chaining).
 	 */
-	public VarResolverSession setSessionObject(String name, Object o) {
-		addToCache(name, o);
+	public VarResolverSession sessionObject(String name, Object o) {
+		sessionObjects.put(name, o);
 		return this;
 	}
 
@@ -266,16 +265,17 @@ public class VarResolverSession extends Session {
 	 * @return The session object.  Never <jk>null</jk>.
 	 * @throws RuntimeException If session object with specified name does not exist.
 	 */
+	@SuppressWarnings("unchecked")
 	public <T> T getSessionObject(Class<T> c, String name) {
 		T t = null;
 		try {
-			t = getFromCache(c, name);
+			t = (T)sessionObjects.get(name);
 			if (t == null) {
-				addToCache(name, this.context.getContextObject(name));
-				t = getFromCache(c, name);
+				sessionObjects.put(name, this.context.getContextObject(name));
+				t = (T)sessionObjects.get(name);
 			}
 		} catch (Exception e) {
-			throw new RuntimeException(format("Session object ''{0}'' or context object ''SvlContext.{0}'' could not be converted to type ''{1}''.", name, c.getName()));
+			throw new RuntimeException(format("Session object ''{0}'' or context object ''SvlContext.{0}'' could not be converted to type ''{1}''.", name, c.getName()), e);
 		}
 		if (t == null)
 			throw new RuntimeException(format("Session object ''{0}'' or context object ''SvlContext.{0}'' not found.", name));
@@ -289,6 +289,6 @@ public class VarResolverSession extends Session {
 	 * @return The {@link Var} instance, or <jk>null</jk> if no <code>Var</code> is associated with the specified name.
 	 */
 	protected Var getVar(String name) {
-		return this.context.getVars().get(name);
+		return this.context.getVarMap().get(name);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/svl/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/svl/package.html b/juneau-core/src/main/java/org/apache/juneau/svl/package.html
index fe61c42..9ef51ef 100644
--- a/juneau-core/src/main/java/org/apache/juneau/svl/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/svl/package.html
@@ -125,7 +125,7 @@
 	
 	<jc>// Next create a var resolver that extends the existing DEFAULT resolver
 	// that supports resolving system properties.</jc>
-	VarResolver r = VarResolver.<jsf>DEFAULT</jsf>.clone().addVars(UrlEncodeVar.<jk>class</jk>);
+	VarResolver r = VarResolver.<jsf>DEFAULT</jsf>.builder().vars(UrlEncodeVar.<jk>class</jk>).build();
 	
 	<jc>// Retrieve a system property and URL-encode it if necessary.</jc>
 	String myProperty = r.resolve(<js>"$URLEncode{$S{my.property}}"</js>);
@@ -191,7 +191,7 @@
 			These object dependencies are made by setting context objects on the var resolver.
 		</p>
 		<p>
-			Context objects are set through the {@link org.apache.juneau.svl.VarResolver#setContextObject(String,Object)} method.
+			Context objects are set through the {@link org.apache.juneau.svl.VarResolverBuilder#contextObject(String,Object)} method.
 			They can be any class type.
 		</p>
 		<p>
@@ -209,19 +209,19 @@
 				of a {@link org.apache.juneau.svl.VarResolverSession} object that contains {@link org.apache.juneau.svl.VarResolverSession#resolve(String)} and {@link org.apache.juneau.svl.VarResolverSession#resolveTo(String,Writer)} methods
 				that are identical to {@link org.apache.juneau.svl.VarResolver#resolve(String)} and {@link org.apache.juneau.svl.VarResolver#resolveTo(String, Writer)} except that the <code>Var</code> objects
 				have access to the session objects through the {@link org.apache.juneau.svl.VarResolverSession#getSessionObject(Class, String)} method.
-			Session objects are specified through either the {@link org.apache.juneau.svl.VarResolver#createSession(Map)} method or the {@link org.apache.juneau.svl.VarResolverSession#setSessionObject(String, Object)} methods.
+			Session objects are specified through either the {@link org.apache.juneau.svl.VarResolver#createSession(Map)} method or the {@link org.apache.juneau.svl.VarResolverSession#sessionObject(String, Object)} methods.
 		</p>
 		<p>
 			Like Context object, Session objects are used by {@link org.apache.juneau.svl.Var Vars} by calling the {@link org.apache.juneau.svl.VarResolverSession#getSessionObject(Class, String)} method.
 		</p>
 		<p>
-			Var resolvers can be cloned and extended by using the {@link org.apache.juneau.svl.VarResolver#clone()} method.
+			Var resolvers can be cloned and extended by using the {@link org.apache.juneau.svl.VarResolver#builder()} method.
 			Cloning a resolver will copy it's {@link org.apache.juneau.svl.Var} class names and context objects.
 		</p>
 		<h6 class='topic'>Example:</h6>
 		<p class='bcode'>
 			<jc>// Create a resolver that copies the default resolver and adds $C and $ARG vars.</jc>
-			VarResolver myVarResolver = VarResolver.<jsf>DEFAULT</jsf>.clone().addVars(ConfigFileVar.<jk>class</jk>, ArgsVar.<jk>class</jk>);
+			VarResolver myVarResolver = VarResolver.<jsf>DEFAULT</jsf>.builder().vars(ConfigFileVar.<jk>class</jk>, ArgsVar.<jk>class</jk>).build();
 		</p>
 	</div>	
 	

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
index 76c8dc0..10fc8be 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/AnnotationBeanFilterBuilder.java
@@ -40,28 +40,28 @@ public final class AnnotationBeanFilterBuilder extends BeanFilterBuilder {
 			Bean b = li.previous();
 
 			if (! b.properties().isEmpty())
-				setProperties(StringUtils.split(b.properties(), ','));
+				properties(StringUtils.split(b.properties(), ','));
 
 			if (! b.typeName().isEmpty())
-				setTypeName(b.typeName());
+				typeName(b.typeName());
 
 			if (b.sort())
-				setSortProperties(true);
+				sortProperties(true);
 
 			if (! b.excludeProperties().isEmpty())
-				setExcludeProperties(StringUtils.split(b.excludeProperties(), ','));
+				excludeProperties(StringUtils.split(b.excludeProperties(), ','));
 
 			if (b.propertyNamer() != PropertyNamerDefault.class)
-				setPropertyNamer(b.propertyNamer());
+				propertyNamer(b.propertyNamer());
 
 			if (b.interfaceClass() != Object.class)
-				setInterfaceClass(b.interfaceClass());
+				interfaceClass(b.interfaceClass());
 
 			if (b.stopClass() != Object.class)
-				setStopClass(b.stopClass());
+				stopClass(b.stopClass());
 
 			if (b.beanDictionary().length > 0)
-				addToBeanDictionary(b.beanDictionary());
+				beanDictionary(b.beanDictionary());
 		}
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
index b44da60..bf30f3f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/BeanFilterBuilder.java
@@ -26,7 +26,7 @@ import org.apache.juneau.*;
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Create our serializer with a bean filter.</jc>
- * 	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(AddressFilter.<jk>class</jk>);
+ * 	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(AddressFilter.<jk>class</jk>).build();
  *
  * 	Address a = <jk>new</jk> Address();
  * 	String json = s.serialize(a); <jc>// Serializes only street, city, state.</jc>
@@ -43,6 +43,7 @@ import org.apache.juneau.*;
  * <h5 class='section'>Additional information:</h5>
  * See <a class='doclink' href='package-summary.html#TOC'>org.apache.juneau.transform</a> for more information.
  */
+@SuppressWarnings("hiding")
 public abstract class BeanFilterBuilder {
 
 	Class<?> beanClass;
@@ -68,7 +69,7 @@ public abstract class BeanFilterBuilder {
 	 * @param typeName The dictionary name associated with this bean.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setTypeName(String typeName) {
+	public BeanFilterBuilder typeName(String typeName) {
 		this.typeName = typeName;
 		return this;
 	}
@@ -81,7 +82,7 @@ public abstract class BeanFilterBuilder {
 	 * @param properties The properties associated with the bean class.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setProperties(String...properties) {
+	public BeanFilterBuilder properties(String...properties) {
 		this.properties = properties;
 		return this;
 	}
@@ -92,7 +93,7 @@ public abstract class BeanFilterBuilder {
 	 * @param excludeProperties The list of properties to ignore on a bean.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setExcludeProperties(String...excludeProperties) {
+	public BeanFilterBuilder excludeProperties(String...excludeProperties) {
 		this.excludeProperties = excludeProperties;
 		return this;
 	}
@@ -121,7 +122,7 @@ public abstract class BeanFilterBuilder {
 	 * 		}
 	 * 	}
 	 *
-	 * 	JsonSerializer s = new JsonSerializer().addBeanFilters(AFilter.<jk>class</jk>);
+	 * 	JsonSerializer s = new JsonSerializerBuilder().beanFilters(AFilter.<jk>class</jk>).build();
 	 * 	A1 a1 = <jk>new</jk> A1();
 	 * 	String r = s.serialize(a1);
 	 * 	<jsm>assertEquals</jsm>(<js>"{f0:'f0'}"</js>, r);  <jc>// Note f1 is not serialized</jc>
@@ -133,7 +134,7 @@ public abstract class BeanFilterBuilder {
 	 * @param interfaceClass The interface class to use for this bean class.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setInterfaceClass(Class<?> interfaceClass) {
+	public BeanFilterBuilder interfaceClass(Class<?> interfaceClass) {
 		this.interfaceClass = interfaceClass;
 		return this;
 	}
@@ -164,7 +165,7 @@ public abstract class BeanFilterBuilder {
 	 * @param stopClass
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setStopClass(Class<?> stopClass) {
+	public BeanFilterBuilder stopClass(Class<?> stopClass) {
 		this.stopClass = stopClass;
 		return this;
 	}
@@ -175,7 +176,7 @@ public abstract class BeanFilterBuilder {
 	 * @param sortProperties
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setSortProperties(boolean sortProperties) {
+	public BeanFilterBuilder sortProperties(boolean sortProperties) {
 		this.sortProperties = sortProperties;
 		return this;
 	}
@@ -186,7 +187,7 @@ public abstract class BeanFilterBuilder {
 	 * @param propertyNamer The property namer instance.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder setPropertyNamer(PropertyNamer propertyNamer) {
+	public BeanFilterBuilder propertyNamer(PropertyNamer propertyNamer) {
 		this.propertyNamer = propertyNamer;
 		return this;
 	}
@@ -198,18 +199,29 @@ public abstract class BeanFilterBuilder {
 	 * @return This object (for method chaining).
 	 * @throws Exception Thrown from constructor method.
 	 */
-	public BeanFilterBuilder setPropertyNamer(Class<? extends PropertyNamer> c) throws Exception {
+	public BeanFilterBuilder propertyNamer(Class<? extends PropertyNamer> c) throws Exception {
 		this.propertyNamer = c.newInstance();
 		return this;
 	}
 
 	/**
-	 * Adds a class to this bean's bean dictionary.
+	 * Sets the contents of this bean's bean dictionary.
 	 *
-	 * @param c The class to add to this bean dictionary.
+	 * @param c The classes to set on this bean's bean dictionary.
 	 * @return This object (for method chaining).
 	 */
-	public BeanFilterBuilder addToBeanDictionary(Class<?>...c) {
+	public BeanFilterBuilder setBeanDictionary(Class<?>...c) {
+		beanDictionary = new ArrayList<Class<?>>(Arrays.asList(c));
+		return this;
+	}
+
+	/**
+	 * Adds classes to this bean's bean dictionary.
+	 *
+	 * @param c The classes to add to this bean's bean dictionary.
+	 * @return This object (for method chaining).
+	 */
+	public BeanFilterBuilder beanDictionary(Class<?>...c) {
 		if (beanDictionary == null)
 			beanDictionary = new ArrayList<Class<?>>(Arrays.asList(c));
 		else for (Class<?> cc : c)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
index 0ccafaf..70300c0 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/InterfaceBeanFilterBuilder.java
@@ -18,7 +18,7 @@ import org.apache.juneau.*;
  * Simple bean filter that simply identifies a class to be used as an interface
  * 	class for all child classes.
  * <p>
- * These objects are created when you pass in non-<code>BeanFilterBuilder</code> classes to {@link ContextFactory#addToProperty(String,Object)},
+ * These objects are created when you pass in non-<code>BeanFilterBuilder</code> classes to {@link PropertyStore#addToProperty(String,Object)},
  * 	and are equivalent to adding a <code><ja>@Bean</ja>(interfaceClass=Foo.<jk>class</jk>)</code> annotation on the <code>Foo</code> class.
  */
 public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
@@ -30,6 +30,6 @@ public class InterfaceBeanFilterBuilder extends BeanFilterBuilder {
 	 */
 	public InterfaceBeanFilterBuilder(Class<?> interfaceClass) {
 		super(interfaceClass);
-		setInterfaceClass(interfaceClass);
+		interfaceClass(interfaceClass);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
index 7c36e7b..477a37a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/PojoSwap.java
@@ -33,7 +33,7 @@ import org.apache.juneau.serializer.*;
  * Swaps MUST declare a public no-arg constructor so that the bean context can instantiate them.
  * <p>
  * 	<code>PojoSwaps</code> are associated with instances of {@link BeanContext BeanContexts} by passing the swap class to
- * 	the {@link CoreApi#addPojoSwaps(Class...)} method.<br>
+ * 	the {@link CoreObjectBuilder#pojoSwaps(Class...)} method.<br>
  * When associated with a bean context, fields of the specified type will automatically be converted when the
  * 	{@link BeanMap#get(Object)} or {@link BeanMap#put(String, Object)} methods are called.<br>
  * <p>

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/SurrogateSwap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/SurrogateSwap.java b/juneau-core/src/main/java/org/apache/juneau/transform/SurrogateSwap.java
index b8e4991..d6bdd39 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/SurrogateSwap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/SurrogateSwap.java
@@ -59,12 +59,12 @@ import org.apache.juneau.serializer.*;
  * 		can be instantiated by the parser before being converted into the normal class by the untransform method).
  * </ul>
  * <p>
- * Surrogate classes are associated with serializers and parsers using the {@link CoreApi#addPojoSwaps(Class...)} method.
+ * Surrogate classes are associated with serializers and parsers using the {@link CoreObjectBuilder#pojoSwaps(Class...)} method.
  * <p class='bcode'>
  * 	<ja>@Test</ja>
  * 	<jk>public void</jk> test() <jk>throws</jk> Exception {
- * 		JsonSerializer s = <jk>new</jk> JsonSerializer.Simple().addPojoSwaps(Surrogate.<jk>class</jk>);
- * 		JsonParser p = <jk>new</jk> JsonParser().addPojoSwaps(Surrogate.<jk>class</jk>);
+ * 		JsonSerializer s = <jk>new</jk> JsonSerializerBuilder().simple().pojoSwaps(Surrogate.<jk>class</jk>).build();
+ * 		JsonParser p = <jk>new</jk> JsonParserBuilder().pojoSwaps(Surrogate.<jk>class</jk>).build();
  * 		String r;
  * 		Normal n = Normal.<jsm>create</jsm>();
  *

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/transform/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/transform/package.html b/juneau-core/src/main/java/org/apache/juneau/transform/package.html
index e6e9f88..32f0413 100644
--- a/juneau-core/src/main/java/org/apache/juneau/transform/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/transform/package.html
@@ -92,11 +92,11 @@
 		Transforms are added to serializers and parsers in a variety of ways:
 	</p> 
 	<ul class='spaced-list'>
-		<li>{@link org.apache.juneau.serializer.Serializer#addBeanFilters(Class[])} / {@link org.apache.juneau.serializer.Serializer#addPojoSwaps(Class[])} - On serializers.
-		<li>{@link org.apache.juneau.serializer.SerializerGroup#addBeanFilters(Class[])} / {@link org.apache.juneau.serializer.SerializerGroup#addPojoSwaps(Class[])} - On groups of serializers.
-		<li>{@link org.apache.juneau.parser.Parser#addBeanFilters(Class[])} / {@link org.apache.juneau.parser.Parser#addPojoSwaps(Class[])} - On parsers.
-		<li>{@link org.apache.juneau.parser.ParserGroup#addBeanFilters(Class[])} / {@link org.apache.juneau.parser.ParserGroup#addPojoSwaps(Class[])} - On groups of parsers.
-		<li>{@link org.apache.juneau.rest.client.RestClient#addBeanFilters(Class[])} / {@link org.apache.juneau.rest.client.RestClient#addPojoSwaps(Class[])} - On the serializer and parser registered on a REST client.
+		<li>{@link org.apache.juneau.serializer.SerializerBuilder#beanFilters(Class[])} / {@link org.apache.juneau.serializer.SerializerBuilder#pojoSwaps(Class[])} - On serializers.
+		<li>{@link org.apache.juneau.serializer.SerializerGroupBuilder#beanFilters(Class[])} / {@link org.apache.juneau.serializer.SerializerGroupBuilder#pojoSwaps(Class[])} - On groups of serializers.
+		<li>{@link org.apache.juneau.parser.ParserBuilder#beanFilters(Class[])} / {@link org.apache.juneau.parser.ParserBuilder#pojoSwaps(Class[])} - On parsers.
+		<li>{@link org.apache.juneau.parser.ParserGroupBuilder#beanFilters(Class[])} / {@link org.apache.juneau.parser.ParserGroupBuilder#pojoSwaps(Class[])} - On groups of parsers.
+		<li>{@link org.apache.juneau.rest.client.RestClientBuilder#beanFilters(Class[])} / {@link org.apache.juneau.rest.client.RestClientBuilder#pojoSwaps(Class[])} - On the serializer and parser registered on a REST client.
 		<li>{@link org.apache.juneau.rest.annotation.RestResource#beanFilters() @RestResource.beanFilters()} / {@link org.apache.juneau.rest.annotation.RestResource#pojoSwaps() @RestResource.pojoSwaps()}- On all serializers and parsers defined on a REST servlet.
 		<li>{@link org.apache.juneau.rest.annotation.RestMethod#beanFilters() @RestMethod.beanFilters()} / {@link org.apache.juneau.rest.annotation.RestMethod#pojoSwaps() @RestMethod.pojoSwaps()} - On all serializers and parsers defined on a method in a REST servlet.
 		<li>{@link org.apache.juneau.rest.jaxrs.JuneauProvider#beanFilters() @JuneauProvider.beanFilters()} / {@link org.apache.juneau.rest.jaxrs.JuneauProvider#pojoSwaps() @JuneauProvider.pojoSwaps()} - On all serializers and parsers defined on a JAX-RS provider.
@@ -136,7 +136,7 @@
 		}
 	}
 	
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	Person p = getPerson();
 	String json = s.serialize(p);  <jc>// Prints "{age:45,name:'John Smith'}"</jc>
 		</p>
@@ -159,7 +159,7 @@
 		}
 	}
 	
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	Person p = getPerson();
 	String json = s.serialize(p);  <jc>// Prints "{age:45}"</jc>
 		</p>
@@ -192,12 +192,12 @@
 	}
 	
 	<jc>// Serialize to JSON</jc>
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	Person person = getPerson();
 	String json = s.serialize(p);  <jc>// Prints "{AGE:45,NAME:'John Smith'}"</jc>
 	
 	<jc>// Parse back into bean</jc>
-	ReaderParser p = <jk>new</jk> JsonParser().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	ReaderParser p = <jk>new</jk> JsonParserBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	person = p.parse(json, Person.class); <jc>// Read back into original object</jc>
 		</p>
 		<p>
@@ -250,7 +250,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Serialize to JSON</jc>
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	MyClass c = <jk>new</jk> MyClassBar();
 	String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
 		</p>	
@@ -273,14 +273,14 @@
 	}
 		</p>
 		<p>
-			Also, the <code>addBeanFilters(...)</code> methods will automatically interpret any non-<code>BeanFilter</code> classes
+			Also, the <code>*BeanFilters(...)</code> methods will automatically interpret any non-<code>BeanFilter</code> classes
 				passed in as meaning interface classes.  
 			So in the previous example, the <code>BeanFilter</code> class could have been avoided altogether by just 
 				passing in <code>MyClass.<jk>class</jk></code> to the serializer, like so:
 		</p>
 		<p class='bcode'>
 	<jc>// Serialize to JSON</jc>
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyClass.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyClass.<jk>class</jk>).build();
 		</p>
 		<p>
 			In fact, this is the shortcut used in the <code>RequestEchoResource</code> sample class:
@@ -388,11 +388,11 @@
 	}
 
 	<jc>// Create a new JSON serializer, associate our date swap with it, and serialize a sample bean.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build();
 	String json = serializer.serialize(<jk>new</jk> MyBean());	<jc>// == "{date:'2012-03-03T04:05:06-0500'}"</jc>
 	
 	<jc>// Create a JSON parser, associate our date swap with it, and reconstruct our bean (including the date).</jc>
-	ReaderParser parser = <jk>new</jk> JsonParser().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+	ReaderParser parser = <jk>new</jk> JsonParserBuilder().pojoSwaps(MyDateSwap.<jk>class</jk>).build();
 	MyBean bean = parser.parse(json, MyBean.<jk>class</jk>);
 	<jk>int</jk> day = bean.<jf>date</jf>.getDay(); 						<jc>// == 3</jc>
 		</p>
@@ -401,7 +401,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new bean context and add our swap.</jc>
-	BeanContext beanContext = <jk>new</jk> BeanContext().addPojoSwaps(MyDateSwap.<jk>class</jk>);
+	BeanContext beanContext = <jk>new</jk> BeanContext().pojoSwaps(MyDateSwap.<jk>class</jk>);
 
 	<jc>// Create a new bean.</jc>
 	MyBean myBean = <jk>new</jk> MyBean();
@@ -459,8 +459,8 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a JSON serializer and register the BASE64 encoding swap with it.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(ByteArrayBase64Swap.<jk>class</jk>);
-	ReaderParser parser = <jk>new</jk> JsonParser().addPojoSwaps(ByteArrayBase64Swap.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(ByteArrayBase64Swap.<jk>class</jk>).build();
+	ReaderParser parser = <jk>new</jk> JsonParserBuilder().pojoSwaps(ByteArrayBase64Swap.<jk>class</jk>).build();
 	
 	<jk>byte</jk>[] a1 = {1,2,3};
 	String s1 = serializer.serialize(a1);		<jc>// Produces "'AQID'"</jc>
@@ -526,7 +526,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a JSON serializer that can serialize Iterators.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(IteratorSwap.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(IteratorSwap.<jk>class</jk>).build();
 	
 	<jc>// Construct an iterator we want to serialize.</jc>
 	Iterator iterator = <jk>new</jk> ObjectList(1,2,3).iterator();
@@ -535,7 +535,7 @@
 	String s = serializer.serialize(iterator);		<jc>// Produces "[1,2,3]"</jc>
 	
 	<jc>// Try to parse it.</jc>
-	ReaderParser parser = <jk>new</jk> JsonParser().addPojoSwaps(IteratorSwap.<jk>class</jk>);
+	ReaderParser parser = <jk>new</jk> JsonParserBuilder().pojoSwaps(IteratorSwap.<jk>class</jk>).build();
 	iterator = parser.parse(s, Iterator.<jk>class</jk>);		<jc>// Throws ParseException!!!</jc>
 		</p>
 	</div>
@@ -579,7 +579,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Serialize to JSON</jc>
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyBeanFilter.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyBeanFilter.<jk>class</jk>).build();
 	MyClass c = <jk>new</jk> MyClassBar();
 	String json = s.serialize(p);  <jc>// Prints "{foo:'foo'}"</jc>
 		</p>	
@@ -602,12 +602,12 @@
 	}
 		</p>
 		<p>
-			Also, the <code>addBeanFilters()</code> methods will automatically interpret any non-<code>BeanFilter</code> classes passed in as meaning interface classes. 
+			Also, the <code>beanFilters()</code> methods will automatically interpret any non-<code>BeanFilter</code> classes passed in as meaning interface classes. 
 			So in the previous example, the <code>BeanFilter</code> class could have been avoided altogether by just passing in <code>MyClass.<jk>class</jk></code> to the serializer, like so:
 		</p>
 		<p class='bcode'>
 	<jc>// Serialize to JSON</jc>
-	WriterSerializer s = <jk>new</jk> JsonSerializer().addBeanFilters(MyClass.<jk>class</jk>);
+	WriterSerializer s = <jk>new</jk> JsonSerializerBuilder().beanFilters(MyClass.<jk>class</jk>).build();
 		</p>
 	</div>
 
@@ -661,7 +661,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a JSON serializer that can serialize Iterators.</jc>
-	Serializer serializer = <jk>new</jk> JsonSerializer().addPojoSwaps(MySerializableSurrogate.<jk>class</jk>);
+	Serializer serializer = <jk>new</jk> JsonSerializerBuilder().pojoSwaps(MySerializableSurrogate.<jk>class</jk>).build();
 		</p>
 		<p>
 			When the serializer encounters the non-serializable class, it will serialize an instance of the surrogate instead.


[33/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index c856512..4de1963 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -14,7 +14,6 @@ package org.apache.juneau.jena;
 
 import static org.apache.juneau.jena.Constants.*;
 import static org.apache.juneau.jena.RdfCommonContext.*;
-import static org.apache.juneau.jena.RdfSerializerContext.*;
 
 import java.lang.reflect.*;
 import java.util.*;
@@ -22,11 +21,9 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.jena.annotation.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.transform.*;
 import org.apache.juneau.xml.*;
-import org.apache.juneau.xml.annotation.*;
 
 import com.hp.hpl.jena.rdf.model.*;
 
@@ -58,67 +55,128 @@ import com.hp.hpl.jena.rdf.model.*;
 public class RdfSerializer extends WriterSerializer {
 
 	/** Default RDF/XML serializer, all default settings.*/
-	public static final RdfSerializer DEFAULT_XML = new RdfSerializer.Xml().lock();
+	public static final RdfSerializer DEFAULT_XML = new Xml(PropertyStore.create());
 
 	/** Default Abbreviated RDF/XML serializer, all default settings.*/
-	public static final RdfSerializer DEFAULT_XMLABBREV = new RdfSerializer.XmlAbbrev().lock();
+	public static final RdfSerializer DEFAULT_XMLABBREV = new XmlAbbrev(PropertyStore.create());
 
 	/** Default Turtle serializer, all default settings.*/
-	public static final RdfSerializer DEFAULT_TURTLE = new RdfSerializer.Turtle().lock();
+	public static final RdfSerializer DEFAULT_TURTLE = new Turtle(PropertyStore.create());
 
 	/** Default N-Triple serializer, all default settings.*/
-	public static final RdfSerializer DEFAULT_NTRIPLE = new RdfSerializer.NTriple().lock();
+	public static final RdfSerializer DEFAULT_NTRIPLE = new NTriple(PropertyStore.create());
 
 	/** Default N3 serializer, all default settings.*/
-	public static final RdfSerializer DEFAULT_N3 = new RdfSerializer.N3().lock();
+	public static final RdfSerializer DEFAULT_N3 = new N3(PropertyStore.create());
 
 
 	/** Produces RDF/XML output */
 	@Produces("text/xml+rdf")
 	public static class Xml extends RdfSerializer {
-		/** Constructor */
-		public Xml() {
-			setLanguage(LANG_RDF_XML);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Xml(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML);
 		}
 	}
 
 	/** Produces Abbreviated RDF/XML output */
 	@Produces(value="text/xml+rdf+abbrev", contentType="text/xml+rdf")
 	public static class XmlAbbrev extends RdfSerializer {
-		/** Constructor */
-		public XmlAbbrev() {
-			setLanguage(LANG_RDF_XML_ABBREV);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public XmlAbbrev(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_RDF_XML_ABBREV);
 		}
 	}
 
 	/** Produces N-Triple output */
 	@Produces("text/n-triple")
 	public static class NTriple extends RdfSerializer {
-		/** Constructor */
-		public NTriple() {
-			setLanguage(LANG_NTRIPLE);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public NTriple(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_NTRIPLE);
 		}
 	}
 
 	/** Produces Turtle output */
 	@Produces("text/turtle")
 	public static class Turtle extends RdfSerializer {
-		/** Constructor */
-		public Turtle() {
-			setLanguage(LANG_TURTLE);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Turtle(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_TURTLE);
 		}
 	}
 
 	/** Produces N3 output */
 	@Produces("text/n3")
 	public static class N3 extends RdfSerializer {
-		/** Constructor */
-		public N3() {
-			setLanguage(LANG_N3);
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public N3(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(RDF_language, LANG_N3);
 		}
 	}
 
 
+	private final RdfSerializerContext ctx;
+	
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public RdfSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(RdfSerializerContext.class);
+	}
+
+	@Override /* CoreObject */
+	public RdfSerializerBuilder builder() {
+		return new RdfSerializerBuilder(propertyStore);
+	}
+
 	@Override /* Serializer */
 	protected void doSerialize(SerializerSession session, Object o) throws Exception {
 
@@ -392,819 +450,6 @@ public class RdfSerializer extends WriterSerializer {
 
 	@Override /* Serializer */
 	public RdfSerializerSession createSession(Object output, ObjectMap op, Method javaMethod, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new RdfSerializerSession(getContext(RdfSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
-	}
-
-	
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  RDF language.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.language"</js>
-	 * 	<li><b>Data type:</b> <code>String</code>
-	 * 	<li><b>Default:</b> <js>"RDF/XML-ABBREV"</js>
-	 * </ul>
-	 * <p>
-	 * Can be any of the following:
-	 * <ul class='spaced-list'>
-	 * 	<li><js>"RDF/XML"</js>
-	 * 	<li><js>"RDF/XML-ABBREV"</js>
-	 * 	<li><js>"N-TRIPLE"</js>
-	 * 	<li><js>"N3"</js> - General name for the N3 writer.
-	 * 		Will make a decision on exactly which writer to use (pretty writer, plain writer or simple writer) when created.
-	 * 		Default is the pretty writer but can be overridden with system property	<code>com.hp.hpl.jena.n3.N3JenaWriter.writer</code>.
-	 * 	<li><js>"N3-PP"</js> - Name of the N3 pretty writer.
-	 * 		The pretty writer uses a frame-like layout, with prefixing, clustering like properties and embedding one-referenced bNodes.
-	 * 	<li><js>"N3-PLAIN"</js> - Name of the N3 plain writer.
-	 * 		The plain writer writes records by subject.
-	 * 	<li><js>"N3-TRIPLES"</js> - Name of the N3 triples writer.
-	 * 		This writer writes one line per statement, like N-Triples, but does N3-style prefixing.
-	 * 	<li><js>"TURTLE"</js> -  Turtle writer.
-	 * 		http://www.dajobe.org/2004/01/turtle/
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_language</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfCommonContext#RDF_language
-	 */
-	public RdfSerializer setLanguage(String value) throws LockedException {
-		return setProperty(RDF_language, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XML namespace for Juneau properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.juneauNs"</js>
-	 * 	<li><b>Data type:</b> {@link Namespace}
-	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_juneauNs</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_juneauNs
-	 */
-	public RdfSerializer setJuneauNs(Namespace value) throws LockedException {
-		return setProperty(RDF_juneauNs, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default XML namespace for bean properties.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.juneauBpNs"</js>
-	 * 	<li><b>Data type:</b> {@link Namespace}
-	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_juneauBpNs</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_juneauBpNs
-	 */
-	public RdfSerializer setJuneauBpNs(Namespace value) throws LockedException {
-		return setProperty(RDF_juneauBpNs, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Reuse XML namespaces when RDF namespaces not specified.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.useXmlNamespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * When specified, namespaces defined using {@link XmlNs} and {@link Xml} will be inherited by the RDF serializers.
-	 * Otherwise, namespaces will be defined using {@link RdfNs} and {@link Rdf}.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_useXmlNamespaces</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see SerializerContext#SERIALIZER_sortMaps
-	 */
-	public RdfSerializer setUseXmlNamespaces(boolean value) throws LockedException {
-		return setProperty(RDF_useXmlNamespaces, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add XSI data types to non-<code>String</code> literals.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RdfSerializer.addLiteralTypes"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_addLiteralTypes</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_addLiteralTypes
-	 */
-	public RdfSerializer setAddLiteralTypes(boolean value) throws LockedException {
-		return setProperty(RDF_addLiteralTypes, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Add RDF root identifier property to root node.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RdfSerializer.addRootProperty"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * When enabled an RDF property <code>http://www.apache.org/juneau/root</code> is added with a value of <js>"true"</js>
-	 * 	to identify the root node in the graph.
-	 * This helps locate the root node during parsing.
-	 * <p>
-	 * If disabled, the parser has to search through the model to find any resources without
-	 * 	incoming predicates to identify root notes, which can introduce a considerable performance
-	 * 	degradation.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_addRootProperty</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_addRootProperty
-	 */
-	public RdfSerializer setAddRootProperty(boolean value) throws LockedException {
-		return setProperty(RDF_addRootProperty, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Auto-detect namespace usage.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RdfSerializer.autoDetectNamespaces"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>true</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Detect namespace usage before serialization.
-	 * <p>
-	 * If enabled, then the data structure will first be crawled looking for
-	 * namespaces that will be encountered before the root element is
-	 * serialized.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_autoDetectNamespaces</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_autoDetectNamespaces
-	 */
-	public RdfSerializer setAutoDetectNamespaces(boolean value) throws LockedException {
-		return setProperty(RDF_autoDetectNamespaces, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Default namespaces.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"RdfSerializer.namespaces.list"</js>
-	 * 	<li><b>Data type:</b> <code>List&lt;{@link Namespace}&gt;</code>
-	 * 	<li><b>Default:</b> empty list
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * The default list of namespaces associated with this serializer.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_namespaces</jsf>, values)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param values The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfSerializerContext#RDF_namespaces
-	 */
-	public RdfSerializer setNamespaces(Namespace...values) throws LockedException {
-		return setProperty(RDF_namespaces, values);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  RDF format for representing collections and arrays.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.collectionFormat"</js>
-	 * 	<li><b>Data type:</b> <code>RdfCollectionFormat</code>
-	 * 	<li><b>Default:</b> <js>"DEFAULT"</js>
-	 * </ul>
-	 * <p>
-	 * Possible values:
-	 * <ul class='spaced-list'>
-	 * 	<li><js>"DEFAULT"</js> - Default format.  The default is an RDF Sequence container.
-	 * 	<li><js>"SEQ"</js> - RDF Sequence container.
-	 * 	<li><js>"BAG"</js> - RDF Bag container.
-	 * 	<li><js>"LIST"</js> - RDF List container.
-	 * 	<li><js>"MULTI_VALUED"</js> - Multi-valued properties.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the order of the elements in the collection will get lost.
-	 * </ul>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_collectionFormat</jsf>, value)</code>.
-	 * 	<li>This introduces a slight performance penalty.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfCommonContext#RDF_collectionFormat
-	 */
-	public RdfSerializer setCollectionFormat(RdfCollectionFormat value) throws LockedException {
-		return setProperty(RDF_collectionFormat, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Collections should be serialized and parsed as loose collections.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"Rdf.looseCollections"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * </ul>
-	 * <p>
-	 * When specified, collections of resources are handled as loose collections of resources in RDF instead of
-	 * resources that are children of an RDF collection (e.g. Sequence, Bag).
-	 * <p>
-	 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of
-	 * losslessly representing POJO models, since the tree structure of these POJO models are lost
-	 * when serialized as loose collections.
-	 * <p>
-	 * This setting is typically only useful if the beans being parsed into do not have a bean property
-	 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	WriterSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setLooseCollections(<jk>true</jk>);
-	 * 	ReaderParser p = <jk>new</jk> RdfParser.Xml().setLooseCollections(<jk>true</jk>);
-	 *
-	 * 	List&lt;MyBean&gt; l = createListOfMyBeans();
-	 *
-	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
-	 * 	String rdfXml = s.serialize(l);
-	 *
-	 * 	<jc>// Parse back into a Java collection</jc>
-	 * 	l = p.parse(rdfXml, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
-	 *
-	 * 	MyBean[] b = createArrayOfMyBeans();
-	 *
-	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
-	 * 	String rdfXml = s.serialize(b);
-	 *
-	 * 	<jc>// Parse back into a bean array</jc>
-	 * 	b = p.parse(rdfXml, MyBean[].<jk>class</jk>);
-	 * </p>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>RDF_looseCollections</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see RdfCommonContext#RDF_looseCollections
-	 */
-	public RdfSerializer setLooseCollections(boolean value) throws LockedException {
-		return setProperty(RDF_looseCollections, value);
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setMaxDepth(int value) throws LockedException {
-		super.setMaxDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setInitialDepth(int value) throws LockedException {
-		super.setInitialDepth(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setDetectRecursions(boolean value) throws LockedException {
-		super.setDetectRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setIgnoreRecursions(boolean value) throws LockedException {
-		super.setIgnoreRecursions(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setUseWhitespace(boolean value) throws LockedException {
-		super.setUseWhitespace(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setAddBeanTypeProperties(boolean value) throws LockedException {
-		super.setAddBeanTypeProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setQuoteChar(char value) throws LockedException {
-		super.setQuoteChar(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setTrimNullProperties(boolean value) throws LockedException {
-		super.setTrimNullProperties(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setTrimEmptyCollections(boolean value) throws LockedException {
-		super.setTrimEmptyCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setTrimEmptyMaps(boolean value) throws LockedException {
-		super.setTrimEmptyMaps(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setRelativeUriBase(String value) throws LockedException {
-		super.setRelativeUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setAbsolutePathUriBase(String value) throws LockedException {
-		super.setAbsolutePathUriBase(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setSortCollections(boolean value) throws LockedException {
-		super.setSortCollections(value);
-		return this;
-	}
-
-	@Override /* Serializer */
-	public RdfSerializer setSortMaps(boolean value) throws LockedException {
-		super.setSortMaps(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public RdfSerializer removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-	
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public RdfSerializer setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public RdfSerializer lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public RdfSerializer clone() {
-		try {
-			return (RdfSerializer)super.clone();
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen
-		}
+		return new RdfSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
new file mode 100644
index 0000000..6b150ad
--- /dev/null
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerBuilder.java
@@ -0,0 +1,890 @@
+// ***************************************************************************************************************************
+// * 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.jena;
+
+import static org.apache.juneau.jena.RdfCommonContext.*;
+import static org.apache.juneau.jena.RdfSerializerContext.*;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.jena.annotation.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.xml.*;
+import org.apache.juneau.xml.annotation.*;
+
+/**
+ * Builder class for building instances of RDF serializers.
+ */
+public class RdfSerializerBuilder extends SerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public RdfSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public RdfSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializer build() {
+		return new RdfSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  RDF language.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.language"</js>
+	 * 	<li><b>Data type:</b> <code>String</code>
+	 * 	<li><b>Default:</b> <js>"RDF/XML-ABBREV"</js>
+	 * </ul>
+	 * <p>
+	 * Can be any of the following:
+	 * <ul class='spaced-list'>
+	 * 	<li><js>"RDF/XML"</js>
+	 * 	<li><js>"RDF/XML-ABBREV"</js>
+	 * 	<li><js>"N-TRIPLE"</js>
+	 * 	<li><js>"N3"</js> - General name for the N3 writer.
+	 * 		Will make a decision on exactly which writer to use (pretty writer, plain writer or simple writer) when created.
+	 * 		Default is the pretty writer but can be overridden with system property	<code>com.hp.hpl.jena.n3.N3JenaWriter.writer</code>.
+	 * 	<li><js>"N3-PP"</js> - Name of the N3 pretty writer.
+	 * 		The pretty writer uses a frame-like layout, with prefixing, clustering like properties and embedding one-referenced bNodes.
+	 * 	<li><js>"N3-PLAIN"</js> - Name of the N3 plain writer.
+	 * 		The plain writer writes records by subject.
+	 * 	<li><js>"N3-TRIPLES"</js> - Name of the N3 triples writer.
+	 * 		This writer writes one line per statement, like N-Triples, but does N3-style prefixing.
+	 * 	<li><js>"TURTLE"</js> -  Turtle writer.
+	 * 		http://www.dajobe.org/2004/01/turtle/
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_language</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfCommonContext#RDF_language
+	 */
+	public RdfSerializerBuilder language(String value) {
+		return property(RDF_language, value);
+	}
+	
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfSerializerBuilder xml() {
+		return language(Constants.LANG_RDF_XML);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_RDF_XML_ABBREV</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfSerializerBuilder xmlabbrev() {
+		return language(Constants.LANG_RDF_XML_ABBREV);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_NTRIPLE</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfSerializerBuilder ntriple() {
+		return language(Constants.LANG_NTRIPLE);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_N3</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfSerializerBuilder n3() {
+		return language(Constants.LANG_N3);
+	}
+
+	/**
+	 * Shortcut for calling <code>language(<jsf>LANG_TURTLE</jsf>)</code>
+	 * @return This object (for method chaining).
+	 */
+	public RdfSerializerBuilder turtle() {
+		return language(Constants.LANG_TURTLE);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XML namespace for Juneau properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.juneauNs"</js>
+	 * 	<li><b>Data type:</b> {@link Namespace}
+	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneau/'</js>}</code>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_juneauNs</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_juneauNs
+	 */
+	public RdfSerializerBuilder juneauNs(Namespace value) {
+		return property(RDF_juneauNs, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default XML namespace for bean properties.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.juneauBpNs"</js>
+	 * 	<li><b>Data type:</b> {@link Namespace}
+	 * 	<li><b>Default:</b> <code>{j:<js>'http://www.apache.org/juneaubp/'</js>}</code>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_juneauBpNs</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_juneauBpNs
+	 */
+	public RdfSerializerBuilder juneauBpNs(Namespace value) {
+		return property(RDF_juneauBpNs, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Reuse XML namespaces when RDF namespaces not specified.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.useXmlNamespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * When specified, namespaces defined using {@link XmlNs} and {@link Xml} will be inherited by the RDF serializers.
+	 * Otherwise, namespaces will be defined using {@link RdfNs} and {@link Rdf}.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_useXmlNamespaces</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see SerializerContext#SERIALIZER_sortMaps
+	 */
+	public RdfSerializerBuilder useXmlNamespaces(boolean value) {
+		return property(RDF_useXmlNamespaces, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add XSI data types to non-<code>String</code> literals.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RdfSerializer.addLiteralTypes"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_addLiteralTypes</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_addLiteralTypes
+	 */
+	public RdfSerializerBuilder addLiteralTypes(boolean value) {
+		return property(RDF_addLiteralTypes, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Add RDF root identifier property to root node.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RdfSerializer.addRootProperty"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * When enabled an RDF property <code>http://www.apache.org/juneau/root</code> is added with a value of <js>"true"</js>
+	 * 	to identify the root node in the graph.
+	 * This helps locate the root node during parsing.
+	 * <p>
+	 * If disabled, the parser has to search through the model to find any resources without
+	 * 	incoming predicates to identify root notes, which can introduce a considerable performance
+	 * 	degradation.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_addRootProperty</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_addRootProperty
+	 */
+	public RdfSerializerBuilder addRootProperty(boolean value) {
+		return property(RDF_addRootProperty, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Auto-detect namespace usage.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RdfSerializer.autoDetectNamespaces"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>true</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Detect namespace usage before serialization.
+	 * <p>
+	 * If enabled, then the data structure will first be crawled looking for
+	 * namespaces that will be encountered before the root element is
+	 * serialized.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_autoDetectNamespaces</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_autoDetectNamespaces
+	 */
+	public RdfSerializerBuilder autoDetectNamespaces(boolean value) {
+		return property(RDF_autoDetectNamespaces, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Default namespaces.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"RdfSerializer.namespaces.list"</js>
+	 * 	<li><b>Data type:</b> <code>List&lt;{@link Namespace}&gt;</code>
+	 * 	<li><b>Default:</b> empty list
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * The default list of namespaces associated with this serializer.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_namespaces</jsf>, values)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param values The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfSerializerContext#RDF_namespaces
+	 */
+	public RdfSerializerBuilder namespaces(Namespace...values) {
+		return property(RDF_namespaces, values);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  RDF format for representing collections and arrays.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.collectionFormat"</js>
+	 * 	<li><b>Data type:</b> <code>RdfCollectionFormat</code>
+	 * 	<li><b>Default:</b> <js>"DEFAULT"</js>
+	 * </ul>
+	 * <p>
+	 * Possible values:
+	 * <ul class='spaced-list'>
+	 * 	<li><js>"DEFAULT"</js> - Default format.  The default is an RDF Sequence container.
+	 * 	<li><js>"SEQ"</js> - RDF Sequence container.
+	 * 	<li><js>"BAG"</js> - RDF Bag container.
+	 * 	<li><js>"LIST"</js> - RDF List container.
+	 * 	<li><js>"MULTI_VALUED"</js> - Multi-valued properties.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>If you use <js>"BAG"</js> or <js>"MULTI_VALUED"</js>, the order of the elements in the collection will get lost.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_collectionFormat</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfCommonContext#RDF_collectionFormat
+	 */
+	public RdfSerializerBuilder collectionFormat(RdfCollectionFormat value) {
+		return property(RDF_collectionFormat, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Collections should be serialized and parsed as loose collections.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"Rdf.looseCollections"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * </ul>
+	 * <p>
+	 * When specified, collections of resources are handled as loose collections of resources in RDF instead of
+	 * resources that are children of an RDF collection (e.g. Sequence, Bag).
+	 * <p>
+	 * Note that this setting is specialized for RDF syntax, and is incompatible with the concept of
+	 * losslessly representing POJO models, since the tree structure of these POJO models are lost
+	 * when serialized as loose collections.
+	 * <p>
+	 * This setting is typically only useful if the beans being parsed into do not have a bean property
+	 * annotated with {@link Rdf#beanUri @Rdf(beanUri=true)}.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	WriterSerializer s = <jk>new</jk> RdfSerializerBuilder().xmlabbrev().looseCollections(<jk>true</jk>).build();
+	 * 	ReaderParser p = <jk>new</jk> RdfParserBuilder().xml().looseCollections(<jk>true</jk>).build();
+	 *
+	 * 	List&lt;MyBean&gt; l = createListOfMyBeans();
+	 *
+	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
+	 * 	String rdfXml = s.serialize(l);
+	 *
+	 * 	<jc>// Parse back into a Java collection</jc>
+	 * 	l = p.parse(rdfXml, LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+	 *
+	 * 	MyBean[] b = createArrayOfMyBeans();
+	 *
+	 * 	<jc>// Serialize to RDF/XML as loose resources</jc>
+	 * 	String rdfXml = s.serialize(b);
+	 *
+	 * 	<jc>// Parse back into a bean array</jc>
+	 * 	b = p.parse(rdfXml, MyBean[].<jk>class</jk>);
+	 * </p>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>RDF_looseCollections</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see RdfCommonContext#RDF_looseCollections
+	 */
+	public RdfSerializerBuilder looseCollections(boolean value) {
+		return property(RDF_looseCollections, value);
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+	
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public RdfSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> RdfSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public RdfSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
index 8c91057..5c3b680 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerContext.java
@@ -21,10 +21,10 @@ import org.apache.juneau.xml.*;
 /**
  * Configurable properties on the {@link RdfSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h6 class='topic' id='ConfigProperties'>Configurable properties inherited by the RDF serializers</h6>
  * <ul class='javahierarchy'>
@@ -140,23 +140,23 @@ public final class RdfSerializerContext extends SerializerContext implements Rdf
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public RdfSerializerContext(ContextFactory cf) {
-		super(cf);
-		addLiteralTypes = cf.getProperty(RDF_addLiteralTypes, boolean.class, false);
-		addRootProperty = cf.getProperty(RDF_addRootProperty, boolean.class, false);
-		useXmlNamespaces = cf.getProperty(RDF_useXmlNamespaces, boolean.class, true);
-		looseCollections = cf.getProperty(RDF_looseCollections, boolean.class, false);
-		autoDetectNamespaces = cf.getProperty(RDF_autoDetectNamespaces, boolean.class, true);
-		rdfLanguage = cf.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
-		juneauNs = cf.getProperty(RDF_juneauNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneau/"));
-		juneauBpNs = cf.getProperty(RDF_juneauBpNs, Namespace.class, new Namespace("jp", "http://www.apache.org/juneaubp/"));
-		collectionFormat = cf.getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
-		namespaces = cf.getProperty(RDF_namespaces, Namespace[].class, new Namespace[0]);
-		addBeanTypeProperties = cf.getProperty(RDF_addBeanTypeProperties, boolean.class, cf.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
+	public RdfSerializerContext(PropertyStore ps) {
+		super(ps);
+		addLiteralTypes = ps.getProperty(RDF_addLiteralTypes, boolean.class, false);
+		addRootProperty = ps.getProperty(RDF_addRootProperty, boolean.class, false);
+		useXmlNamespaces = ps.getProperty(RDF_useXmlNamespaces, boolean.class, true);
+		looseCollections = ps.getProperty(RDF_looseCollections, boolean.class, false);
+		autoDetectNamespaces = ps.getProperty(RDF_autoDetectNamespaces, boolean.class, true);
+		rdfLanguage = ps.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
+		juneauNs = ps.getProperty(RDF_juneauNs, Namespace.class, new Namespace("j", "http://www.apache.org/juneau/"));
+		juneauBpNs = ps.getProperty(RDF_juneauBpNs, Namespace.class, new Namespace("jp", "http://www.apache.org/juneaubp/"));
+		collectionFormat = ps.getProperty(RDF_collectionFormat, RdfCollectionFormat.class, RdfCollectionFormat.DEFAULT);
+		namespaces = ps.getProperty(RDF_namespaces, Namespace[].class, new Namespace[0]);
+		addBeanTypeProperties = ps.getProperty(RDF_addBeanTypeProperties, boolean.class, ps.getProperty(SERIALIZER_addBeanTypeProperties, boolean.class, true));
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
index c44951a..b2e63d9 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/RdfSerializerSession.java
@@ -57,7 +57,7 @@ public final class RdfSerializerSession extends SerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
----------------------------------------------------------------------
diff --git a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
index d5b446d..c29250c 100644
--- a/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
+++ b/juneau-core-rdf/src/main/java/org/apache/juneau/jena/package.html
@@ -238,7 +238,7 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder().xmlabbrev().property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3).build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>);
@@ -251,7 +251,7 @@
 	</p>
 	<p class='bcode'>
 	<jc>// Create a new serializer with readable output by cloning an existing serializer.</jc>
-	RdfSerializer s = RdfSerializer.<jsf>DEFAULT_XMLABBREV</jsf>.clone().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
+	RdfSerializer s = RdfSerializer.<jsf>DEFAULT_XMLABBREV</jsf>.builder().property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3).build();
 	</p>
 	<p>
 		This code produces the following output:
@@ -344,10 +344,12 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer, but manually specify the namespaces.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3)
-		.setProperty(XmlSerializerContext.<jsf>XML_autoDetectNamespaces</jsf>, <jk>false</jk>)
-		.setProperty(XmlSerializerContext.<jsf>XML_namespaces</jsf>, <js>"{per:'http://www.apache.org/person/'}"</js>);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3)
+		.autoDetectNamespaces(<jk>false</jk>)
+		.namespaces(<js>"{per:'http://www.apache.org/person/'}"</js>)
+		.build();
 	</p>
 		<p>
 			This code change will produce the same output as before, but will perform slightly better since it doesn't have to crawl the POJO tree before serializing the result.
@@ -440,10 +442,12 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
-		.setProperty(SerializerContext.<jsf>SERIALIZER_relativeUriBase</jsf>, <js>"http://myhost/sample"</js>);
-		.setProperty(SerializerContext.<jsf>SERIALIZER_absolutePathUriBase</jsf>, <js>"http://myhost"</js>);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
+		.relativeUriBase(<js>"http://myhost/sample"</js>);
+		.absolutePathUriBase(<js>"http://myhost"</js>)
+		.build();
 		
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"person/1"</js>, <js>"/"</js>);
@@ -559,7 +563,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer (revert back to namespace autodetection).</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev().setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder().xmlabbrev().property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3).build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
@@ -635,9 +639,11 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3),
-		.setProperty(RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, <jk>true</jk>);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3),
+		.addRootProperty(<jk>true</jk>)
+		.build();
 		</p>	
 		<p>
 			Now when we rerun the sample code, we'll see the added <code>root</code> attribute on the root resource.
@@ -689,9 +695,11 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer (revert back to namespace autodetection).</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3),
-		.setProperty(RdfSerializerContext.<jsf>RDF_addLiteralTypes</jsf>, <jk>true</jk>);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3),
+		.addLiteralTypes(<jk>true</jk>)
+		.build();
 		</p>	
 		<p>
 			Now when we rerun the sample code, we'll see the added <code>root</code> attribute on the root resource.
@@ -809,9 +817,11 @@
 	</p>
 		<p class='bcode'>
 	<jc>// Create a new serializer with readable output.</jc>
-	RdfSerializer s = <jk>new</jk> RdfSerializer.XmlAbbrev()
-		.setProperty(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3)
-		.setProperty(RdfSerializerContext.<jsf>RDF_addRootProperty</jsf>, <jk>true</jk>);
+	RdfSerializer s = <jk>new</jk> RdfSerializerBuilder()
+		.xmlabbrev()
+		.property(RdfProperties.<jsf>RDF_rdfxml_tab</jsf>, 3)
+		.addRootProperty(<jk>true</jk>)
+		.build();
 
 	<jc>// Create our bean.</jc>
 	Person p = <jk>new</jk> Person(1, <js>"John Smith"</js>, <js>"http://sample/addressBook/person/1"</js>, <js>"http://sample/addressBook"</js>, <js>"Aug 12, 1946"</js>);
@@ -1361,7 +1371,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Create a client to handle RDF/XML requests and responses.</jc>
-	RestClient client = <jk>new</jk> RestClient(RdfSerializer.XmlAbbrev.<jk>class</jk>, RdfParser.Xml.<jk>class</jk>);
+	RestClient client = <jk>new</jk> RestClientBuilder(RdfSerializer.XmlAbbrev.<jk>class</jk>, RdfParser.Xml.<jk>class</jk>).build();
 		</p>
 		<p>
 			The client handles all content negotiation based on the registered serializers and parsers.

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
index 3757598..b55b98e 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanConfigTest.java
@@ -457,7 +457,7 @@ public class BeanConfigTest {
 	//====================================================================================================
 	@Test
 	public void testProxyHandler() throws Exception {
-		BeanSession session = ContextFactory.create().getBeanContext().createSession();
+		BeanSession session = PropertyStore.create().getBeanContext().createSession();
 
 		A f1 = (A) Proxy.newProxyInstance(this.getClass()
 				.getClassLoader(), new Class[] { A.class },
@@ -564,153 +564,153 @@ public class BeanConfigTest {
 	//====================================================================================================
 	@Test
 	public void testClassMetaCaching() throws Exception {
-		Parser p1, p2;
+		ParserBuilder p1, p2;
 
-		p1 = new JsonParser();
-		p2 = new JsonParser();
+		p1 = new JsonParserBuilder();
+		p2 = new JsonParserBuilder();
 		assertSameCache(p1, p2);
 
-		p1.setBeansRequireDefaultConstructor(true);
+		p1.beansRequireDefaultConstructor(true);
 		assertDifferentCache(p1, p2);
-		p2.setBeansRequireDefaultConstructor(true);
+		p2.beansRequireDefaultConstructor(true);
 		assertSameCache(p1, p2);
 
-		p1.setBeansRequireSerializable(true);
+		p1.beansRequireSerializable(true);
 		assertDifferentCache(p1, p2);
-		p2.setBeansRequireSerializable(true);
+		p2.beansRequireSerializable(true);
 		assertSameCache(p1, p2);
 
-		p1.setBeansRequireSettersForGetters(true);
+		p1.beansRequireSettersForGetters(true);
 		assertDifferentCache(p1, p2);
-		p2.setBeansRequireSettersForGetters(true);
+		p2.beansRequireSettersForGetters(true);
 		assertSameCache(p1, p2);
 
-		p1.setBeansRequireSomeProperties(false);
+		p1.beansRequireSomeProperties(false);
 		assertDifferentCache(p1, p2);
-		p2.setBeansRequireSomeProperties(false);
+		p2.beansRequireSomeProperties(false);
 		assertSameCache(p1, p2);
 
-		p1.setBeanMapPutReturnsOldValue(true);
+		p1.beanMapPutReturnsOldValue(true);
 		assertDifferentCache(p1, p2);
-		p2.setBeanMapPutReturnsOldValue(true);
+		p2.beanMapPutReturnsOldValue(true);
 		assertSameCache(p1, p2);
 
-		p1.setBeanConstructorVisibility(Visibility.DEFAULT);
+		p1.beanConstructorVisibility(Visibility.DEFAULT);
 		assertDifferentCache(p1, p2);
-		p2.setBeanConstructorVisibility(Visibility.DEFAULT);
+		p2.beanConstructorVisibility(Visibility.DEFAULT);
 		assertSameCache(p1, p2);
-		p1.setBeanConstructorVisibility(Visibility.NONE);
+		p1.beanConstructorVisibility(Visibility.NONE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanConstructorVisibility(Visibility.NONE);
+		p2.beanConstructorVisibility(Visibility.NONE);
 		assertSameCache(p1, p2);
-		p1.setBeanConstructorVisibility(Visibility.PRIVATE);
+		p1.beanConstructorVisibility(Visibility.PRIVATE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanConstructorVisibility(Visibility.PRIVATE);
+		p2.beanConstructorVisibility(Visibility.PRIVATE);
 		assertSameCache(p1, p2);
-		p1.setBeanConstructorVisibility(Visibility.PROTECTED);
+		p1.beanConstructorVisibility(Visibility.PROTECTED);
 		assertDifferentCache(p1, p2);
-		p2.setBeanConstructorVisibility(Visibility.PROTECTED);
+		p2.beanConstructorVisibility(Visibility.PROTECTED);
 		assertSameCache(p1, p2);
 
-		p1.setBeanClassVisibility(Visibility.DEFAULT);
+		p1.beanClassVisibility(Visibility.DEFAULT);
 		assertDifferentCache(p1, p2);
-		p2.setBeanClassVisibility(Visibility.DEFAULT);
+		p2.beanClassVisibility(Visibility.DEFAULT);
 		assertSameCache(p1, p2);
-		p1.setBeanClassVisibility(Visibility.NONE);
+		p1.beanClassVisibility(Visibility.NONE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanClassVisibility(Visibility.NONE);
+		p2.beanClassVisibility(Visibility.NONE);
 		assertSameCache(p1, p2);
-		p1.setBeanClassVisibility(Visibility.PRIVATE);
+		p1.beanClassVisibility(Visibility.PRIVATE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanClassVisibility(Visibility.PRIVATE);
+		p2.beanClassVisibility(Visibility.PRIVATE);
 		assertSameCache(p1, p2);
-		p1.setBeanClassVisibility(Visibility.PROTECTED);
+		p1.beanClassVisibility(Visibility.PROTECTED);
 		assertDifferentCache(p1, p2);
-		p2.setBeanClassVisibility(Visibility.PROTECTED);
+		p2.beanClassVisibility(Visibility.PROTECTED);
 		assertSameCache(p1, p2);
 
-		p1.setBeanFieldVisibility(Visibility.DEFAULT);
+		p1.beanFieldVisibility(Visibility.DEFAULT);
 		assertDifferentCache(p1, p2);
-		p2.setBeanFieldVisibility(Visibility.DEFAULT);
+		p2.beanFieldVisibility(Visibility.DEFAULT);
 		assertSameCache(p1, p2);
-		p1.setBeanFieldVisibility(Visibility.NONE);
+		p1.beanFieldVisibility(Visibility.NONE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanFieldVisibility(Visibility.NONE);
+		p2.beanFieldVisibility(Visibility.NONE);
 		assertSameCache(p1, p2);
-		p1.setBeanFieldVisibility(Visibility.PRIVATE);
+		p1.beanFieldVisibility(Visibility.PRIVATE);
 		assertDifferentCache(p1, p2);
-		p2.setBeanFieldVisibility(Visibility.PRIVATE);
+		p2.beanFieldVisibility(Visibility.PRIVATE);
 		assertSameCache(p1, p2);
-		p1.setBeanFieldVisibility(Visibility.PROTECTED);
+		p1.beanFieldVisibility(Visibility.PROTECTED);
 		assertDifferentCache(p1, p2);
-		p2.setBeanFieldVisibility(Visibility.PROTECTED);
+		p2.beanFieldVisibility(Visibility.PROTECTED);
 		assertSameCache(p1, p2);
 
-		p1.setMethodVisibility(Visibility.DEFAULT);
+		p1.methodVisibility(Visibility.DEFAULT);
 		assertDifferentCache(p1, p2);
-		p2.setMethodVisibility(Visibility.DEFAULT);
+		p2.methodVisibility(Visibility.DEFAULT);
 		assertSameCache(p1, p2);
-		p1.setMethodVisibility(Visibility.NONE);
+		p1.methodVisibility(Visibility.NONE);
 		assertDifferentCache(p1, p2);
-		p2.setMethodVisibility(Visibility.NONE);
+		p2.methodVisibility(Visibility.NONE);
 		assertSameCache(p1, p2);
-		p1.setMethodVisibility(Visibility.PRIVATE);
+		p1.methodVisibility(Visibility.PRIVATE);
 		assertDifferentCache(p1, p2);
-		p2.setMethodVisibility(Visibility.PRIVATE);
+		p2.methodVisibility(Visibility.PRIVATE);
 		assertSameCache(p1, p2);
-		p1.setMethodVisibility(Visibility.PROTECTED);
+		p1.methodVisibility(Visibility.PROTECTED);
 		assertDifferentCache(p1, p2);
-		p2.setMethodVisibility(Visibility.PROTECTED);
+		p2.methodVisibility(Visibility.PROTECTED);
 		assertSameCache(p1, p2);
 
-		p1.setUseJavaBeanIntrospector(true);
+		p1.useJavaBeanIntrospector(true);
 		assertDifferentCache(p1, p2);
-		p2.setUseJavaBeanIntrospector(true);
+		p2.useJavaBeanIntrospector(true);
 		assertSameCache(p1, p2);
 
-		p1.setUseInterfaceProxies(false);
+		p1.useInterfaceProxies(false);
 		assertDifferentCache(p1, p2);
-		p2.setUseInterfaceProxies(false);
+		p2.useInterfaceProxies(false);
 		assertSameCache(p1, p2);
 
-		p1.setIgnoreUnknownBeanProperties(true);
+		p1.ignoreUnknownBeanProperties(true);
 		assertDifferentCache(p1, p2);
-		p2.setIgnoreUnknownBeanProperties(true);
+		p2.ignoreUnknownBeanProperties(true);
 		assertSameCache(p1, p2);
 
-		p1.setIgnoreUnknownNullBeanProperties(false);
+		p1.ignoreUnknownNullBeanProperties(false);
 		assertDifferentCache(p1, p2);
-		p2.setIgnoreUnknownNullBeanProperties(false);
+		p2.ignoreUnknownNullBeanProperties(false);
 		assertSameCache(p1, p2);
 
-		p1.setIgnorePropertiesWithoutSetters(false);
+		p1.ignorePropertiesWithoutSetters(false);
 		assertDifferentCache(p1, p2);
-		p2.setIgnorePropertiesWithoutSetters(false);
+		p2.ignorePropertiesWithoutSetters(false);
 		assertSameCache(p1, p2);
 
-		p1.setIgnoreInvocationExceptionsOnGetters(true);
+		p1.ignoreInvocationExceptionsOnGetters(true);
 		assertDifferentCache(p1, p2);
-		p2.setIgnoreInvocationExceptionsOnGetters(true);
+		p2.ignoreInvocationExceptionsOnGetters(true);
 		assertSameCache(p1, p2);
 
-		p1.setIgnoreInvocationExceptionsOnSetters(true);
+		p1.ignoreInvocationExceptionsOnSetters(true);
 		assertDifferentCache(p1, p2);
-		p2.setIgnoreInvocationExceptionsOnSetters(true);
+		p2.ignoreInvocationExceptionsOnSetters(true);
 		assertSameCache(p1, p2);
 
-		p1.addNotBeanPackages("foo");
+		p1.notBeanPackages("foo");
 		assertDifferentCache(p1, p2);
-		p2.addNotBeanPackages("foo");
+		p2.notBeanPackages("foo");
 		assertSameCache(p1, p2);
-		p1.addNotBeanPackages("bar");
+		p1.notBeanPackages("bar");
 		assertDifferentCache(p1, p2);
-		p2.addNotBeanPackages("bar");
+		p2.notBeanPackages("bar");
 		assertSameCache(p1, p2);
-		p1.addNotBeanPackages("baz");
-		p1.addNotBeanPackages("bing");
+		p1.notBeanPackages("baz");
+		p1.notBeanPackages("bing");
 		assertDifferentCache(p1, p2);
-		p2.addNotBeanPackages("bing");
-		p2.addNotBeanPackages("baz");
+		p2.notBeanPackages("bing");
+		p2.notBeanPackages("baz");
 		assertSameCache(p1, p2);
 
 		p1.removeNotBeanPackages("bar");
@@ -718,22 +718,22 @@ public class BeanConfigTest {
 		p2.removeNotBeanPackages("bar");
 		assertSameCache(p1, p2);
 
-		p1.addPojoSwaps(DummyPojoSwapA.class);
+		p1.pojoSwaps(DummyPojoSwapA.class);
 		assertDifferentCache(p1, p2);
-		p2.addPojoSwaps(DummyPojoSwapA.class);
+		p2.pojoSwaps(DummyPojoSwapA.class);
 		assertSameCache(p1, p2);
-		p1.addPojoSwaps(DummyPojoSwapB.class,DummyPojoSwapC.class);  // Order of filters is important!
-		p2.addPojoSwaps(DummyPojoSwapC.class,DummyPojoSwapB.class);
+		p1.pojoSwaps(DummyPojoSwapB.class,DummyPojoSwapC.class);  // Order of filters is important!
+		p2.pojoSwaps(DummyPojoSwapC.class,DummyPojoSwapB.class);
 		assertDifferentCache(p1, p2);
 
-		p1 = new JsonParser();
-		p2 = new JsonParser();
-		p1.addBeanFilters(DummyBeanFilterA.class);
+		p1 = new JsonParserBuilder();
+		p2 = new JsonParserBuilder();
+		p1.beanFilters(DummyBeanFilterA.class);
 		assertDifferentCache(p1, p2);
-		p2.addBeanFilters(DummyBeanFilterA.class);
+		p2.beanFilters(DummyBeanFilterA.class);
 		assertSameCache(p1, p2);
-		p1.addBeanFilters(DummyBeanFilterB.class,DummyBeanFilterC.class);  // Order of filters is important!
-		p2.addBeanFilters(DummyBeanFilterC.class,DummyBeanFilterB.class);
+		p1.beanFilters(DummyBeanFilterB.class,DummyBeanFilterC.class);  // Order of filters is important!
+		p2.beanFilters(DummyBeanFilterC.class,DummyBeanFilterB.class);
 		assertDifferentCache(p1, p2);
 	}
 
@@ -757,12 +757,14 @@ public class BeanConfigTest {
 	}
 	public static class C {}
 
-	private void assertSameCache(Parser p1, Parser p2) {
+	private void assertSameCache(ParserBuilder p1b, ParserBuilder p2b) {
+		Parser p1 = p1b.build(), p2 = p2b.build();
 		assertTrue(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
 		assertTrue(p1.getBeanContext().hashCode() == p2.getBeanContext().hashCode());
 	}
 
-	private void assertDifferentCache(Parser p1, Parser p2) {
+	private void assertDifferentCache(ParserBuilder p1b, ParserBuilder p2b) {
+		Parser p1 = p1b.build(), p2 = p2b.build();
 		assertFalse(p1.getBeanContext().hasSameCache(p2.getBeanContext()));
 		assertFalse(p1.getBeanContext().hashCode() == p2.getBeanContext().hashCode());
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java b/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
index 8116344..8b6f383 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/BeanFilterTest.java
@@ -89,7 +89,7 @@ public class BeanFilterTest {
 	//====================================================================================================
 	@Test
 	public void testParentClassFilter() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple().addBeanFilters(C1.class);
+		JsonSerializer s = new JsonSerializerBuilder().simple().beanFilters(C1.class).build();
 
 		C1 c1 = new C2();
 		String r = s.serialize(c1);
@@ -114,7 +114,7 @@ public class BeanFilterTest {
 	//====================================================================================================
 	@Test
 	public void testParentClassFilter2() throws Exception {
-		JsonSerializer s = new JsonSerializer.Simple().addBeanFilters(D1.class);
+		JsonSerializer s = new JsonSerializerBuilder().simple().beanFilters(D1.class).build();
 
 		D1 d1 = new D2();
 		String r = s.serialize(d1);


[08/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
new file mode 100644
index 0000000..6ea4ed3
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerBuilder.java
@@ -0,0 +1,590 @@
+// ***************************************************************************************************************************
+// * 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.urlencoding;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
+
+/**
+ * Builder class for building instances of URL-Encoding serializers.
+ */
+public class UrlEncodingSerializerBuilder extends UonSerializerBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public UrlEncodingSerializerBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public UrlEncodingSerializerBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializer build() {
+		return new UrlEncodingSerializer(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Serialize bean property collections/arrays as separate key/value pairs.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
+	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
+	 *
+	 * <h5 class='section'>Example:</h5>
+	 * <p class='bcode'>
+	 * 	<jk>public class</jk> A {
+	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
+	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
+	 * 	}
+	 *
+	 * 	UrlEncodingSerializer s1 = UrlEncodingSerializer.<jsf>DEFAULT</jsf>;
+	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingSerializerBuilder().expandedParams(<jk>true</jk>).build();
+	 *
+	 * 	String ss1 = s1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
+	 * 	String ss2 = s2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
+	 * </p>
+	 * <p>
+	 * This option only applies to beans.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
+	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
+	 * 		is added to it.
+	 * </ul>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>URLENC_expandedParams</jsf>, value)</code>.
+	 * 	<li>This introduces a slight performance penalty.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see UrlEncodingContext#URLENC_expandedParams
+	 */
+	public UrlEncodingSerializerBuilder expandedParams(boolean value) {
+		return property(UrlEncodingContext.URLENC_expandedParams, value);
+	}
+
+	@Override /* UonSerializerBuilder */
+	public UrlEncodingSerializerBuilder encodeChars(boolean value) {
+		super.encodeChars(value);
+		return this;
+	}
+
+	@Override /* UonSerializerBuilder */
+	public UrlEncodingSerializerBuilder encoding() {
+		super.encoding();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder maxDepth(int value) {
+		super.maxDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder initialDepth(int value) {
+		super.initialDepth(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder detectRecursions(boolean value) {
+		super.detectRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder ignoreRecursions(boolean value) {
+		super.ignoreRecursions(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder useWhitespace(boolean value) {
+		super.useWhitespace(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder ws() {
+		super.ws();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder addBeanTypeProperties(boolean value) {
+		super.addBeanTypeProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder quoteChar(char value) {
+		super.quoteChar(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder sq() {
+		super.sq();
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder trimNullProperties(boolean value) {
+		super.trimNullProperties(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder trimEmptyCollections(boolean value) {
+		super.trimEmptyCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder trimEmptyMaps(boolean value) {
+		super.trimEmptyMaps(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder relativeUriBase(String value) {
+		super.relativeUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder absolutePathUriBase(String value) {
+		super.absolutePathUriBase(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder sortCollections(boolean value) {
+		super.sortCollections(value);
+		return this;
+	}
+
+	@Override /* SerializerBuilder */
+	public UrlEncodingSerializerBuilder sortMaps(boolean value) {
+		super.sortMaps(value);
+		return this;
+	}
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> UrlEncodingSerializerBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public UrlEncodingSerializerBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
index dc2c46e..7c546ec 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerContext.java
@@ -13,69 +13,31 @@
 package org.apache.juneau.urlencoding;
 
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Configurable properties on the {@link UrlEncodingSerializer} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  */
 public class UrlEncodingSerializerContext extends UonSerializerContext {
 
-	/**
-	 * <b>Configuration property:</b>  Serialize bean property collections/arrays as separate key/value pairs.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"UrlEncoding.expandedParams"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>false</jk>, serializing the array <code>[1,2,3]</code> results in <code>?key=$a(1,2,3)</code>.
-	 * If <jk>true</jk>, serializing the same array results in <code>?key=1&amp;key=2&amp;key=3</code>.
-	 *
-	 * <h5 class='section'>Example:</h5>
-	 * <p class='bcode'>
-	 * 	<jk>public class</jk> A {
-	 * 		<jk>public</jk> String[] f1 = {<js>"a"</js>,<js>"b"</js>};
-	 * 		<jk>public</jk> List&lt;String&gt; f2 = <jk>new</jk> LinkedList&lt;String&gt;(Arrays.<jsm>asList</jsm>(<jk>new</jk> String[]{<js>"c"</js>,<js>"d"</js>}));
-	 * 	}
-	 *
-	 * 	UrlEncodingSerializer s1 = <jk>new</jk> UrlEncodingParser();
-	 * 	UrlEncodingSerializer s2 = <jk>new</jk> UrlEncodingParser().setProperty(UrlEncodingContext.<jsf>URLENC_expandedParams</jsf>, <jk>true</jk>);
-	 *
-	 * 	String s1 = p1.serialize(<jk>new</jk> A()); <jc>// Produces "f1=(a,b)&amp;f2=(c,d)"</jc>
-	 * 	String s2 = p2.serialize(<jk>new</jk> A()); <jc>// Produces "f1=a&amp;f1=b&amp;f2=c&amp;f2=d"</jc>
-	 * </p>
-	 * <p>
-	 * This option only applies to beans.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>If parsing multi-part parameters, it's highly recommended to use Collections or Lists
-	 * 		as bean property types instead of arrays since arrays have to be recreated from scratch every time a value
-	 * 		is added to it.
-	 * </ul>
-	 */
-	public static final String URLENC_expandedParams = "UrlEncoding.expandedParams";
-
-
 	final boolean
 		expandedParams;
 
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public UrlEncodingSerializerContext(ContextFactory cf) {
-		super(cf);
-		this.expandedParams = cf.getProperty(URLENC_expandedParams, boolean.class, false);
+	public UrlEncodingSerializerContext(PropertyStore ps) {
+		super(ps);
+		this.expandedParams = ps.getProperty(UrlEncodingContext.URLENC_expandedParams, boolean.class, false);
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
index 9f89a7f..30b5b5c 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/UrlEncodingSerializerSession.java
@@ -12,13 +12,12 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.urlencoding;
 
-import static org.apache.juneau.urlencoding.UrlEncodingParserContext.*;
-
 import java.lang.reflect.*;
 import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.json.*;
+import org.apache.juneau.uon.*;
 
 /**
  * Session object that lives for the duration of a single use of {@link UrlEncodingSerializer}.
@@ -37,7 +36,7 @@ public class UrlEncodingSerializerSession extends UonSerializerSession {
 	 * @param output The output object.  See {@link JsonSerializerSession#getWriter()} for valid class types.
 	 * @param op The override properties.
 	 * These override any context properties defined in the context.
-	 * @param javaMethod The java method that called this parser, usually the method in a REST servlet.
+	 * @param javaMethod The java method that called this serializer, usually the method in a REST servlet.
 	 * @param locale The session locale.
 	 * If <jk>null</jk>, then the locale defined on the context is used.
 	 * @param timeZone The session timezone.
@@ -49,7 +48,7 @@ public class UrlEncodingSerializerSession extends UonSerializerSession {
 		if (op == null || op.isEmpty()) {
 			expandedParams = ctx.expandedParams;
 		} else {
-			expandedParams = op.getBoolean(URLENC_expandedParams, false);
+			expandedParams = op.getBoolean(UrlEncodingContext.URLENC_expandedParams, false);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
index 1282922..4d623d1 100644
--- a/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
+++ b/juneau-core/src/main/java/org/apache/juneau/urlencoding/package.html
@@ -305,7 +305,7 @@
 <h2 class='topic' onclick='toggle(this)'>2 - UrlEncodingSerializer and UonSerializer classes</h2>
 <div class='topic'>
 	<p>
-		{@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.urlencoding.UonSerializer} classes are used to convert POJOs to URL-encoded strings.<br>
+		{@link org.apache.juneau.urlencoding.UrlEncodingSerializer} and {@link org.apache.juneau.uon.UonSerializer} classes are used to convert POJOs to URL-encoded strings.<br>
 		The <code>UonSerializer</code> class converts parameter values to UON notation. 
 		The <code>UrlEncodingSerializer</code> class converts a POJO to key/value URL-Encoded pairs using <code>UonSerializer</code> to serialize the values.
 		If you're trying to construct complete URL-Encoded entities, use <code>UrlEncodingSerializer</code>. 
@@ -318,9 +318,9 @@
 	<ul class='spaced-list'>
 		<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT} - All default settings, strict mode.
 		<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability.
-		<li>{@link org.apache.juneau.urlencoding.UonSerializer#DEFAULT} - All default settings, strict mode.
-		<li>{@link org.apache.juneau.urlencoding.UonSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability.
-		<li>{@link org.apache.juneau.urlencoding.UonSerializer#DEFAULT_ENCODING} - Same as DEFAULT, but use URL-Encoding on special characters.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT} - All default settings, strict mode.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_READABLE} - Use whitespace and indentation for readability.
+		<li>{@link org.apache.juneau.uon.UonSerializer#DEFAULT_ENCODING} - Same as DEFAULT, but use URL-Encoding on special characters.
 	</ul>
 	<p>
 		The general guidelines on which serializer to use is:
@@ -623,7 +623,7 @@
 		</p>
 		<p class='bcode'>
 	<jc>// Clone an existing serializer and set property for detecting recursions.</jc>
-	UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT_READABLE</jsf>.clone().setDetectRecursions(<jk>true</jk>);
+	UrlEncodingSerializer s = UrlEncodingSerializer.<jsf>DEFAULT_READABLE</jsf>.builder().detectRecursions(<jk>true</jk>).build();
 
 	<jc>// Create a recursive loop.</jc>
 	A a = <jk>new</jk> A();
@@ -663,7 +663,7 @@
 		</p>
 		<ul class='spaced-list'>
 			<li>{@link org.apache.juneau.BeanContext} - Bean context properties.
-			<li>{@link org.apache.juneau.urlencoding.UonSerializerContext} - UON serializer context properties.
+			<li>{@link org.apache.juneau.uon.UonSerializerContext} - UON serializer context properties.
 			<li>{@link org.apache.juneau.urlencoding.UrlEncodingSerializerContext} - URL-Encoding serializer context properties.
 		</ul>
 	</div>		
@@ -686,7 +686,7 @@
 <h2 class='topic' onclick='toggle(this)'>3 - UrlEncodingParser and UonParser classes</h2>
 <div class='topic'>
 	<p>
-		{@link org.apache.juneau.urlencoding.UrlEncodingParser} and {@link org.apache.juneau.urlencoding.UonParser} classes are used to convert URL-encoded strings back into POJOs.<br>
+		{@link org.apache.juneau.urlencoding.UrlEncodingParser} and {@link org.apache.juneau.uon.UonParser} classes are used to convert URL-encoded strings back into POJOs.<br>
 		The <code>UonParser</code> class converts UON-encoded parameter values to POJOs.
 		The <code>UrlEncodingParser</code> class converts entire URL-Encoded strings to POJOs using <code>UonSerializer</code> to serialize indivisual values.
 		If you're trying to parse an entire URL-Encoded string, use <code>UrlEncodingParser</code>. 
@@ -697,8 +697,8 @@
 	</p>
 	<ul class='spaced-list'>
 		<li>{@link org.apache.juneau.urlencoding.UrlEncodingParser#DEFAULT} - Default parser for entire URL-encoded strings, decode <code>%xx</code> sequences.
-		<li>{@link org.apache.juneau.urlencoding.UonParser#DEFAULT} - Default parser for URL-encoded parameter values, don't decode <code>%xx</code> sequences.
-		<li>{@link org.apache.juneau.urlencoding.UonParser#DEFAULT_DECODING} - Default parser for URL-encoded parameter values, decode <code>%xx</code> sequences.
+		<li>{@link org.apache.juneau.uon.UonParser#DEFAULT} - Default parser for URL-encoded parameter values, don't decode <code>%xx</code> sequences.
+		<li>{@link org.apache.juneau.uon.UonParser#DEFAULT_DECODING} - Default parser for URL-encoded parameter values, decode <code>%xx</code> sequences.
 	</ul>
 	<p>
 		The general guildlines on which parser to use is:
@@ -916,7 +916,7 @@
 		</p>
 		<ul class='spaced-list'>
 			<li>{@link org.apache.juneau.BeanContext} - Bean context properties.
-			<li>{@link org.apache.juneau.urlencoding.UonParserContext} - UON parser context properties.
+			<li>{@link org.apache.juneau.uon.UonParserContext} - UON parser context properties.
 			<li>{@link org.apache.juneau.urlencoding.UrlEncodingParserContext} - URL-Encoding parser context properties.
 		</ul>
 	</div>		

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java b/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java
index e42ec1b..5249b17 100644
--- a/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java
+++ b/juneau-core/src/main/java/org/apache/juneau/utils/PojoQuery.java
@@ -622,7 +622,7 @@ public final class PojoQuery {
 			numberRanges = l.toArray(new NumberRange[l.size()]);
 		}
 
-		private List<String> breakUpTokens(String s) {
+		private static List<String> breakUpTokens(String s) {
 			// Get rid of whitespace in "123 - 456"
 			s = s.replaceAll("(-?\\d+)\\s*-\\s*(-?\\d+)", "$1-$2");
 			// Get rid of whitespace in ">= 123"
@@ -1042,7 +1042,7 @@ public final class PojoQuery {
 		/**
 		 * Break up search pattern into separate tokens.
 		 */
-		private List<String> breakUpTokens(String s) {
+		private static List<String> breakUpTokens(String s) {
 
 			// If the string is null or all whitespace, return an empty vector.
 			if (s == null || s.trim().length() == 0)

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
index 0121a3e..7b00113 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlBeanMeta.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.xml;
 
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
+
 import java.util.*;
 
 import org.apache.juneau.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
index c62d18f..0d4a9d2 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlDocSerializer.java
@@ -12,6 +12,9 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.xml;
 
+import static org.apache.juneau.xml.XmlSerializerContext.*;
+
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.serializer.*;
 
@@ -33,14 +36,30 @@ import org.apache.juneau.serializer.*;
 public class XmlDocSerializer extends XmlSerializer {
 
 	/** Default serializer without namespaces. */
-	@Produces(value="text/xml+simple",contentType="text/xml")
-	public static class Simple extends XmlDocSerializer {
-		/** Constructor */
-		public Simple() {
-			setEnableNamespaces(false);
+	@Produces(value="text/xml",contentType="text/xml")
+	public static class Ns extends XmlDocSerializer {
+
+		/**
+		 * Constructor.
+		 * @param propertyStore The property store containing all the settings for this object.
+		 */
+		public Ns(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
+		@Override /* CoreObject */
+		protected ObjectMap getOverrideProperties() {
+			return super.getOverrideProperties().append(XML_enableNamespaces, true);
 		}
 	}
 
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public XmlDocSerializer(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
 
 	//--------------------------------------------------------------------------------
 	// Entry point methods

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
index a6a0212..7a325c7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParser.java
@@ -15,13 +15,11 @@ package org.apache.juneau.xml;
 import static javax.xml.stream.XMLStreamConstants.*;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.xml.annotation.XmlFormat.*;
-import static org.apache.juneau.xml.XmlParserContext.*;
 
 import java.lang.reflect.*;
 import java.util.*;
 
 import javax.xml.stream.*;
-import javax.xml.stream.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
@@ -53,10 +51,27 @@ import org.apache.juneau.xml.annotation.*;
 public class XmlParser extends ReaderParser {
 
 	/** Default parser, all default settings.*/
-	public static final XmlParser DEFAULT = new XmlParser().lock();
+	public static final XmlParser DEFAULT = new XmlParser(PropertyStore.create());
 
 	private static final int UNKNOWN=0, OBJECT=1, ARRAY=2, STRING=3, NUMBER=4, BOOLEAN=5, NULL=6;
 
+
+	private final XmlParserContext ctx;
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
+	 */
+	public XmlParser(PropertyStore propertyStore) {
+		super(propertyStore);
+		this.ctx = createContext(XmlParserContext.class);
+	}
+
+	@Override /* CoreObject */
+	public XmlParserBuilder builder() {
+		return new XmlParserBuilder(propertyStore);
+	}
+
 	/**
 	 * Workhorse method.
 	 *
@@ -497,7 +512,7 @@ public class XmlParser extends ReaderParser {
 
 	@Override /* Parser */
 	public XmlParserSession createSession(Object input, ObjectMap op, Method javaMethod, Object outer, Locale locale, TimeZone timeZone, MediaType mediaType) {
-		return new XmlParserSession(getContext(XmlParserContext.class), op, input, javaMethod, outer, locale, timeZone, mediaType);
+		return new XmlParserSession(ctx, op, input, javaMethod, outer, locale, timeZone, mediaType);
 	}
 
 	@Override /* Parser */
@@ -525,585 +540,4 @@ public class XmlParser extends ReaderParser {
 		XmlParserSession s = (XmlParserSession)session;
 		return doParseArgs(s, s.getXmlStreamReader(), argTypes);
 	}
-
-
-	//--------------------------------------------------------------------------------
-	// Properties
-	//--------------------------------------------------------------------------------
-
-	/**
-	 * <b>Configuration property:</b>  Enable validation.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlParser.validating"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, XML document will be validated.
-	 * See {@link XMLInputFactory#IS_VALIDATING} for more info.
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_validating</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlParserContext#XML_validating
-	 */
-	public XmlParser setValidating(boolean value) throws LockedException {
-		return setProperty(XML_validating, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XML reporter.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlParser.reporter"</js>
-	 * 	<li><b>Data type:</b> {@link XMLReporter}
-	 * 	<li><b>Default:</b> <jk>null</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Associates an {@link XMLReporter} with this parser.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>Reporters are not copied to new parsers during a clone.
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_reporter</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlParserContext#XML_reporter
-	 */
-	public XmlParser setReporter(XMLReporter value) throws LockedException {
-		return setProperty(XML_reporter, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XML resolver.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlParser.resolver"</js>
-	 * 	<li><b>Data type:</b> {@link XMLResolver}
-	 * 	<li><b>Default:</b> <jk>null</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Associates an {@link XMLResolver} with this parser.
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_resolver</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlParserContext#XML_resolver
-	 */
-	public XmlParser setResolver(XMLResolver value) throws LockedException {
-		return setProperty(XML_resolver, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  XML event allocator.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlParser.eventAllocator"</js>
-	 * 	<li><b>Data type:</b> {@link XMLEventAllocator}
-	 * 	<li><b>Default:</b> <jk>null</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * Associates an {@link XMLEventAllocator} with this parser.
-	 * <p>
-	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_eventAllocator</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlParserContext#XML_eventAllocator
-	 */
-	public XmlParser setEventAllocator(XMLEventAllocator value) throws LockedException {
-		return setProperty(XML_eventAllocator, value);
-	}
-
-	/**
-	 * <b>Configuration property:</b>  Preserve root element during generalized parsing.
-	 * <p>
-	 * <ul>
-	 * 	<li><b>Name:</b> <js>"XmlParser.preserveRootElement"</js>
-	 * 	<li><b>Data type:</b> <code>Boolean</code>
-	 * 	<li><b>Default:</b> <jk>false</jk>
-	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
-	 * </ul>
-	 * <p>
-	 * If <jk>true</jk>, when parsing into a generic {@link ObjectMap}, the map will
-	 * 	contain a single entry whose key is the root element name.
-	 *
-	 * Example:
-	 * <table class='styled'>
-	 * 	<tr>
-	 * 		<td>XML</td>
-	 * 		<td>ObjectMap.toString(), preserveRootElement==false</td>
-	 * 		<td>ObjectMap.toString(), preserveRootElement==true</td>
-	 * 	</tr>
-	 * 	<tr>
-	 * 		<td><code><xt>&lt;root&gt;&lt;a&gt;</xt>foobar<xt>&lt;/a&gt;&lt;/root&gt;</xt></code></td>
-	 * 		<td><code>{ a:<js>'foobar'</js> }</code></td>
-	 * 		<td><code>{ root: { a:<js>'foobar'</js> }}</code></td>
-	 * 	</tr>
-	 * </table>
-	 * <p>
-	 * <h5 class='section'>Notes:</h5>
-	 * <ul>
-	 * 	<li>This is equivalent to calling <code>setProperty(<jsf>XML_preserveRootElement</jsf>, value)</code>.
-	 * </ul>
-	 *
-	 * @param value The new value for this property.
-	 * @return This object (for method chaining).
-	 * @throws LockedException If {@link #lock()} was called on this class.
-	 * @see XmlParserContext#XML_preserveRootElement
-	 */
-	public XmlParser setPreserveRootElement(boolean value) throws LockedException {
-		return setProperty(XML_preserveRootElement, value);
-	}
-
-	@Override /* Parser */
-	public XmlParser setTrimStrings(boolean value) throws LockedException {
-		super.setTrimStrings(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public XmlParser setStrict(boolean value) throws LockedException {
-		super.setStrict(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public XmlParser setInputStreamCharset(String value) throws LockedException {
-		super.setInputStreamCharset(value);
-		return this;
-	}
-
-	@Override /* Parser */
-	public XmlParser setFileCharset(String value) throws LockedException {
-		super.setFileCharset(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeansRequireDefaultConstructor(boolean value) throws LockedException {
-		super.setBeansRequireDefaultConstructor(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeansRequireSerializable(boolean value) throws LockedException {
-		super.setBeansRequireSerializable(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeansRequireSettersForGetters(boolean value) throws LockedException {
-		super.setBeansRequireSettersForGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeansRequireSomeProperties(boolean value) throws LockedException {
-		super.setBeansRequireSomeProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanMapPutReturnsOldValue(boolean value) throws LockedException {
-		super.setBeanMapPutReturnsOldValue(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanConstructorVisibility(Visibility value) throws LockedException {
-		super.setBeanConstructorVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanClassVisibility(Visibility value) throws LockedException {
-		super.setBeanClassVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanFieldVisibility(Visibility value) throws LockedException {
-		super.setBeanFieldVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setMethodVisibility(Visibility value) throws LockedException {
-		super.setMethodVisibility(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setUseJavaBeanIntrospector(boolean value) throws LockedException {
-		super.setUseJavaBeanIntrospector(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setUseInterfaceProxies(boolean value) throws LockedException {
-		super.setUseInterfaceProxies(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setIgnoreUnknownBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setIgnoreUnknownNullBeanProperties(boolean value) throws LockedException {
-		super.setIgnoreUnknownNullBeanProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setIgnorePropertiesWithoutSetters(boolean value) throws LockedException {
-		super.setIgnorePropertiesWithoutSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setIgnoreInvocationExceptionsOnGetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnGetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setIgnoreInvocationExceptionsOnSetters(boolean value) throws LockedException {
-		super.setIgnoreInvocationExceptionsOnSetters(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setSortProperties(boolean value) throws LockedException {
-		super.setSortProperties(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setNotBeanPackages(String...values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setNotBeanPackages(Collection<String> values) throws LockedException {
-		super.setNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addNotBeanPackages(String...values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addNotBeanPackages(Collection<String> values) throws LockedException {
-		super.addNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeNotBeanPackages(String...values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeNotBeanPackages(Collection<String> values) throws LockedException {
-		super.removeNotBeanPackages(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setNotBeanClasses(Class<?>...values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.setNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addNotBeanClasses(Class<?>...values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.addNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeNotBeanClasses(Class<?>...values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeNotBeanClasses(Collection<Class<?>> values) throws LockedException {
-		super.removeNotBeanClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanFilters(Class<?>...values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.setBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addBeanFilters(Class<?>...values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.addBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeBeanFilters(Class<?>...values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeBeanFilters(Collection<Class<?>> values) throws LockedException {
-		super.removeBeanFilters(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setPojoSwaps(Class<?>...values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.setPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addPojoSwaps(Class<?>...values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addPojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.addPojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removePojoSwaps(Class<?>...values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removePojoSwaps(Collection<Class<?>> values) throws LockedException {
-		super.removePojoSwaps(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setImplClasses(Map<Class<?>,Class<?>> values) throws LockedException {
-		super.setImplClasses(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public <T> CoreApi addImplClass(Class<T> interfaceClass, Class<? extends T> implClass) throws LockedException {
-		super.addImplClass(interfaceClass, implClass);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanDictionary(Class<?>...values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.setBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addToBeanDictionary(Class<?>...values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addToBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.addToBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeFromBeanDictionary(Class<?>...values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeFromBeanDictionary(Collection<Class<?>> values) throws LockedException {
-		super.removeFromBeanDictionary(values);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setBeanTypePropertyName(String value) throws LockedException {
-		super.setBeanTypePropertyName(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setDefaultParser(Class<?> value) throws LockedException {
-		super.setDefaultParser(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setLocale(Locale value) throws LockedException {
-		super.setLocale(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setTimeZone(TimeZone value) throws LockedException {
-		super.setTimeZone(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setMediaType(MediaType value) throws LockedException {
-		super.setMediaType(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setDebug(boolean value) throws LockedException {
-		super.setDebug(value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setProperty(String name, Object value) throws LockedException {
-		super.setProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser setProperties(ObjectMap properties) throws LockedException {
-		super.setProperties(properties);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser addToProperty(String name, Object value) throws LockedException {
-		super.addToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser putToProperty(String name, Object key, Object value) throws LockedException {
-		super.putToProperty(name, key, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser putToProperty(String name, Object value) throws LockedException {
-		super.putToProperty(name, value);
-		return this;
-	}
-
-	@Override /* CoreApi */
-	public XmlParser removeFromProperty(String name, Object value) throws LockedException {
-		super.removeFromProperty(name, value);
-		return this;
-	}
-
-
-	//--------------------------------------------------------------------------------
-	// Overridden methods
-	//--------------------------------------------------------------------------------
-
-	@Override /* CoreApi */
-	public XmlParser setClassLoader(ClassLoader classLoader) throws LockedException {
-		super.setClassLoader(classLoader);
-		return this;
-	}
-
-	@Override /* Lockable */
-	public XmlParser lock() {
-		super.lock();
-		return this;
-	}
-
-	@Override /* Lockable */
-	public XmlParser clone() {
-		try {
-			XmlParser c = (XmlParser)super.clone();
-			return c;
-		} catch (CloneNotSupportedException e) {
-			throw new RuntimeException(e); // Shouldn't happen.
-		}
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserBuilder.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserBuilder.java
new file mode 100644
index 0000000..6074bb3
--- /dev/null
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserBuilder.java
@@ -0,0 +1,616 @@
+// ***************************************************************************************************************************
+// * 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.xml;
+
+import static org.apache.juneau.xml.XmlParserContext.*;
+
+import java.util.*;
+
+import javax.xml.stream.*;
+import javax.xml.stream.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.parser.*;
+
+/**
+ * Builder class for building XML parsers.
+ */
+public class XmlParserBuilder extends ParserBuilder {
+
+	/**
+	 * Constructor, default settings.
+	 */
+	public XmlParserBuilder() {
+		super();
+	}
+
+	/**
+	 * Constructor.
+	 * @param propertyStore The initial configuration settings for this builder.
+	 */
+	public XmlParserBuilder(PropertyStore propertyStore) {
+		super(propertyStore);
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParser build() {
+		return new XmlParser(propertyStore);
+	}
+
+
+	//--------------------------------------------------------------------------------
+	// Properties
+	//--------------------------------------------------------------------------------
+
+	/**
+	 * <b>Configuration property:</b>  Enable validation.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlParserBuilder.validating"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, XML document will be validated.
+	 * See {@link XMLInputFactory#IS_VALIDATING} for more info.
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_validating</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlParserContext#XML_validating
+	 */
+	public XmlParserBuilder validating(boolean value) {
+		return property(XML_validating, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XML reporter.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlParserBuilder.reporter"</js>
+	 * 	<li><b>Data type:</b> {@link XMLReporter}
+	 * 	<li><b>Default:</b> <jk>null</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Associates an {@link XMLReporter} with this parser.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>Reporters are not copied to new parsers during a clone.
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_reporter</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlParserContext#XML_reporter
+	 */
+	public XmlParserBuilder reporter(XMLReporter value) {
+		return property(XML_reporter, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XML resolver.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlParserBuilder.resolver"</js>
+	 * 	<li><b>Data type:</b> {@link XMLResolver}
+	 * 	<li><b>Default:</b> <jk>null</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Associates an {@link XMLResolver} with this parser.
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_resolver</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlParserContext#XML_resolver
+	 */
+	public XmlParserBuilder resolver(XMLResolver value) {
+		return property(XML_resolver, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  XML event allocator.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlParserBuilder.eventAllocator"</js>
+	 * 	<li><b>Data type:</b> {@link XMLEventAllocator}
+	 * 	<li><b>Default:</b> <jk>null</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * Associates an {@link XMLEventAllocator} with this parser.
+	 * <p>
+	 * If <jk>true</jk>, string values will be trimmed of whitespace using {@link String#trim()} before being added to the POJO.
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_eventAllocator</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlParserContext#XML_eventAllocator
+	 */
+	public XmlParserBuilder eventAllocator(XMLEventAllocator value) {
+		return property(XML_eventAllocator, value);
+	}
+
+	/**
+	 * <b>Configuration property:</b>  Preserve root element during generalized parsing.
+	 * <p>
+	 * <ul>
+	 * 	<li><b>Name:</b> <js>"XmlParserBuilder.preserveRootElement"</js>
+	 * 	<li><b>Data type:</b> <code>Boolean</code>
+	 * 	<li><b>Default:</b> <jk>false</jk>
+	 * 	<li><b>Session-overridable:</b> <jk>true</jk>
+	 * </ul>
+	 * <p>
+	 * If <jk>true</jk>, when parsing into a generic {@link ObjectMap}, the map will
+	 * 	contain a single entry whose key is the root element name.
+	 *
+	 * Example:
+	 * <table class='styled'>
+	 * 	<tr>
+	 * 		<td>XML</td>
+	 * 		<td>ObjectMap.toString(), preserveRootElement==false</td>
+	 * 		<td>ObjectMap.toString(), preserveRootElement==true</td>
+	 * 	</tr>
+	 * 	<tr>
+	 * 		<td><code><xt>&lt;root&gt;&lt;a&gt;</xt>foobar<xt>&lt;/a&gt;&lt;/root&gt;</xt></code></td>
+	 * 		<td><code>{ a:<js>'foobar'</js> }</code></td>
+	 * 		<td><code>{ root: { a:<js>'foobar'</js> }}</code></td>
+	 * 	</tr>
+	 * </table>
+	 * <p>
+	 * <h5 class='section'>Notes:</h5>
+	 * <ul>
+	 * 	<li>This is equivalent to calling <code>property(<jsf>XML_preserveRootElement</jsf>, value)</code>.
+	 * </ul>
+	 *
+	 * @param value The new value for this property.
+	 * @return This object (for method chaining).
+	 * @see XmlParserContext#XML_preserveRootElement
+	 */
+	public XmlParserBuilder preserveRootElement(boolean value) {
+		return property(XML_preserveRootElement, value);
+	}
+
+	@Override /* ParserBuilder */
+	public XmlParserBuilder trimStrings(boolean value) {
+		super.trimStrings(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public XmlParserBuilder strict(boolean value) {
+		super.strict(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public XmlParserBuilder strict() {
+		super.strict();
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public XmlParserBuilder inputStreamCharset(String value) {
+		super.inputStreamCharset(value);
+		return this;
+	}
+
+	@Override /* ParserBuilder */
+	public XmlParserBuilder fileCharset(String value) {
+		super.fileCharset(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beansRequireDefaultConstructor(boolean value) {
+		super.beansRequireDefaultConstructor(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beansRequireSerializable(boolean value) {
+		super.beansRequireSerializable(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beansRequireSettersForGetters(boolean value) {
+		super.beansRequireSettersForGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beansRequireSomeProperties(boolean value) {
+		super.beansRequireSomeProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanMapPutReturnsOldValue(boolean value) {
+		super.beanMapPutReturnsOldValue(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanConstructorVisibility(Visibility value) {
+		super.beanConstructorVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanClassVisibility(Visibility value) {
+		super.beanClassVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanFieldVisibility(Visibility value) {
+		super.beanFieldVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder methodVisibility(Visibility value) {
+		super.methodVisibility(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder useJavaBeanIntrospector(boolean value) {
+		super.useJavaBeanIntrospector(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder useInterfaceProxies(boolean value) {
+		super.useInterfaceProxies(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder ignoreUnknownBeanProperties(boolean value) {
+		super.ignoreUnknownBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder ignoreUnknownNullBeanProperties(boolean value) {
+		super.ignoreUnknownNullBeanProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder ignorePropertiesWithoutSetters(boolean value) {
+		super.ignorePropertiesWithoutSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder ignoreInvocationExceptionsOnGetters(boolean value) {
+		super.ignoreInvocationExceptionsOnGetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder ignoreInvocationExceptionsOnSetters(boolean value) {
+		super.ignoreInvocationExceptionsOnSetters(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder sortProperties(boolean value) {
+		super.sortProperties(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder notBeanPackages(String...values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder notBeanPackages(Collection<String> values) {
+		super.notBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setNotBeanPackages(String...values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setNotBeanPackages(Collection<String> values) {
+		super.setNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeNotBeanPackages(String...values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeNotBeanPackages(Collection<String> values) {
+		super.removeNotBeanPackages(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder notBeanClasses(Class<?>...values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder notBeanClasses(Collection<Class<?>> values) {
+		super.notBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setNotBeanClasses(Class<?>...values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setNotBeanClasses(Collection<Class<?>> values) {
+		super.setNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeNotBeanClasses(Class<?>...values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeNotBeanClasses(Collection<Class<?>> values) {
+		super.removeNotBeanClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanFilters(Class<?>...values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanFilters(Collection<Class<?>> values) {
+		super.beanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setBeanFilters(Class<?>...values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setBeanFilters(Collection<Class<?>> values) {
+		super.setBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeBeanFilters(Class<?>...values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeBeanFilters(Collection<Class<?>> values) {
+		super.removeBeanFilters(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder pojoSwaps(Class<?>...values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder pojoSwaps(Collection<Class<?>> values) {
+		super.pojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setPojoSwaps(Class<?>...values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setPojoSwaps(Collection<Class<?>> values) {
+		super.setPojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removePojoSwaps(Class<?>...values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removePojoSwaps(Collection<Class<?>> values) {
+		super.removePojoSwaps(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder implClasses(Map<Class<?>,Class<?>> values) {
+		super.implClasses(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public <T> CoreObjectBuilder implClass(Class<T> interfaceClass, Class<? extends T> implClass) {
+		super.implClass(interfaceClass, implClass);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanDictionary(Class<?>...values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanDictionary(Collection<Class<?>> values) {
+		super.beanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setBeanDictionary(Class<?>...values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder setBeanDictionary(Collection<Class<?>> values) {
+		super.setBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeFromBeanDictionary(Class<?>...values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeFromBeanDictionary(Collection<Class<?>> values) {
+		super.removeFromBeanDictionary(values);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder beanTypePropertyName(String value) {
+		super.beanTypePropertyName(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder defaultParser(Class<?> value) {
+		super.defaultParser(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder locale(Locale value) {
+		super.locale(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder timeZone(TimeZone value) {
+		super.timeZone(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder mediaType(MediaType value) {
+		super.mediaType(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder debug(boolean value) {
+		super.debug(value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder property(String name, Object value) {
+		super.property(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder properties(Map<String,Object> properties) {
+		super.properties(properties);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder addToProperty(String name, Object value) {
+		super.addToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder putToProperty(String name, Object key, Object value) {
+		super.putToProperty(name, key, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder putToProperty(String name, Object value) {
+		super.putToProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder removeFromProperty(String name, Object value) {
+		super.removeFromProperty(name, value);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder classLoader(ClassLoader classLoader) {
+		super.classLoader(classLoader);
+		return this;
+	}
+
+	@Override /* CoreObjectBuilder */
+	public XmlParserBuilder apply(PropertyStore copyFrom) {
+		super.apply(copyFrom);
+		return this;
+	}
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserContext.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserContext.java
index 095410d..931edd7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserContext.java
@@ -21,10 +21,10 @@ import org.apache.juneau.parser.*;
 /**
  * Configurable properties on the {@link XmlParser} class.
  * <p>
- * Context properties are set by calling {@link ContextFactory#setProperty(String, Object)} on the context factory
- * returned {@link CoreApi#getContextFactory()}.
+ * Context properties are set by calling {@link PropertyStore#setProperty(String, Object)} on the property store
+ * passed into the constructor.
  * <p>
- * See {@link ContextFactory} for more information about context properties.
+ * See {@link PropertyStore} for more information about context properties.
  *
  * <h5 class='section'>Inherited configurable properties:</h5>
  * <ul class='javahierarchy'>
@@ -137,17 +137,17 @@ public class XmlParserContext extends ParserContext {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public XmlParserContext(ContextFactory cf) {
-		super(cf);
-		validating = cf.getProperty(XML_validating, boolean.class, false);
-		preserveRootElement = cf.getProperty(XML_preserveRootElement, boolean.class, false);
-		reporter = cf.getProperty(XML_reporter, XMLReporter.class, null);
-		resolver = cf.getProperty(XML_resolver, XMLResolver.class, null);
-		eventAllocator = cf.getProperty(XML_eventAllocator, XMLEventAllocator.class, null);
+	public XmlParserContext(PropertyStore ps) {
+		super(ps);
+		validating = ps.getProperty(XML_validating, boolean.class, false);
+		preserveRootElement = ps.getProperty(XML_preserveRootElement, boolean.class, false);
+		reporter = ps.getProperty(XML_reporter, XMLReporter.class, null);
+		resolver = ps.getProperty(XML_resolver, XMLResolver.class, null);
+		eventAllocator = ps.getProperty(XML_eventAllocator, XMLEventAllocator.class, null);
 	}
 
 	@Override /* Context */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
index 6a52ed7..0cb6aba 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlParserSession.java
@@ -12,8 +12,8 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.xml;
 
+import static javax.xml.stream.XMLStreamConstants.*;
 import static org.apache.juneau.xml.XmlParserContext.*;
-import static  javax.xml.stream.XMLStreamConstants.*;
 
 import java.io.*;
 import java.lang.reflect.*;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaDocSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaDocSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaDocSerializer.java
index 6dd2841..5036bf8 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaDocSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaDocSerializer.java
@@ -37,16 +37,10 @@ public class XmlSchemaDocSerializer extends XmlSchemaSerializer {
 
 	/**
 	 * Constructor.
+	 * @param propertyStore The property store containing all the settings for this object.
 	 */
-	public XmlSchemaDocSerializer() {}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param cf The context factory to use for creating the context for this serializer.
-	 */
-	protected XmlSchemaDocSerializer(ContextFactory cf) {
-		super(cf);
+	public XmlSchemaDocSerializer(PropertyStore propertyStore) {
+		super(propertyStore, null);
 	}
 
 	@Override /* Serializer */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
index ec9bc52..1cd340f 100644
--- a/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
+++ b/juneau-core/src/main/java/org/apache/juneau/xml/XmlSchemaSerializer.java
@@ -56,20 +56,24 @@ import org.w3c.dom.ls.*;
 @Produces(value="text/xml+schema",contentType="text/xml")
 public class XmlSchemaSerializer extends XmlSerializer {
 
+	private final XmlSerializerContext ctx;
+
 	/**
-	 * Constructor
+	 * Constructor.
+	 * @param propertyStore Initialize with the specified config property store.
 	 */
-	public XmlSchemaSerializer() {
-		super();
+	public XmlSchemaSerializer(PropertyStore propertyStore) {
+		this(propertyStore, null);
 	}
 
 	/**
-	 * Constructor.
-	 *
-	 * @param config Initialize with the specified config property store.
+	 * Constructor
+	 * @param propertyStore The property store containing all the settings for this object.
+	 * @param overrideProperties A set of overridden settings, typically defined by the class itself.
 	 */
-	protected XmlSchemaSerializer(ContextFactory config) {
-		getContextFactory().copyFrom(config);
+	public XmlSchemaSerializer(PropertyStore propertyStore, Map<String,Object> overrideProperties) {
+		super(propertyStore);
+		this.ctx = this.propertyStore.create(overrideProperties).getContext(XmlSerializerContext.class);
 	}
 
 	@Override /* XmlSerializer */
@@ -580,6 +584,6 @@ public class XmlSchemaSerializer extends XmlSerializer {
 		if (op == null)
 			op = new ObjectMap();
 		op.put(XmlSerializerContext.XML_enableNamespaces, true);
-		return new XmlSerializerSession(getContext(XmlSerializerContext.class), op, output, javaMethod, locale, timeZone, mediaType);
+		return new XmlSerializerSession(ctx, op, output, javaMethod, locale, timeZone, mediaType);
 	}
 }


[28/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UrlEncodingTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UrlEncodingTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UrlEncodingTest.java
index c8f40d3..e0b6012 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UrlEncodingTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/Common_UrlEncodingTest.java
@@ -21,7 +21,6 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.testbeans.*;
 import org.junit.*;
 
@@ -34,17 +33,17 @@ public class Common_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		UrlEncodingSerializer s = new UrlEncodingSerializer();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("s1=null&s2=s2", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("s2=s2", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -65,18 +64,18 @@ public class Common_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		UrlEncodingSerializer s = UrlEncodingSerializer.DEFAULT.clone();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("f1=()&f2=(f2a=null,f2b=(s2=s2))", r);
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("f2=(f2a=null,f2b=(s2=s2))", r);
 		t2 = p.parse(r, B.class);
 		assertNull(t2.f1);
@@ -98,18 +97,18 @@ public class Common_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		UrlEncodingSerializer s = new UrlEncodingSerializer();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("f1=@()&f2=@(null,(s2=s2))", r);
 		t2 = p.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("f2=@(null,(s2=s2))", r);
 		t2 = p.parse(r, C.class);
 		assertNull(t2.f1);
@@ -131,18 +130,18 @@ public class Common_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		UrlEncodingSerializer s = new UrlEncodingSerializer();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("f1=@()&f2=@(null,(s2=s2))", r);
 		t2 = p.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("f2=@(null,(s2=s2))", r);
 		t2 = p.parse(r, D.class);
 		assertNull(t2.f1);
@@ -242,13 +241,13 @@ public class Common_UrlEncodingTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		WriterSerializer s = new UrlEncodingSerializer();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 		TestURI t = new TestURI();
 		String r;
 		String expected = "";
 
-		s.setRelativeUriBase(null);
-		r = s.serialize(t);
+		s.relativeUriBase(null);
+		r = s.build().serialize(t);
 		expected = ""
 			+"f0=f0/x0"
 			+"&f1=f1/x1"
@@ -267,12 +266,12 @@ public class Common_UrlEncodingTest {
 			+"&fe='http://www.apache.org/fe/xe?foo=bar%26label2=MY_LABEL'";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.relativeUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = s.serialize(t);
+		s.relativeUriBase("/cr");
+		r = s.build().serialize(t);
 		expected = ""
 			+"f0=/cr/f0/x0"
 			+"&f1=/cr/f1/x1"
@@ -291,12 +290,12 @@ public class Common_UrlEncodingTest {
 			+"&fe='http://www.apache.org/fe/xe?foo=bar%26label2=MY_LABEL'";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = s.serialize(t);
+		s.relativeUriBase("/cr/");  // Same as above
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = s.serialize(t);
+		s.relativeUriBase("/");
+		r = s.build().serialize(t);
 		expected = ""
 			+"f0=/f0/x0"
 			+"&f1=/f1/x1"
@@ -315,10 +314,10 @@ public class Common_UrlEncodingTest {
 			+"&fe='http://www.apache.org/fe/xe?foo=bar%26label2=MY_LABEL'";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo");
+		r = s.build().serialize(t);
 		expected = ""
 			+"f0=f0/x0"
 			+"&f1=f1/x1"
@@ -337,12 +336,12 @@ public class Common_UrlEncodingTest {
 			+"&fe='http://www.apache.org/fe/xe?foo=bar%26label2=MY_LABEL'";
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo/");
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.absolutePathUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		expected = ""
 			+"f0=f0/x0"
 			+"&f1=f1/x1"
@@ -363,31 +362,11 @@ public class Common_UrlEncodingTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		UrlEncodingSerializer s = new UrlEncodingSerializer().lock();
-		try {
-			s.setUseWhitespace(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		WriterSerializer s = new UrlEncodingSerializer();
+		UrlEncodingSerializerBuilder s = new UrlEncodingSerializerBuilder();
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -398,7 +377,7 @@ public class Common_UrlEncodingTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -406,9 +385,9 @@ public class Common_UrlEncodingTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -418,8 +397,8 @@ public class Common_UrlEncodingTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.urlencoding.Common_UrlEncodingTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		assertEquals("name=foo&r2=(name=bar,r3=(name=baz))", s.serialize(r1));
+		s.ignoreRecursions(true);
+		assertEquals("name=foo&r2=(name=bar,r3=(name=baz))", s.build().serialize(r1));
 	}
 
 	public static class R1 {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserReaderTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserReaderTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserReaderTest.java
index ee37cb0..32833b9 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserReaderTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserReaderTest.java
@@ -17,6 +17,7 @@ import static org.junit.Assert.*;
 import java.io.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings({"javadoc","resource"})

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserTest.java
index de54711..87b46e1 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonParserTest.java
@@ -17,6 +17,7 @@ import static org.junit.Assert.*;
 import java.util.*;
 
 import org.apache.juneau.parser.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings({"rawtypes","javadoc"})

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonSerializerTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonSerializerTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonSerializerTest.java
index 4c6d001..bf3bc75 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonSerializerTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UonSerializerTest.java
@@ -15,6 +15,7 @@ package org.apache.juneau.urlencoding;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
index 753d585..474c467 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingParserTest.java
@@ -850,7 +850,7 @@ public class UrlEncodingParserTest {
 		UrlEncodingParser p;
 		String in;
 
-		p = UrlEncodingParser.DEFAULT.clone().setExpandedParams(true);
+		p = new UrlEncodingParserBuilder().expandedParams(true).build();
 		in = ""
 			+ "f01=a&f01=b"
 			+ "&f02=c&f02=d"

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
index 84f240b..91dc1a6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/urlencoding/UrlEncodingSerializerTest.java
@@ -17,7 +17,7 @@ import static org.junit.Assert.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.json.JsonSerializer;
+import org.apache.juneau.json.*;
 import org.junit.*;
 
 @SuppressWarnings("javadoc")
@@ -343,7 +343,7 @@ public class UrlEncodingSerializerTest {
 			+ "&f20=@(@((a=a,b=1,c=true)),@((a=a,b=1,c=true)))";
 		assertEquals(e, r);
 
-		s = UrlEncodingSerializer.DEFAULT.clone().setExpandedParams(true);
+		s = new UrlEncodingSerializerBuilder().expandedParams(true).build();
 		r = s.serialize(t);
 		e = ""
 			+ "f01=a&f01=b"
@@ -404,7 +404,7 @@ public class UrlEncodingSerializerTest {
 			+ "&f20=@((a=a,b=1,c=true))&f20=@((a=a,b=1,c=true))";
 		assertEquals(e, r);
 
-		s = UrlEncodingSerializer.DEFAULT.clone().setExpandedParams(true);
+		s = new UrlEncodingSerializerBuilder().expandedParams(true).build();
 		r = s.serialize(t);
 		e = ""
 			+ "f01=a&f01=b"

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoQueryTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
index 5f451fd..c73d51a 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoQueryTest.java
@@ -87,7 +87,7 @@ public class PojoQueryTest {
 		int limit = 0;
 		boolean ignoreCase = false;
 		BeanSession session = BeanContext.DEFAULT.createSession();
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(CalendarSwap.DateTimeSimple.class);
+		WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(CalendarSwap.DateTimeSimple.class).build();
 		B[] in;
 		PojoQuery filter;
 
@@ -603,7 +603,7 @@ public class PojoQueryTest {
 		int limit = 0;
 		boolean ignoreCase = false;
 		BeanSession session = BeanContext.DEFAULT.createSession();
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(CalendarSwap.DateTimeSimple.class);
+		WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(CalendarSwap.DateTimeSimple.class).build();
 		List results;
 
 		I[] in = new I[] {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
index be25076..f274435 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/PojoRestTest.java
@@ -71,7 +71,7 @@ public class PojoRestTest {
 		model.put("/person1", p);
 
 		// Make sure it got stored correctly.
-		JsonSerializer serializer = JsonSerializer.DEFAULT_LAX.clone().setAddBeanTypeProperties(false);
+		JsonSerializer serializer = new JsonSerializerBuilder().simple().addBeanTypeProperties(false).build();
 		assertEquals("{person1:{name:'some name',age:123,addresses:[{street:'street A',city:'city A',state:'state A',zip:12345,isCurrent:true},{street:'street B',city:'city B',state:'state B',zip:12345,isCurrent:false}]}}", serializer.serialize(model.getRootObject()));
 
 		// Get the original Person object back.
@@ -82,7 +82,7 @@ public class PojoRestTest {
 		Address a3 = (Address)model.get("/person1/addresses/1");
 		assertEquals("city B", a3.city);
 
-		serializer = new JsonSerializer.Simple();
+		serializer = JsonSerializer.DEFAULT_LAX;
 		p = new Person("some name", 123,
 			new Address("street A", "city A", "state A", 12345, true),
 			new Address("street B", "city B", "state B", 12345, false)
@@ -94,7 +94,7 @@ public class PojoRestTest {
 		assertEquals(expectedValue, s);
 
 		// Parse it back to Java objects.
-		p = (Person)JsonParser.DEFAULT.clone().addToBeanDictionary(Person.class).parse(s, Object.class);
+		p = (Person)new JsonParserBuilder().beanDictionary(Person.class).build().parse(s, Object.class);
 		expectedValue = "city B";
 		s = p.addresses[1].city;
 		assertEquals(expectedValue, s);
@@ -115,7 +115,7 @@ public class PojoRestTest {
 		model.put("addresses/0", new Address("street D", "city D", "state D", 12345, false));
 		model.put("addresses/1", new Address("street E", "city E", "state E", 12345, false));
 		model.put("addresses/2", new Address("street F", "city F", "state F", 12345, false));
-		serializer = JsonSerializer.DEFAULT_LAX.clone().setAddBeanTypeProperties(false);
+		serializer = new JsonSerializerBuilder().simple().addBeanTypeProperties(false).build();
 		s = serializer.serialize(p);
 		expectedValue = "{name:'some name',age:123,addresses:[{street:'street D',city:'city D',state:'state D',zip:12345,isCurrent:false},{street:'street E',city:'city E',state:'state E',zip:12345,isCurrent:false},{street:'street F',city:'city F',state:'state F',zip:12345,isCurrent:false}]}";
 		assertEquals(expectedValue, s);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
index 5adc446..95c340b 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringUtilsTest.java
@@ -638,7 +638,7 @@ public class StringUtilsTest {
 	//====================================================================================================
 	@Test
 	public void testParseISO8601Date() throws Exception {
-		WriterSerializer s = new JsonSerializer.Simple().addPojoSwaps(DateSwap.ISO8601DTPZ.class).setTimeZone(TimeZone.getTimeZone("GMT"));
+		WriterSerializer s = new JsonSerializerBuilder().simple().pojoSwaps(DateSwap.ISO8601DTPZ.class).timeZone(TimeZone.getTimeZone("GMT")).build();
 
 		assertNull(parseISO8601Date(null));
 		assertNull(parseISO8601Date(""));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java
index 9cc91ff..122dbd6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/utils/StringVarResolverTest.java
@@ -26,7 +26,7 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		VarResolver vr = new VarResolver().addVars(XVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(XVar.class).build();
 		String t;
 
 		t = null;
@@ -99,7 +99,7 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void test2() throws Exception {
-		VarResolver vr = new VarResolver().addVars(BlankVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(BlankVar.class).build();
 		String t;
 
 		t = "${y}";
@@ -130,7 +130,7 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void testEscaped$() throws Exception {
-		VarResolver vr = new VarResolver().addVars(BlankVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(BlankVar.class).build();
 		String t;
 
 		t = "${y}";
@@ -151,7 +151,7 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void testEscapedSequences() throws Exception {
-		VarResolver vr = new VarResolver().addVars(XVar.class);
+		VarResolver vr = new VarResolverBuilder().vars(XVar.class).build();
 		String t;
 		char b = '\\';
 
@@ -191,15 +191,15 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void testParent() throws Exception {
-		VarResolver svr = VarResolver.DEFAULT.clone().addVars(XMultipartVar.class);
+		VarResolver vr = new VarResolverBuilder().defaultVars().vars(XMultipartVar.class).build();
 		String t;
 		System.setProperty("a", "a1");
 		System.setProperty("b", "b1");
 
 		t = "$X{$S{a},$S{b}}";
-		assertEquals("a1+b1", svr.resolve(t));
+		assertEquals("a1+b1", vr.resolve(t));
 		t = "$X{$S{a}}";
-		assertEquals("a1", svr.resolve(t));
+		assertEquals("a1", vr.resolve(t));
 	}
 
 	public static class XMultipartVar extends MultipartVar {
@@ -217,72 +217,76 @@ public class StringVarResolverTest {
 	//====================================================================================================
 	@Test
 	public void testFalseTriggers() throws Exception {
-		VarResolver svr = VarResolver.DEFAULT.clone();
+		VarResolverBuilder vrb = new VarResolverBuilder().defaultVars();
 		String in = null;
 
 		// Should reject names with characters outside A-Za-z
 		for (Class<?> c : new Class[]{InvalidVar1.class, InvalidVar2.class, InvalidVar3.class, InvalidVar4.class, InvalidVar5.class}) {
 			try {
-				svr.addVars(c);
+				vrb.vars(c);
 				fail();
 			} catch (IllegalArgumentException e) {
 				assertEquals("Invalid var name.  Must consist of only uppercase and lowercase ASCII letters.", e.getLocalizedMessage());
 			}
 		}
 
+		VarResolver vr = vrb.build();
+		
 		// These should all be unchanged.
 		in = "$@{foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "$[{foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "$`{foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "$|{foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "${{foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "${$foobar}";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 
 		System.setProperty("foobar", "baz");
 
 		in = "$";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 
 		in = "$S";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 
 		in = "$S{";
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 
 		in = "$S{foobar";
 
-		assertEquals(in, svr.resolve(in));
+		assertEquals(in, vr.resolve(in));
 		in = "$S{foobar}$";
-		assertEquals("baz$", svr.resolve(in));
+		assertEquals("baz$", vr.resolve(in));
 
 		in = "$S{foobar}$S";
-		assertEquals("baz$S", svr.resolve(in));
+		assertEquals("baz$S", vr.resolve(in));
 
 		in = "$S{foobar}$S{";
-		assertEquals("baz$S{", svr.resolve(in));
+		assertEquals("baz$S{", vr.resolve(in));
 
 		in = "$S{foobar}$S{foobar";
-		assertEquals("baz$S{foobar", svr.resolve(in));
+		assertEquals("baz$S{foobar", vr.resolve(in));
 
 		System.clearProperty("foobar");
 		in = "$S{foobar}";
 
 		// Test nulls returned by StringVar.
 		// Should be converted to blanks.
-		svr.addVars(AlwaysNullVar.class);
+		vrb.vars(AlwaysNullVar.class);
 
+		vr = vrb.build();
+		
 		in = "$A{xxx}";
-		assertEquals("", svr.resolve(in));
+		assertEquals("", vr.resolve(in));
 		in = "x$A{xxx}";
-		assertEquals("x", svr.resolve(in));
+		assertEquals("x", vr.resolve(in));
 		in = "$A{xxx}x";
-		assertEquals("x", svr.resolve(in));
+		assertEquals("x", vr.resolve(in));
 	}
 
 	public static class AlwaysNullVar extends SimpleVar {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
index 68265db..6c06dc3 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonParserTest.java
@@ -103,7 +103,7 @@ public class CommonParserTest {
 	//====================================================================================================
 	@Test
 	public void testCorrectHandlingOfUnknownProperties() throws Exception {
-		ReaderParser p = new XmlParser().setIgnoreUnknownBeanProperties(true);
+		ReaderParser p = new XmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		B t;
 
 		String in =  "<object><a>1</a><unknown>foo</unknown><b>2</b></object>";
@@ -118,7 +118,7 @@ public class CommonParserTest {
 
 
 		try {
-			p = new XmlParser();
+			p = XmlParser.DEFAULT;
 			p.parse(in, B.class);
 			fail("Exception expected");
 		} catch (ParseException e) {}
@@ -159,7 +159,7 @@ public class CommonParserTest {
 	@Test
 	public void testParserListeners() throws Exception {
 		final List<String> events = new LinkedList<String>();
-		XmlParser p = new XmlParser().setIgnoreUnknownBeanProperties(true);
+		XmlParser p = new XmlParserBuilder().ignoreUnknownBeanProperties(true).build();
 		p.addListener(
 			new ParserListener() {
 				@Override /* ParserListener */

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java
index 764847a..240b2e4 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonTest.java
@@ -23,7 +23,6 @@ import java.util.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.jena.annotation.*;
-import org.apache.juneau.serializer.*;
 import org.apache.juneau.testbeans.*;
 import org.apache.juneau.xml.annotation.*;
 import org.junit.*;
@@ -36,18 +35,18 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimNullsFromBeans() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
-		XmlParser p = new XmlParser();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
+		XmlParser p = XmlParser.DEFAULT;
 		A t1 = A.create(), t2;
 
-		s.setTrimNullProperties(false);
-		String r = s.serialize(t1);
+		s.trimNullProperties(false);
+		String r = s.build().serialize(t1);
 		assertEquals("<object><s1 _type='null'/><s2>s2</s2></object>", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimNullProperties(true);
-		r = s.serialize(t1);
+		s.trimNullProperties(true);
+		r = s.build().serialize(t1);
 		assertEquals("<object><s2>s2</s2></object>", r);
 		t2 = p.parse(r, A.class);
 		assertEqualObjects(t1, t2);
@@ -68,19 +67,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyMaps() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 		B t1 = B.create(), t2;
 		String r;
 
-		s.setTrimEmptyMaps(false);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(false);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f1/><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r);
 		t2 = p.parse(r, B.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyMaps(true);
-		r = s.serialize(t1);
+		s.trimEmptyMaps(true);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f2><f2a _type='null'/><f2b><s2>s2</s2></f2b></f2></object>", r);
 		t2 = p.parse(r, B.class);
 		assertNull(t2.f1);
@@ -102,19 +101,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyLists() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 		C t1 = C.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r);
 		t2 = p.parse(r, C.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r);
 		t2 = p.parse(r, C.class);
 		assertNull(t2.f1);
@@ -136,19 +135,19 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testTrimEmptyArrays() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 		D t1 = D.create(), t2;
 		String r;
 
-		s.setTrimEmptyCollections(false);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(false);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f1></f1><f2><null/><object><s2>s2</s2></object></f2></object>", r);
 		t2 = p.parse(r, D.class);
 		assertEqualObjects(t1, t2);
 
-		s.setTrimEmptyCollections(true);
-		r = s.serialize(t1);
+		s.trimEmptyCollections(true);
+		r = s.build().serialize(t1);
 		assertEquals("<object><f2><null/><object><s2>s2</s2></object></f2></object>", r);
 		t2 = p.parse(r, D.class);
 		assertNull(t2.f1);
@@ -258,13 +257,13 @@ public class CommonTest {
 	//====================================================================================================
 	@Test
 	public void testUris() throws Exception {
-		WriterSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		TestURI t = new TestURI();
 		String r;
 		String expected;
 
-		s.setRelativeUriBase(null);
-		r = s.serialize(t);
+		s.relativeUriBase(null);
+		r = s.build().serialize(t);
 		expected = ""
 			+"<object f0='f0/x0'>"
 			+"<f1>f1/x1</f1>"
@@ -284,12 +283,12 @@ public class CommonTest {
 			+"</object>";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.relativeUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr");
-		r = s.serialize(t);
+		s.relativeUriBase("/cr");
+		r = s.build().serialize(t);
 		expected = ""
 			+"<object f0='/cr/f0/x0'>"
 			+"<f1>/cr/f1/x1</f1>"
@@ -309,12 +308,12 @@ public class CommonTest {
 			+"</object>";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/cr/");  // Same as above
-		r = s.serialize(t);
+		s.relativeUriBase("/cr/");  // Same as above
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase("/");
-		r = s.serialize(t);
+		s.relativeUriBase("/");
+		r = s.build().serialize(t);
 		expected = ""
 			+"<object f0='/f0/x0'>"
 			+"<f1>/f1/x1</f1>"
@@ -334,10 +333,10 @@ public class CommonTest {
 			+"</object>";
 		assertEquals(expected, r);
 
-		s.setRelativeUriBase(null);
+		s.relativeUriBase(null);
 
-		s.setAbsolutePathUriBase("http://foo");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo");
+		r = s.build().serialize(t);
 		expected = ""
 			+"<object f0='f0/x0'>"
 			+"<f1>f1/x1</f1>"
@@ -357,12 +356,12 @@ public class CommonTest {
 			+"</object>";
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("http://foo/");
-		r = s.serialize(t);
+		s.absolutePathUriBase("http://foo/");
+		r = s.build().serialize(t);
 		assertEquals(expected, r);
 
-		s.setAbsolutePathUriBase("");  // Same as null.
-		r = s.serialize(t);
+		s.absolutePathUriBase("");  // Same as null.
+		r = s.build().serialize(t);
 		expected = ""
 			+"<object f0='f0/x0'>"
 			+"<f1>f1/x1</f1>"
@@ -384,31 +383,11 @@ public class CommonTest {
 	}
 
 	//====================================================================================================
-	// Validate that you cannot update properties on locked serializer.
-	//====================================================================================================
-	@Test
-	public void testLockedSerializer() throws Exception {
-		XmlSerializer s = new XmlSerializer().lock();
-		try {
-			s.setEnableNamespaces(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setAddBeanTypeProperties(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-		try {
-			s.setBeanMapPutReturnsOldValue(true);
-			fail("Locked exception not thrown");
-		} catch (LockedException e) {}
-	}
-
-	//====================================================================================================
 	// Recursion
 	//====================================================================================================
 	@Test
 	public void testRecursion() throws Exception {
-		XmlSerializer s = new XmlSerializer().setEnableNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().enableNamespaces(false);
 
 		R1 r1 = new R1();
 		R2 r2 = new R2();
@@ -419,7 +398,7 @@ public class CommonTest {
 
 		// No recursion detection
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -427,9 +406,9 @@ public class CommonTest {
 		}
 
 		// Recursion detection, no ignore
-		s.setDetectRecursions(true);
+		s.detectRecursions(true);
 		try {
-			s.serialize(r1);
+			s.build().serialize(r1);
 			fail("Exception expected!");
 		} catch (Exception e) {
 			String msg = e.getLocalizedMessage();
@@ -439,11 +418,11 @@ public class CommonTest {
 			assertTrue(msg.contains("->[3]r1:org.apache.juneau.xml.CommonTest$R1"));
 		}
 
-		s.setIgnoreRecursions(true);
-		assertEquals("<object><name>foo</name><r2><name>bar</name><r3><name>baz</name></r3></r2></object>", s.serialize(r1));
+		s.ignoreRecursions(true);
+		assertEquals("<object><name>foo</name><r2><name>bar</name><r3><name>baz</name></r3></r2></object>", s.build().serialize(r1));
 
 		// Make sure this doesn't blow up.
-		s.getSchemaSerializer().serialize(r1);
+		s.build().getSchemaSerializer().serialize(r1);
 	}
 
 	public static class R1 {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java
index 996a6cf..031a879 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/CommonXmlTest.java
@@ -61,7 +61,7 @@ public class CommonXmlTest {
 	//====================================================================================================
 	@Test
 	public void testBeanUriAnnotationOnlyUriProperty() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAddNamespaceUrisToRoot(false);
+		XmlSerializer s = new XmlSerializerBuilder().sq().addNamespaceUrisToRoot(false).build();
 
 		B t = new B("http://foo");
 		String xml = s.serialize(t);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java
index e11fe18..6f0738e 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlContentTest.java
@@ -34,7 +34,7 @@ public class XmlContentTest {
 	public void testContentFormat() throws Exception {
 		A t = A.newInstance(), t2;
 		XmlSerializer s1 = XmlSerializer.DEFAULT_SQ,
-			s2 = new XmlSerializer().setQuoteChar('\'').setUseWhitespace(true).setEnableNamespaces(false);
+			s2 = new XmlSerializerBuilder().sq().ws().enableNamespaces(false).build();
 		XmlParser p = XmlParser.DEFAULT;
 		XmlSerializerSession session;
 		String r;
@@ -142,7 +142,7 @@ public class XmlContentTest {
 	public void testXmlMixed() throws Exception {
 		B t = B.newInstance(), t2;
 		XmlSerializer s1 = XmlSerializer.DEFAULT_SQ,
-			s2 = new XmlSerializer().setQuoteChar('\'').setUseWhitespace(true).setEnableNamespaces(false);
+			s2 = new XmlSerializerBuilder().sq().ws().enableNamespaces(false).build();
 		XmlParser p = XmlParser.DEFAULT;
 		XmlSerializerSession session;
 		String r;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlParserTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlParserTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlParserTest.java
index 64ca1c3..9e1f571 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlParserTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlParserTest.java
@@ -82,7 +82,7 @@ public class XmlParserTest {
 	public void testPreserveRootElement() throws Exception {
 		String xml;
 		ObjectMap m;
-		ReaderParser p = new XmlParser().setPreserveRootElement(true);
+		ReaderParser p = new XmlParserBuilder().preserveRootElement(true).build();
 
 		xml = "<A><B><C>c</C></B></A>";
 		m = p.parse(xml, ObjectMap.class);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTest.java b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTest.java
index d7ece92..555ca49 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/xml/XmlTest.java
@@ -77,12 +77,13 @@ public class XmlTest {
 			+"</object>\n";
 
 		ObjectMap m = (ObjectMap) XmlParser.DEFAULT.parse(xml1, Object.class);
-		String json2 = new JsonSerializer.SimpleReadable().setQuoteChar('"').setTrimNullProperties(false).serialize(m);
+		String json2 = new JsonSerializerBuilder().simple().ws().quoteChar('"').trimNullProperties(false).build().serialize(m);
 		assertEquals(json1, json2);
 
 		m = (ObjectMap) JsonParser.DEFAULT.parse(json1, Object.class);
-		String xml2 = new XmlSerializer.SqReadable()
-			.setTrimNullProperties(false)
+		String xml2 = new XmlSerializerBuilder().sq().ws()
+			.trimNullProperties(false)
+			.build()
 			.serialize(m);
 		assertEquals(xml1, xml2);
 	}
@@ -132,10 +133,11 @@ public class XmlTest {
 			+"</object>\n";
 
 		ObjectMap m = (ObjectMap) JsonParser.DEFAULT.parse(json1, Object.class);
-		String r = new XmlSerializer.NsSqReadable()
-			.setAddNamespaceUrisToRoot(true)
-			.setDefaultNamespace("http://www.apache.org")
-			.setTrimNullProperties(false)
+		String r = new XmlSerializerBuilder().ns().sq().ws()
+			.addNamespaceUrisToRoot(true)
+			.defaultNamespace("http://www.apache.org")
+			.trimNullProperties(false)
+			.build()
 			.serialize(m);
 		assertEquals(xml1, r);
 	}
@@ -351,21 +353,21 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testXmlFormatAttrWithNs() throws Exception {
-		XmlSerializer s = XmlSerializer.DEFAULT_SQ.clone();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 		M t = new M();
 		String r = null;
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object f1='1' f2='2' f3='3'/>", r);
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(true).setAutoDetectNamespaces(true).setTrimNullProperties(false);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(true).autoDetectNamespaces(true).trimNullProperties(false);
 		t.f1 = 4; t.f2 = 5; t.f3 = 6;
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:bar='http://bar' xmlns:foo='http://foo' xmlns:baz='http://baz' bar:f1='4' foo:f2='5' baz:f3='6'/>", r);
 		t = p.parse(r, M.class);
 		assertEquals(4, t.f1);
 		assertEquals(5, t.f2);
 		assertEquals(6, t.f3);
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	@Xml(prefix="bar", namespace="http://bar")
@@ -519,51 +521,51 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnClass() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T1 t = new T1();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T1.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T1.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T1.class)));
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T1.class)));
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.enableNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T1.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -571,49 +573,49 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnClassWithElementName() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T2 t = new T2();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<T2><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T2>", r);
 		assertTrue(t.equals(p.parse(r, T2.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T2><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T2>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T2 xmlns='http://www.apache.org/2013/Juneau'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T2>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T2 xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T2>", r);
 		assertTrue(t.equals(p.parse(r, T2.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<T2><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T2>", r);
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<T2><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T2>", r);
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.enableNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T2 xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T2>", r);
 		assertTrue(t.equals(p.parse(r, T2.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 
@@ -622,51 +624,51 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnPackageNoNsOnClass() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 
 		T3 t = new T3();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T3.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true).setAutoDetectNamespaces(false);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true).autoDetectNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Manually set namespaces
-		s.setAutoDetectNamespaces(false);
-		s.setNamespaces(
+		s.autoDetectNamespaces(false);
+		s.namespaces(
 			NamespaceFactory.get("p1","http://p1"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:p1='http://p1' xmlns:bar='http://bar' xmlns:baz='http://baz'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T3.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.enableNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:p1='http://p1' xmlns:bar='http://bar' xmlns:baz='http://baz'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T3.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -674,50 +676,50 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnPackageNoNsOnClassElementNameOnClass() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T4 t = new T4();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<T4><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T4>", r);
 		assertTrue(t.equals(p.parse(r, T4.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<p1:T4><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></p1:T4>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<p1:T4 xmlns='http://www.apache.org/2013/Juneau'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></p1:T4>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz"),
 			NamespaceFactory.get("p1","http://p1")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<p1:T4 xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz' xmlns:p1='http://p1'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></p1:T4>", r);
 		assertTrue(t.equals(p.parse(r, T4.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<T4><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T4>", r);
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<T4><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T4>", r);
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.enableNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<p1:T4 xmlns='http://www.apache.org/2013/Juneau' xmlns:p1='http://p1' xmlns:bar='http://bar' xmlns:baz='http://baz'><p1:f1>1</p1:f1><bar:f2>2</bar:f2><p1:f3>3</p1:f3><baz:f4>4</baz:f4></p1:T4>", r);
 		assertTrue(t.equals(p.parse(r, T4.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -725,52 +727,52 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnPackageNsOnClassElementNameOnClass() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 
 		T5 t = new T5();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<T5><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T5>", r);
 		assertTrue(t.equals(p.parse(r, T5.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false).setAutoDetectNamespaces(false);
-		r = s.serialize(t);
+		s.ns().addNamespaceUrisToRoot(false).autoDetectNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T5><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T5>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T5 xmlns='http://www.apache.org/2013/Juneau'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T5>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<foo:T5 xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T5>", r);
 		assertTrue(t.equals(p.parse(r, T5.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<T5><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T5>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<T5><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></T5>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.ns();
+		r = s.build().serialize(t);
 		assertEquals("<foo:T5 xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></foo:T5>", r);
 		assertTrue(t.equals(p.parse(r, T5.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -778,51 +780,51 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testNsOnPackageNsOnClassNoElementNameOnClass() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T6 t = new T6();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T6.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.ns().addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true).setAutoDetectNamespaces(false);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true).autoDetectNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T6.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.ns();
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><foo:f1>1</foo:f1><bar:f2>2</bar:f2><foo:f3>3</foo:f3><baz:f4>4</baz:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T6.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -830,49 +832,49 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testComboOfNsAndOverriddenBeanPropertyNames() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T7 t = new T7();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><g1>1</g1><g2>2</g2><g3>3</g3><g4>4</g4></object>", r);
 		assertTrue(t.equals(p.parse(r, T7.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.enableNamespaces(true).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><p1:g1>1</p1:g1><bar:g2>2</bar:g2><p1:g3>3</p1:g3><baz:g4>4</baz:g4></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true).setAutoDetectNamespaces(false);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true).autoDetectNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><p1:g1>1</p1:g1><bar:g2>2</bar:g2><p1:g3>3</p1:g3><baz:g4>4</baz:g4></object>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz"),
 			NamespaceFactory.get("p1","http://p1")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz' xmlns:p1='http://p1'><p1:g1>1</p1:g1><bar:g2>2</bar:g2><p1:g3>3</p1:g3><baz:g4>4</baz:g4></object>", r);
 		assertTrue(t.equals(p.parse(r, T7.class)));
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><g1>1</g1><g2>2</g2><g3>3</g3><g4>4</g4></object>", r);
 
-		s.setEnableNamespaces(false);
-		r = s.serialize(t);
+		s.enableNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><g1>1</g1><g2>2</g2><g3>3</g3><g4>4</g4></object>", r);
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.ns().addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:p1='http://p1' xmlns:bar='http://bar' xmlns:baz='http://baz'><p1:g1>1</p1:g1><bar:g2>2</bar:g2><p1:g3>3</p1:g3><baz:g4>4</baz:g4></object>", r);
 		assertTrue(t.equals(p.parse(r, T7.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -880,50 +882,50 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testXmlNsAnnotation() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T8 t = new T8();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T8.class)));
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(false).setAutoDetectNamespaces(false);
-		r = s.serialize(t);
+		s.ns().addNamespaceUrisToRoot(false).autoDetectNamespaces(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><p2:f1>1</p2:f1><p1:f2>2</p1:f2><c1:f3>3</c1:f3><f1:f4>4</f1:f4></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><p2:f1>1</p2:f1><p1:f2>2</p1:f2><c1:f3>3</c1:f3><f1:f4>4</f1:f4></object>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><p2:f1>1</p2:f1><p1:f2>2</p1:f2><c1:f3>3</c1:f3><f1:f4>4</f1:f4></object>", r);
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T8.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1><f2>2</f2><f3>3</f3><f4>4</f4></object>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.ns();
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:p2='http://p2' xmlns:p1='http://p1' xmlns:c1='http://c1' xmlns:f1='http://f1'><p2:f1>1</p2:f1><p1:f2>2</p1:f2><c1:f3>3</c1:f3><f1:f4>4</f1:f4></object>", r);
 		assertTrue(t.equals(p.parse(r, T8.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -931,50 +933,50 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testXmlNsOnPackageNsUriInXmlNs() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq().setAutoDetectNamespaces(false);
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq().autoDetectNamespaces(false);
 		XmlParser p = XmlParser.DEFAULT;
 
 		T9 t = new T9();
-		String r = s.serialize(t);
+		String r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1></object>", r);
 		assertTrue(t.equals(p.parse(r, T9.class)));
 
-		s.setEnableNamespaces(true).setAutoDetectNamespaces(false).setAddNamespaceUrisToRoot(false);
-		r = s.serialize(t);
+		s.ns().autoDetectNamespaces(false).addNamespaceUrisToRoot(false);
+		r = s.build().serialize(t);
 		assertEquals("<object><p1:f1>1</p1:f1></object>", r);
 
 		// Add namespace URIs to root, but don't auto-detect.
 		// Only xsi should be added to root.
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau'><p1:f1>1</p1:f1></object>", r);
 
 		// Manually set namespaces
-		s.setNamespaces(
+		s.namespaces(
 			NamespaceFactory.get("foo","http://foo"),
 			NamespaceFactory.get("bar","http://bar"),
 			NamespaceFactory.get("baz","http://baz")
 		);
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:foo='http://foo' xmlns:bar='http://bar' xmlns:baz='http://baz'><p1:f1>1</p1:f1></object>", r);
 
 		// Auto-detect namespaces.
-		s = new XmlSerializer.Sq().setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s = new XmlSerializerBuilder().sq().autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1></object>", r);
 		assertTrue(t.equals(p.parse(r, T9.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setAddNamespaceUrisToRoot(true);
-		r = s.serialize(t);
+		s.addNamespaceUrisToRoot(true);
+		r = s.build().serialize(t);
 		assertEquals("<object><f1>1</f1></object>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
-		s.setEnableNamespaces(true);
-		r = s.serialize(t);
+		s.ns();
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:p1='http://p1'><p1:f1>1</p1:f1></object>", r);
 		assertTrue(t.equals(p.parse(r, T9.class)));
-		validateXml(t, s);
+		validateXml(t, s.build());
 	}
 
 	//====================================================================================================
@@ -982,7 +984,7 @@ public class XmlTest {
 	//====================================================================================================
 	@Test
 	public void testXmlAttrs() throws Exception {
-		XmlSerializer s = new XmlSerializer.Sq();
+		XmlSerializerBuilder s = new XmlSerializerBuilder().sq();
 		XmlParser p = XmlParser.DEFAULT;
 		String r;
 
@@ -990,17 +992,17 @@ public class XmlTest {
 		t.f1 = new URL("http://xf1");
 		t.f2 = "xf2";
 		t.f3 = "xf3";
-		r = s.serialize(t);
+		r = s.build().serialize(t);
 		assertEquals("<object f1='http://xf1' f2='xf2' x3='xf3'/>", r);
 		t = p.parse(r, Q.class);
 		assertEquals("http://xf1", t.f1.toString());
 		assertEquals("xf2", t.f2);
 		assertEquals("xf3", t.f3);
 
-		s.setEnableNamespaces(true).setAddNamespaceUrisToRoot(true).setAutoDetectNamespaces(true);
-		r = s.serialize(t);
+		s.ns().addNamespaceUrisToRoot(true).autoDetectNamespaces(true);
+		r = s.build().serialize(t);
 		assertEquals("<object xmlns='http://www.apache.org/2013/Juneau' xmlns:ns='http://ns' xmlns:nsf1='http://nsf1' xmlns:nsf3='http://nsf3' nsf1:f1='http://xf1' ns:f2='xf2' nsf3:x3='xf3'/>", r);
-		validateXml(t, s);
+		validateXml(t, s.build());
 
 		t = p.parse(r, Q.class);
 		assertEquals("http://xf1", t.f1.toString());

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/.gitignore
----------------------------------------------------------------------
diff --git a/juneau-core/.gitignore b/juneau-core/.gitignore
index ac0418c..1401e35 100644
--- a/juneau-core/.gitignore
+++ b/juneau-core/.gitignore
@@ -2,3 +2,4 @@
 /.DS_Store
 /.settings/
 /.classpath
+/TODO.txt

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/.DS_Store
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/.DS_Store b/juneau-core/src/main/java/org/apache/juneau/.DS_Store
new file mode 100644
index 0000000..5008ddf
Binary files /dev/null and b/juneau-core/src/main/java/org/apache/juneau/.DS_Store differ

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
index 5c5d836..2a2f75a 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanContext.java
@@ -43,9 +43,9 @@ import org.apache.juneau.transform.*;
  * All serializer and parser contexts extend from this context.
  *
  * <h5 class='topic'>Bean Contexts</h5>
- * Bean contexts are created through the {@link ContextFactory#getContext(Class)} method.
+ * Bean contexts are created through the {@link PropertyStore#getContext(Class)} method.
  * These context objects are read-only, reusable, and thread-safe.
- * The {@link ContextFactory} class will typically cache copies of <code>Context</code> objects based on
+ * The {@link PropertyStore} class will typically cache copies of <code>Context</code> objects based on
  * 	the current settings on the factory.
  * <p>
  * Each bean context maintains a cache of {@link ClassMeta} objects that describe information about classes encountered.
@@ -74,20 +74,20 @@ import org.apache.juneau.transform.*;
  * <p>
  * Some settings (e.g. {@link BeanContext#BEAN_beanMapPutReturnsOldValue}) change the runtime behavior of bean maps.
  * <p>
- * Settings are specified using the {@link ContextFactory#setProperty(String, Object)} method and related convenience methods.
+ * Settings are specified using the {@link PropertyStore#setProperty(String, Object)} method and related convenience methods.
  *
  * <h5 class='section'>Example:</h5>
  * <p class='bcode'>
  * 	<jc>// Construct a context from scratch.</jc>
- * 	BeanContext beanContext = ContextFactory.<jsm>create</jsm>()
- * 		.setProperty(BeanContext.<jsf>BEAN_beansRequireDefaultConstructor</jsf>, <jk>true</jk>)
- * 		.addNotBeanClasses(Foo.<jk>class</jk>)
+ * 	BeanContext beanContext = PropertyStore.<jsm>create</jsm>()
+ * 		.property(BeanContext.<jsf>BEAN_beansRequireDefaultConstructor</jsf>, <jk>true</jk>)
+ * 		.notBeanClasses(Foo.<jk>class</jk>)
  * 		.getBeanContext();
  *
- * 	<jc>// Clone an existing context factory.</jc>
- * 	BeanContext beanContext = ContextFactory.<jsm>create</jsm>(otherConfig)
- * 		.setProperty(BeanContext.<jsf>BEAN_beansRequireDefaultConstructor</jsf>, <jk>true</jk>)
- * 		.addNotBeanClasses(Foo.<jk>class</jk>)
+ * 	<jc>// Clone an existing property store.</jc>
+ * 	BeanContext beanContext = PropertyStore.<jsm>create</jsm>(otherConfig)
+ * 		.property(BeanContext.<jsf>BEAN_beansRequireDefaultConstructor</jsf>, <jk>true</jk>)
+ * 		.notBeanClasses(Foo.<jk>class</jk>)
  * 		.getBeanContext();
  * </p>
  *
@@ -761,7 +761,7 @@ public class BeanContext extends Context {
 	};
 
 
-	static final void loadDefaults(ContextFactory config) {
+	static final void loadDefaults(PropertyStore config) {
 		config.setProperty(BEAN_notBeanPackages, DEFAULT_NOTBEAN_PACKAGES);
 		config.setProperty(BEAN_notBeanClasses, DEFAULT_NOTBEAN_CLASSES);
 	}
@@ -775,10 +775,10 @@ public class BeanContext extends Context {
 	private static final ConcurrentHashMap<Integer,Map<Class,ClassMeta>> cmCacheCache = new ConcurrentHashMap<Integer,Map<Class,ClassMeta>>();
 
 	/** Default config.  All default settings. */
-	public static final BeanContext DEFAULT = ContextFactory.create().getContext(BeanContext.class);
+	public static final BeanContext DEFAULT = PropertyStore.create().getContext(BeanContext.class);
 
 	/** Default config.  All default settings except sort bean properties. */
-	public static final BeanContext DEFAULT_SORTED = ContextFactory.create().setProperty(BEAN_sortProperties, true).getContext(BeanContext.class);
+	public static final BeanContext DEFAULT_SORTED = PropertyStore.create().setProperty(BEAN_sortProperties, true).getContext(BeanContext.class);
 
 	final boolean
 		beansRequireDefaultConstructor,
@@ -829,17 +829,17 @@ public class BeanContext extends Context {
 	/**
 	 * Constructor.
 	 * <p>
-	 * Typically only called from {@link ContextFactory#getContext(Class)} or {@link ContextFactory#getBeanContext()}.
+	 * Typically only called from {@link PropertyStore#getContext(Class)} or {@link PropertyStore#getBeanContext()}.
 	 *
-	 * @param cf The factory that created this context.
+	 * @param ps The property store that created this context.
 	 */
-	public BeanContext(ContextFactory cf) {
-		super(cf);
+	public BeanContext(PropertyStore ps) {
+		super(ps);
 
-		ContextFactory.PropertyMap pm = cf.getPropertyMap("BeanContext");
+		PropertyStore.PropertyMap pm = ps.getPropertyMap("BeanContext");
 		hashCode = pm.hashCode();
-		classLoader = cf.classLoader;
-		defaultParser = cf.defaultParser;
+		classLoader = ps.classLoader;
+		defaultParser = ps.defaultParser;
 
 		beansRequireDefaultConstructor = pm.get(BEAN_beansRequireDefaultConstructor, boolean.class, false);
 		beansRequireSerializable = pm.get(BEAN_beansRequireSerializable, boolean.class, false);
@@ -855,7 +855,7 @@ public class BeanContext extends Context {
 		useJavaBeanIntrospector = pm.get(BEAN_useJavaBeanIntrospector, boolean.class, false);
 		sortProperties = pm.get(BEAN_sortProperties, boolean.class, false);
 		beanTypePropertyName = pm.get(BEAN_beanTypePropertyName, String.class, "_type");
-		debug = cf.getProperty(BEAN_debug, boolean.class, false);
+		debug = ps.getProperty(BEAN_debug, boolean.class, false);
 
 		beanConstructorVisibility = pm.get(BEAN_beanConstructorVisibility, Visibility.class, PUBLIC);
 		beanClassVisibility = pm.get(BEAN_beanClassVisibility, Visibility.class, PUBLIC);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
index 009ce2f..ed57429 100644
--- a/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
+++ b/juneau-core/src/main/java/org/apache/juneau/BeanMap.java
@@ -176,7 +176,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 	 * 	Person p = <jk>new</jk> Person();
 	 *
 	 * 	<jc>// Create a bean context and add the ISO8601 date-time swap</jc>
-	 * 	BeanContext beanContext = <jk>new</jk> BeanContext().addPojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
+	 * 	BeanContext beanContext = <jk>new</jk> BeanContext().pojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
 	 *
 	 * 	<jc>// Wrap our bean in a bean map</jc>
 	 * 	BeanMap&lt;Person&gt; b = beanContext.forBean(p);
@@ -251,7 +251,7 @@ public class BeanMap<T> extends AbstractMap<String,Object> implements Delegate<T
 	 * 	p.setBirthDate(<jk>new</jk> Date(1, 2, 3, 4, 5, 6));
 	 *
 	 * 	<jc>// Create a bean context and add the ISO8601 date-time swap</jc>
-	 * 	BeanContext beanContext = <jk>new</jk> BeanContext().addPojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
+	 * 	BeanContext beanContext = <jk>new</jk> BeanContext().pojoSwaps(DateSwap.ISO8601DT.<jk>class</jk>);
 	 *
 	 * 	<jc>// Wrap our bean in a bean map</jc>
 	 * 	BeanMap&lt;Person&gt; b = beanContext.forBean(p);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core/src/main/java/org/apache/juneau/Context.java
----------------------------------------------------------------------
diff --git a/juneau-core/src/main/java/org/apache/juneau/Context.java b/juneau-core/src/main/java/org/apache/juneau/Context.java
index 6005ee9..d6912e7 100644
--- a/juneau-core/src/main/java/org/apache/juneau/Context.java
+++ b/juneau-core/src/main/java/org/apache/juneau/Context.java
@@ -19,14 +19,14 @@ import org.apache.juneau.serializer.*;
 /**
  * A reusable stateless thread-safe read-only configuration, typically used for creating one-time use {@link Session} objects.
  * <p>
- * Contexts are created through the {@link ContextFactory#getContext(Class)} method.
+ * Contexts are created through the {@link PropertyStore#getContext(Class)} method.
  * <p>
- * Subclasses MUST implement a constructor method that takes in a {@link ContextFactory} parameter.
+ * Subclasses MUST implement a constructor method that takes in a {@link PropertyStore} parameter.
  * Besides that restriction, a context object can do anything you desire.  However, it MUST
  * 	be thread-safe and all fields should be declared final to prevent modification.
  * It should NOT be used for storing temporary or state information.
  *
- * @see ContextFactory
+ * @see PropertyStore
  */
 public abstract class Context {
 
@@ -35,9 +35,9 @@ public abstract class Context {
 	 * <p>
 	 * Subclasses MUST implement the same constructor.
 	 *
-	 * @param configFactory The factory that created this config.
+	 * @param propertyStore The factory that created this config.
 	 */
-	public Context(ContextFactory configFactory) {}
+	public Context(PropertyStore propertyStore) {}
 
 	/**
 	 * Returns the properties defined on this bean context as a simple map for debugging purposes.


[03/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
index eafefd4..0ca0557 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/GroupsResource.java
@@ -31,6 +31,11 @@ public class GroupsResource extends RestServlet {
 
 	@Produces("text/s1,text/s2")
 	public static class SSerializer extends WriterSerializer {
+
+		public SSerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object output) throws Exception {
 			session.getWriter().write("text/s," + output);
@@ -39,6 +44,11 @@ public class GroupsResource extends RestServlet {
 
 	@Consumes("text/p1,text/p2")
 	public static class PParser extends ReaderParser {
+
+		public PParser(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -48,13 +58,13 @@ public class GroupsResource extends RestServlet {
 
 
 	@Override /* RestServlet */
-	public SerializerGroup createSerializers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		return new SerializerGroup().append(SSerializer.class).setProperties(properties).addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
+	public SerializerGroupBuilder createSerializers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		return super.createSerializers(properties, beanFilters, pojoSwaps).append(SSerializer.class);
 	}
 
 	@Override /* RestServlet */
-	public ParserGroup createParsers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
-		return new ParserGroup().append(PParser.class).setProperties(properties).addBeanFilters(beanFilters).addPojoSwaps(pojoSwaps);
+	public ParserGroupBuilder createParsers(ObjectMap properties, Class<?>[] beanFilters, Class<?>[] pojoSwaps) throws Exception {
+		return super.createParsers(properties, beanFilters, pojoSwaps).append(PParser.class);
 	}
 
 	//====================================================================================================

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
index 0e41572..204860b 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/InheritanceResource.java
@@ -223,6 +223,11 @@ public class InheritanceResource extends RestServlet {
 	}
 
 	public static class DummyParser extends ReaderParser {
+
+		public DummyParser() {
+			super(PropertyStore.create());
+		}
+
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
 			return null;
@@ -230,6 +235,11 @@ public class InheritanceResource extends RestServlet {
 	}
 
 	public static class DummySerializer extends WriterSerializer {
+
+		public DummySerializer() {
+			super(PropertyStore.create());
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write(o.toString());
@@ -237,34 +247,34 @@ public class InheritanceResource extends RestServlet {
 	}
 
 	@Consumes("text/p1")
-	public static class P1 extends DummyParser{}
+	public static class P1 extends DummyParser{ public P1(PropertyStore ps) {super();} }
 
 	@Consumes("text/p2")
-	public static class P2 extends DummyParser{}
+	public static class P2 extends DummyParser{ public P2(PropertyStore ps) {super();} }
 
 	@Consumes("text/p3")
-	public static class P3 extends DummyParser{}
+	public static class P3 extends DummyParser{ public P3(PropertyStore ps) {super();} }
 
 	@Consumes("text/p4")
-	public static class P4 extends DummyParser{}
+	public static class P4 extends DummyParser{ public P4(PropertyStore ps) {super();} }
 
 	@Consumes("text/p5")
-	public static class P5 extends DummyParser{}
+	public static class P5 extends DummyParser{ public P5(PropertyStore ps) {super();} }
 
 	@Produces("text/s1")
-	public static class S1 extends DummySerializer{}
+	public static class S1 extends DummySerializer{ public S1(PropertyStore ps) {super();} }
 
 	@Produces("text/s2")
-	public static class S2 extends DummySerializer{}
+	public static class S2 extends DummySerializer{ public S2(PropertyStore ps) {super();} }
 
 	@Produces("text/s3")
-	public static class S3 extends DummySerializer{}
+	public static class S3 extends DummySerializer{ public S3(PropertyStore ps) {super();} }
 
 	@Produces("text/s4")
-	public static class S4 extends DummySerializer{}
+	public static class S4 extends DummySerializer{ public S4(PropertyStore ps) {super();} }
 
 	@Produces("text/s5")
-	public static class S5 extends DummySerializer{}
+	public static class S5 extends DummySerializer{ public S5(PropertyStore ps) {super();} }
 
 	public static class E1 extends IdentityEncoder {
 		@Override public String[] getCodings() {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
index a53055b..05093b9 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/NlsPropertyResource.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.test;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -53,6 +54,11 @@ public class NlsPropertyResource extends RestServlet {
 
 	@Produces("text/plain")
 	public static class TestSerializer extends WriterSerializer {
+
+		public TestSerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write(session.getProperties().getString("TestProperty"));

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
index 01add72..c18b5e3 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPostCallResource.java
@@ -37,6 +37,11 @@ public class OnPostCallResource extends RestServlet {
 
 	@Produces("text/s1,text/s2,text/s3")
 	public static class TestSerializer extends WriterSerializer {
+
+		public TestSerializer(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			ObjectMap p = session.getProperties();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java
index e2661cb..46e20a6 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/OnPreCallResource.java
@@ -39,6 +39,11 @@ public class OnPreCallResource extends RestServlet {
 
 	@Consumes("text/a1,text/a2,text/a3")
 	public static class TestParserA extends ReaderParser {
+
+		public TestParserA(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
index e3d0f48..e690d88 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParamsResource.java
@@ -13,7 +13,6 @@
 package org.apache.juneau.rest.test;
 
 import static org.apache.juneau.rest.RestServletContext.*;
-import static org.apache.juneau.urlencoding.UrlEncodingContext.*;
 
 import java.util.*;
 
@@ -26,6 +25,7 @@ import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.transforms.*;
+import org.apache.juneau.urlencoding.*;
 
 /**
  * JUnit automated testcase resource.
@@ -268,7 +268,7 @@ public class ParamsResource extends RestServletDefault {
 	//====================================================================================================
 	@RestMethod(name="POST", path="/testFormPostsWithMultiParamsUsingProperty",
 		properties={
-			@Property(name=URLENC_expandedParams, value="true")
+			@Property(name=UrlEncodingContext.URLENC_expandedParams, value="true")
 		}
 	)
 	public DTO2s.B testFormPostsWithMultiParamsViaProperty(@Body DTO2s.B content) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParsersResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParsersResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParsersResource.java
index c32c44b..3c6ddad 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParsersResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/ParsersResource.java
@@ -36,6 +36,11 @@ public class ParsersResource extends RestServletDefault {
 
 	@Consumes("text/a")
 	public static class TestParserA extends ReaderParser {
+
+		public TestParserA(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -61,6 +66,11 @@ public class ParsersResource extends RestServletDefault {
 
 	@Consumes("text/b")
 	public static class TestParserB extends ReaderParser {
+
+		public TestParserB(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -78,6 +88,11 @@ public class ParsersResource extends RestServletDefault {
 
 	@Consumes("text/c")
 	public static class TestParserC extends ReaderParser {
+
+		public TestParserC(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {
@@ -95,6 +110,11 @@ public class ParsersResource extends RestServletDefault {
 
 	@Consumes("text/a,text/d")
 	public static class TestParserD extends ReaderParser {
+
+		public TestParserD(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@SuppressWarnings("unchecked")
 		@Override /* Parser */
 		protected <T> T doParse(ParserSession session, ClassMeta<T> type) throws Exception {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
index ad60f37..ff41a3b 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/PropertiesResource.java
@@ -61,6 +61,11 @@ public class PropertiesResource extends RestServletDefault {
 
 	@Produces("application/json,text/json")
 	public static class PropertySerializer1 extends WriterSerializer {
+
+		public PropertySerializer1(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object output) throws Exception {
 			ObjectMap p = session.getProperties();
@@ -80,6 +85,11 @@ public class PropertiesResource extends RestServletDefault {
 
 	@Produces("application/json,text/json")
 	public static class PropertySerializer2 extends WriterSerializer {
+
+		public PropertySerializer2(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object output) throws Exception {
 			ObjectMap p = session.getProperties();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
index d08c0cf..793c337 100644
--- a/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
+++ b/juneau-rest-test/src/main/java/org/apache/juneau/rest/test/SerializersResource.java
@@ -14,6 +14,7 @@ package org.apache.juneau.rest.test;
 
 import static org.apache.juneau.rest.annotation.Inherit.*;
 
+import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
@@ -31,6 +32,11 @@ public class SerializersResource extends RestServletDefault {
 
 	@Produces("text/a")
 	public static class TestSerializerA extends WriterSerializer {
+
+		public TestSerializerA(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write("text/a - " + o);
@@ -39,6 +45,11 @@ public class SerializersResource extends RestServletDefault {
 
 	@Produces("text/b")
 	public static class TestSerializerB extends WriterSerializer {
+
+		public TestSerializerB(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write("text/b - " + o);
@@ -71,6 +82,11 @@ public class SerializersResource extends RestServletDefault {
 
 	@Produces("text/a")
 	public static class TestSerializerC extends WriterSerializer {
+
+		public TestSerializerC(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write("text/c - " + o);
@@ -87,6 +103,11 @@ public class SerializersResource extends RestServletDefault {
 
 	@Produces(value="text/a,text/d",contentType="text/d")
 	public static class TestSerializerD extends WriterSerializer {
+
+		public TestSerializerD(PropertyStore propertyStore) {
+			super(propertyStore);
+		}
+
 		@Override /* Serializer */
 		protected void doSerialize(SerializerSession session, Object o) throws Exception {
 			session.getWriter().write("text/d - " + o);

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/AcceptCharsetTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/AcceptCharsetTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/AcceptCharsetTest.java
index 0bace15..e6b5147 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/AcceptCharsetTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/AcceptCharsetTest.java
@@ -31,7 +31,7 @@ public class AcceptCharsetTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testQValues() throws Exception {
-		RestClient client = new TestRestClient().setHeader("Accept", "text/plain");
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 
 		check1(client, "utf-8", "utf-8");
 		check1(client, "iso-8859-1", "iso-8859-1");
@@ -46,15 +46,13 @@ public class AcceptCharsetTest extends RestTestcase {
 		check1(client, "*", "utf-8");
 		check1(client, "bad,iso-8859-1;q=0.5,*;q=0.1", "iso-8859-1");
 		check1(client, "bad,iso-8859-1;q=0.1,*;q=0.5", "utf-8");
-
-		client.closeQuietly();
 	}
 
 	private void check1(RestClient client, String requestCharset, String responseCharset) throws Exception {
 		RestCall r;
 		InputStream is;
 		String url = "/testAcceptCharset/testQValues";
-		r = client.doGet(url).setHeader("Accept-Charset", requestCharset).connect();
+		r = client.doGet(url).acceptCharset(requestCharset).connect();
 		assertTrue(r.getResponse().getFirstHeader("Content-Type").getValue().toLowerCase().contains(responseCharset));
 		is = r.getInputStream();
 		assertEquals("foo", IOUtils.read(new InputStreamReader(is, responseCharset)));
@@ -65,50 +63,50 @@ public class AcceptCharsetTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testCharsetOnResponse() throws Exception {
-		RestClient client = new TestRestClient().setAccept("text/plain").setContentType("text/plain");
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = "/testAcceptCharset/testCharsetOnResponse";
 		String r;
 
 		r = client.doPut(url, new StringReader("")).getResponseAsString();
 		assertEquals("utf-8/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Accept-Charset", "Shift_JIS").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).acceptCharset("Shift_JIS").getResponseAsString();
 		assertEquals("utf-8/shift_jis", r.toLowerCase());
 
 		try {
-			r = client.doPut(url+"?noTrace=true", new StringReader("")).setHeader("Accept-Charset", "BAD").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", new StringReader("")).acceptCharset("BAD").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE, "No supported charsets in header 'Accept-Charset': 'BAD'");
 		}
 
-		r = client.doPut(url, new StringReader("")).setHeader("Accept-Charset", "UTF-8").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).acceptCharset("UTF-8").getResponseAsString();
 		assertEquals("utf-8/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Accept-Charset", "bad,iso-8859-1").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).acceptCharset("bad,iso-8859-1").getResponseAsString();
 		assertEquals("utf-8/iso-8859-1", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Accept-Charset", "bad;q=0.9,iso-8859-1;q=0.1").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).acceptCharset("bad;q=0.9,iso-8859-1;q=0.1").getResponseAsString();
 		assertEquals("utf-8/iso-8859-1", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Accept-Charset", "bad;q=0.1,iso-8859-1;q=0.9").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).acceptCharset("bad;q=0.1,iso-8859-1;q=0.9").getResponseAsString();
 		assertEquals("utf-8/iso-8859-1", r.toLowerCase());
 
-		client.setHeader("Accept-Charset", "utf-8");
+		client = TestMicroservice.client().accept("text/plain").contentType("text/plain").acceptCharset("utf-8").build();
 
-		r = client.doPut(url, new StringReader("")).setHeader("Content-Type", "text/plain").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).contentType("text/plain").getResponseAsString();
 		assertEquals("utf-8/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Content-Type", "text/plain;charset=utf-8").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).contentType("text/plain;charset=utf-8").getResponseAsString();
 		assertEquals("utf-8/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Content-Type", "text/plain;charset=UTF-8").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).contentType("text/plain;charset=UTF-8").getResponseAsString();
 		assertEquals("utf-8/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Content-Type", "text/plain;charset=iso-8859-1").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).contentType("text/plain;charset=iso-8859-1").getResponseAsString();
 		assertEquals("iso-8859-1/utf-8", r.toLowerCase());
 
-		r = client.doPut(url, new StringReader("")).setHeader("Content-Type", "text/plain;charset=Shift_JIS").getResponseAsString();
+		r = client.doPut(url, new StringReader("")).contentType("text/plain;charset=Shift_JIS").getResponseAsString();
 		assertEquals("shift_jis/utf-8", r.toLowerCase());
 
 		try {

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BeanContextPropertiesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BeanContextPropertiesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BeanContextPropertiesTest.java
index 6580d9d..1e583a5 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BeanContextPropertiesTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/BeanContextPropertiesTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,11 +26,9 @@ public class BeanContextPropertiesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testClassTransforms() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.class, JsonParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
-		r = client.doGet("/testBeanContext/testClassTransforms/2001-07-04T15:30:45Z?d2=2001-07-05T15:30:45Z").setHeader("X-D3", "2001-07-06T15:30:45Z").getResponseAsString();
+		r = client.doGet("/testBeanContext/testClassTransforms/2001-07-04T15:30:45Z?d2=2001-07-05T15:30:45Z").header("X-D3", "2001-07-06T15:30:45Z").getResponseAsString();
 		assertEquals("d1=2001-07-04T15:30:45Z,d2=2001-07-05T15:30:45Z,d3=2001-07-06T15:30:45Z", r);
-
-		client.closeQuietly();
 	}
 }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CallbackStringsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CallbackStringsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CallbackStringsTest.java
index b65d2f8..36a6961 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CallbackStringsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CallbackStringsTest.java
@@ -24,7 +24,7 @@ public class CallbackStringsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/json+simple");
+		RestClient c = TestMicroservice.client().accept("text/json+simple").build();
 		String r;
 
 		r = c.doCallback("GET /testCallback").getResponseAsString();

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CharsetEncodingsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CharsetEncodingsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CharsetEncodingsTest.java
index 2aeb4f7..3bf705e 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CharsetEncodingsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/CharsetEncodingsTest.java
@@ -34,7 +34,8 @@ public class CharsetEncodingsTest extends RestTestcase {
 	@Test
 	public void test() throws Exception {
 		String url = "/testCharsetEncodings";
-		RestClient client = new TestRestClient().setAccept("text/s").setContentType("text/p");
+		RestClientBuilder cb = TestMicroservice.client().accept("text/s").contentType("text/p");
+		RestClient client = cb.build();
 		InputStream is;
 		String r;
 
@@ -47,20 +48,26 @@ public class CharsetEncodingsTest extends RestTestcase {
 		if (debug) System.err.println(r);
 		assertEquals("utf-8/foo/utf-8", r);
 
-		client.setHeader("Accept-Charset", "utf-8").setContentType("text/p;charset=utf-8");
-		is = client.doPut(url, new StringReader("foo")).getInputStream();
+		client.closeQuietly();
+
+		client = cb.acceptCharset("utf-8").contentType("text/p;charset=utf-8").build();
+		is = client.doPut(url, new StringReader("foo")).acceptCharset("utf-8").contentType("text/p;charset=utf-8").getInputStream();
 		r = IOUtils.read(new InputStreamReader(is, "utf-8"));
 		if (debug) System.err.println(r);
 		assertEquals("utf-8/foo/utf-8", r);
 
-		client.setHeader("Accept-Charset", "Shift_JIS").setContentType("text/p;charset=shift_jis");
+		client.closeQuietly();
+
+		client = cb.acceptCharset("Shift_JIS").contentType("text/p;charset=shift_jis").build();
 		is = client.doPut(url, new StringReader("foo")).getInputStream();
 		r = IOUtils.read(new InputStreamReader(is, "Shift_JIS"));
 		if (debug) System.err.println(r);
 		assertEquals("shift_jis/foo/shift_jis", r);
 
+		client.closeQuietly();
+
 		try {
-			client.setHeader("Accept-Charset", "BAD").setContentType("text/p;charset=sjis");
+			client = cb.acceptCharset("BAD").contentType("text/p;charset=sjis").build();
 			is = client.doPut(url + "?noTrace=true", new StringReader("foo")).getInputStream();
 			r = IOUtils.read(new InputStreamReader(is, "sjis"));
 			if (debug) System.err.println(r);
@@ -69,20 +76,26 @@ public class CharsetEncodingsTest extends RestTestcase {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE, "No supported charsets in header 'Accept-Charset': 'BAD'");
 		}
 
-		client.setAccept("text/s").setHeader("Accept-Charset", "utf-8").setContentType("text/p");
+		client.closeQuietly();
+
+		client = cb.accept("text/s").acceptCharset("utf-8").contentType("text/p").build();
 		is = client.doPut(url+"?Content-Type=text/p", new StringReader("foo")).getInputStream();
 		r = IOUtils.read(new InputStreamReader(is, "utf-8"));
 		if (debug) System.err.println(r);
 		assertEquals("utf-8/foo/utf-8", r);
 
-		client.setAccept("text/s").setContentType("text/bad").setHeader("Accept-Charset", "utf-8");
+		client.closeQuietly();
+
+		client = cb.accept("text/s").contentType("text/bad").acceptCharset("utf-8").build();
 		is = client.doPut(url+"?Content-Type=text/p;charset=utf-8", new StringReader("foo")).getInputStream();
 		r = IOUtils.read(new InputStreamReader(is, "utf-8"));
 		if (debug) System.err.println(r);
 		assertEquals("utf-8/foo/utf-8", r);
 
+		client.closeQuietly();
+
 		try {
-			client.setAccept("text/s").setContentType("text/p").setHeader("Accept-Charset", "utf-8");
+			client = cb.accept("text/s").contentType("text/p").acceptCharset("utf-8").build();
 			is = client.doPut(url+"?Content-Type=text/p;charset=BAD&noTrace=true", new StringReader("foo")).getInputStream();
 			r = IOUtils.read(new InputStreamReader(is, "utf-8"));
 			if (debug) System.err.println(r);
@@ -91,6 +104,7 @@ public class CharsetEncodingsTest extends RestTestcase {
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE, "Unsupported charset in header 'Content-Type': 'text/p;charset=BAD'");
 		}
+
 		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ClientVersionTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ClientVersionTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ClientVersionTest.java
index 85c168b..3eda27b 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ClientVersionTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ClientVersionTest.java
@@ -14,7 +14,6 @@ package org.apache.juneau.rest.test;
 
 import static org.junit.Assert.*;
 
-import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -27,32 +26,26 @@ public class ClientVersionTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testDefaultHeader() throws Exception {
-		RestClient c = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/defaultHeader";
 
-		assertEquals("no-version", c.doGet(url).getResponseAsString());
+		assertEquals("no-version", client.doGet(url).getResponseAsString());
 
 //		for (String s : "0, 0.0, 0.1, .1, .9, .99".split("\\s*,\\s*")) {
-//			c.setClientVersion(s);
-//			assertEquals(s, "[0.0,1.0)", c.doGet(url).getResponseAsString());
+//			assertEquals(s, "[0.0,1.0)", client.doGet(url).clientVersion(s).getResponseAsString());
 //		}
 
 		for (String s : "1, 1.0, 1.0.0, 1.0.1".split("\\s*,\\s*")) {
-			c.setClientVersion(s);
-			assertEquals(s, "[1.0,1.0]", c.doGet(url).getResponseAsString());
+			assertEquals(s, "[1.0,1.0]", client.doGet(url).clientVersion(s).getResponseAsString());
 		}
 
 		for (String s : "1.1, 1.1.1, 1.2, 1.9.9".split("\\s*,\\s*")) {
-			c.setClientVersion(s);
-			assertEquals(s, "[1.1,2)", c.doGet(url).getResponseAsString());
+			assertEquals(s, "[1.1,2)", client.doGet(url).clientVersion(s).getResponseAsString());
 		}
 
 		for (String s : "2, 2.0, 2.1, 9, 9.9".split("\\s*,\\s*")) {
-			c.setClientVersion(s);
-			assertEquals(s, "2", c.doGet(url).getResponseAsString());
+			assertEquals(s, "2", client.doGet(url).clientVersion(s).getResponseAsString());
 		}
-
-		c.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -60,31 +53,25 @@ public class ClientVersionTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testCustomHeader() throws Exception {
-		RestClient c = new TestRestClient(PlainTextSerializer.class, PlainTextParser.class);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT_PLAINTEXT;
 		String url = URL + "/customHeader";
 
-		assertEquals("no-version", c.doGet(url).getResponseAsString());
+		assertEquals("no-version", client.doGet(url).getResponseAsString());
 
 		for (String s : "0, 0.0, 0.1, .1, .9, .99".split("\\s*,\\s*")) {
-			c.setHeader("Custom-Client-Version", s);
-			assertEquals("[0.0,1.0)", c.doGet(url).getResponseAsString());
+			assertEquals("[0.0,1.0)", client.doGet(url).header("Custom-Client-Version", s).getResponseAsString());
 		}
 
 		for (String s : "1, 1.0, 1.0.0, 1.0.1".split("\\s*,\\s*")) {
-			c.setHeader("Custom-Client-Version", s);
-			assertEquals("[1.0,1.0]", c.doGet(url).getResponseAsString());
+			assertEquals("[1.0,1.0]", client.doGet(url).header("Custom-Client-Version", s).getResponseAsString());
 		}
 
 		for (String s : "1.1, 1.1.1, 1.2, 1.9.9".split("\\s*,\\s*")) {
-			c.setHeader("Custom-Client-Version", s);
-			assertEquals("[1.1,2)", c.doGet(url).getResponseAsString());
+			assertEquals("[1.1,2)", client.doGet(url).header("Custom-Client-Version", s).getResponseAsString());
 		}
 
 		for (String s : "2, 2.0, 2.1, 9, 9.9".split("\\s*,\\s*")) {
-			c.setHeader("Custom-Client-Version", s);
-			assertEquals("2", c.doGet(url).getResponseAsString());
+			assertEquals("2", client.doGet(url).header("Custom-Client-Version", s).getResponseAsString());
 		}
-
-		c.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ConfigTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
index 3856466..a0f7b88 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
@@ -16,7 +16,6 @@ import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.ini.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
@@ -30,7 +29,7 @@ public class ConfigTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void test() throws Exception {
-		RestClient c = new TestRestClient(JsonSerializer.class, JsonParser.class).setAccept("text/json+simple");
+		RestClient c = TestMicroservice.client().accept("text/json+simple").build();
 
 		ConfigFile cf = c.doGet(URL).getResponse(ConfigFileImpl.class);
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ContentTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ContentTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ContentTest.java
index 724a3dd..386aad1 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ContentTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ContentTest.java
@@ -20,7 +20,7 @@ import java.net.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.plaintext.*;
 import org.apache.juneau.rest.client.*;
-import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.uon.*;
 import org.junit.*;
 
 public class ContentTest extends RestTestcase {
@@ -32,7 +32,7 @@ public class ContentTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testUsingContentParam() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/json+simple");
+		RestClient c = TestMicroservice.client().accept("text/json+simple").build();
 		String r;
 
 		//	@RestMethod(name="POST", path="/boolean")
@@ -180,157 +180,8 @@ public class ContentTest extends RestTestcase {
 	// Basic tests using &Body parameter with &Accept=text/json
 	//====================================================================================================
 	@Test
-	public void testUsingContentParamJsonHeader() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/json+simple").setHeader("Content-Type", "text/json");
-		String r;
-
-		//	@RestMethod(name="POST", path="/boolean")
-		//	public boolean testBool(@Body boolean b) {
-		//		return b;
-		//	}
-		r = c.doPost(URL + "/boolean?body=true", null).getResponseAsString();
-		assertEquals("true", r);
-		r = c.doPost(URL + "/boolean?body=false", null).getResponseAsString();
-		assertEquals("false", r);
-		try {
-			r = c.doPost(URL + "/boolean?body=null&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-		try {
-			r = c.doPost(URL + "/boolean?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-
-		//	@RestMethod(name="POST", path="/Boolean")
-		//	public Boolean testBoolean(@Body Boolean b) {
-		//		return b;
-		//	}
-		r = c.doPost(URL + "/Boolean?body=true", null).getResponseAsString();
-		assertEquals("true", r);
-		r = c.doPost(URL + "/Boolean?body=false", null).getResponseAsString();
-		assertEquals("false", r);
-		r = c.doPost(URL + "/Boolean?body=null", null).getResponseAsString();
-		assertEquals("null", r);
-		try {
-			r = c.doPost(URL + "/Boolean?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/int")
-		//	public int testInt(@Body int i) {
-		//		return i;
-		//	}
-		r = c.doPost(URL + "/int?body=-123", null).getResponseAsString();
-		assertEquals("-123", r);
-		try {
-			r = c.doPost(URL + "/int?body=null&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-		try {
-			r = c.doPost(URL + "/int?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/Integer")
-		//	public Integer testInteger(@Body Integer i) {
-		//		return i;
-		//	}
-		r = c.doPost(URL + "/Integer?body=-123", null).getResponseAsString();
-		assertEquals("-123", r);
-		r = c.doPost(URL + "/Integer?body=null", null).getResponseAsString();
-		assertEquals("null", r);
-		try {
-			r = c.doPost(URL + "/Integer?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/float")
-		//	public float testFloat(@Body float f) {
-		//		return f;
-		//	}
-		r = c.doPost(URL + "/float?body=-1.23", null).getResponseAsString();
-		assertEquals("-1.23", r);
-		try {
-			r = c.doPost(URL + "/float?body=null&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-		try {
-			r = c.doPost(URL + "/float?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/Float")
-		//	public Float testFloat2(@Body Float f) {
-		//		return f;
-		//	}
-		r = c.doPost(URL + "/Float?body=-1.23", null).getResponseAsString();
-		assertEquals("-1.23", r);
-		r = c.doPost(URL + "/Float?body=null", null).getResponseAsString();
-		assertEquals("null", r);
-		try {
-			r = c.doPost(URL + "/Float?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/Map")
-		//	public TreeMap<String,String> testMap(@Body TreeMap<String,String> m) {
-		//		return m;
-		//	}
-		r = c.doPost(URL + "/Map?body=" + encode("{a:'b',c:'d'}"), null).getResponseAsString();
-		assertEquals("{a:'b',c:'d'}", r);
-		r = c.doPost(URL + "/Map?body=null", null).getResponseAsString();
-		assertEquals("null", r);
-		try {
-			r = c.doPost(URL + "/Map?body=bad&noTrace=true", null).getResponseAsString();
-			fail("Exception expected!");
-		} catch (RestCallException e) {
-			assertEquals(400, e.getResponseCode());
-		}
-
-		//	@RestMethod(name="POST", path="/B")
-		//	public DTO2s.B testPojo1(@Body DTO2s.B b) {
-		//		return b;
-		//	}
-		DTOs.B b = DTOs.B.create();
-		r = c.doPost(URL + "/B?body=" + encode(JsonSerializer.DEFAULT_LAX.serialize(b)), null).getResponseAsString();
-		assertEquals("{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f19:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f20:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]]}", r);
-
-		//	@RestMethod(name="POST", path="/C")
-		//	public DTO2s.C testPojo2(@Body DTO2s.C c) {
-		//		return c;
-		//	}
-		DTOs.C x = DTOs.C.create();
-		r = c.doPost(URL + "/C?body=" + encode(JsonSerializer.DEFAULT_LAX.serialize(x)), null).getResponseAsString();
-		assertEquals("{f01:['a','b'],f02:['c','d'],f03:[1,2],f04:[3,4],f05:[['e','f'],['g','h']],f06:[['i','j'],['k','l']],f07:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f08:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f09:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f10:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f11:['a','b'],f12:['c','d'],f13:[1,2],f14:[3,4],f15:[['e','f'],['g','h']],f16:[['i','j'],['k','l']],f17:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f18:[{a:'a',b:1,c:true},{a:'a',b:1,c:true}],f19:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]],f20:[[{a:'a',b:1,c:true}],[{a:'a',b:1,c:true}]]}", r);
-
-		c.closeQuietly();
-	}
-
-	//====================================================================================================
-	// Basic tests using &Body parameter with &Accept=text/json
-	//====================================================================================================
-	@Test
 	public void testUsingContentParamJsonParam() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/json+simple");
+		RestClient c = TestMicroservice.client().accept("text/json+simple").build();
 		String r;
 
 		//	@RestMethod(name="POST", path="/boolean")
@@ -479,7 +330,7 @@ public class ContentTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testUsingContent() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/json+simple").setHeader("Content-Type", "text/uon").setSerializer(PlainTextSerializer.class);
+		RestClient c = TestMicroservice.client().accept("text/json+simple").contentType("text/uon").serializer(PlainTextSerializer.class).build();
 		String r;
 
 		//	@RestMethod(name="POST", path="/boolean")

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/DefaultContentTypesTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/DefaultContentTypesTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/DefaultContentTypesTest.java
index aa662d8..99a7c9b 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/DefaultContentTypesTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/DefaultContentTypesTest.java
@@ -16,7 +16,6 @@ import static javax.servlet.http.HttpServletResponse.*;
 import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -31,42 +30,34 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testDefaultHeadersOnServletAnnotation() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		String url = URL + "/testDefaultHeadersOnServletAnnotation";
 
-		client.setAccept("").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s1").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("").getResponseAsString();
 		assertEquals("s1/p2", r);
 
-		client.setAccept("").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p1").getResponseAsString();
 		assertEquals("s2/p1", r);
 
-		client.setAccept("text/s1").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("text/p1").getResponseAsString();
 		assertEquals("s1/p1", r);
 
-		client.setAccept("text/s2").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p2").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s2").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("text/p2").getResponseAsString();
 		assertEquals("s2/p2", r);
 
 		try {
-			client.setAccept("text/s3").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s3").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -76,8 +67,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p3");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p3").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -87,8 +77,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s3").setContentType("text/p3");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s3").contentType("text/p3").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -96,8 +85,6 @@ public class DefaultContentTypesTest extends RestTestcase {
 				"Supported media-types: [text/p1, text/p2]"
 			);
 		}
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -106,14 +93,13 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testRestMethodParsersSerializers() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		String url = URL + "/testRestMethodParsersSerializers";
 
 		try {
-			client.setAccept("").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -123,8 +109,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s1").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s1").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -134,8 +119,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p1");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -145,8 +129,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s1").setContentType("text/p1");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s1").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -156,8 +139,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s2").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s2").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -167,8 +149,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p2");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p2").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -178,8 +159,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s2").setContentType("text/p2");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s2").contentType("text/p2").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -189,8 +169,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s3").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s3").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -200,8 +179,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p3");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p3").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -210,11 +188,8 @@ public class DefaultContentTypesTest extends RestTestcase {
 			);
 		}
 
-		client.setAccept("text/s3").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -223,54 +198,43 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testRestMethodAddParsersSerializers() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		String url = URL + "/testRestMethodAddParsersSerializers";
 
-		client.setAccept("").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s1").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("").getResponseAsString();
 		assertEquals("s1/p2", r);
 
-		client.setAccept("").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p1").getResponseAsString();
 		assertEquals("s2/p1", r);
 
-		client.setAccept("text/s1").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("text/p1").getResponseAsString();
 		assertEquals("s1/p1", r);
 
-		client.setAccept("text/s2").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p2").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s2").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("text/p2").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s3").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("").getResponseAsString();
 		assertEquals("s3/p2", r);
 
-		client.setAccept("").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p3").getResponseAsString();
 		assertEquals("s2/p3", r);
 
-		client.setAccept("text/s3").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
 
 		try {
-			client.setAccept("").setContentType("text/p4");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p4").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			// Note that parsers defined on method are listed before parsers defined on class.
@@ -281,8 +245,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s4").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s4").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			// Note that serializers defined on method are listed before serializers defined on class.
@@ -291,8 +254,6 @@ public class DefaultContentTypesTest extends RestTestcase {
 				"Supported media-types: [text/s3, text/s1, text/s2]"
 			);
 		}
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -300,24 +261,21 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testAccept() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT).setContentType("text/p1");
+		RestClient client = TestMicroservice.client().contentType("text/p1").build();
 		String r;
 
 		String url = URL + "/testAccept";
 
 		// "*/*" should match the first serializer, not the default serializer.
-		client.setAccept("*/*");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("*/*").getResponseAsString();
 		assertEquals("s1/p1", r);
 
 		// "text/*" should match the first serializer, not the default serializer.
-		client.setAccept("text/*");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/*").getResponseAsString();
 		assertEquals("s1/p1", r);
 
 		try {
-			client.setAccept("bad/*");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("bad/*").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -326,20 +284,16 @@ public class DefaultContentTypesTest extends RestTestcase {
 			);
 		}
 
-		client.setAccept("bad/*,text/*");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("bad/*,text/*").getResponseAsString();
 		assertEquals("s1/p1", r);
 
-		client.setAccept("text/*,bad/*");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/*,bad/*").getResponseAsString();
 		assertEquals("s1/p1", r);
 
-		client.setAccept("text/s1;q=0.5,text/s2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1;q=0.5,text/s2").getResponseAsString();
 		assertEquals("s2/p1", r);
 
-		client.setAccept("text/s1,text/s2;q=0.5");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1,text/s2;q=0.5").getResponseAsString();
 		assertEquals("s1/p1", r);
 
 		client.closeQuietly();
@@ -351,18 +305,16 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testRestMethodParserSerializerAnnotations() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		String url = URL + "/testRestMethodParserSerializerAnnotations";
 
-		client.setAccept("").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("").getResponseAsString();
 		assertEquals("s3/p3", r);
 
 		try {
-			client.setAccept("text/s1").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s1").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -372,8 +324,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p1");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -383,8 +334,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s1").setContentType("text/p1");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s1").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -394,8 +344,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s2").setContentType("");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s2").contentType("").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -405,8 +354,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("").setContentType("text/p2");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("").contentType("text/p2").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -416,8 +364,7 @@ public class DefaultContentTypesTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s2").setContentType("text/p2");
-			r = client.doPut(url+"?noTrace=true", "").getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", "").accept("text/s2").contentType("text/p2").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -426,19 +373,14 @@ public class DefaultContentTypesTest extends RestTestcase {
 			);
 		}
 
-		client.setAccept("text/s3").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("").getResponseAsString();
 		assertEquals("s3/p3", r);
 
-		client.setAccept("").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
 
-		client.setAccept("text/s3").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
-
-		client.closeQuietly();
 	}
 
 	//====================================================================================================
@@ -447,51 +389,39 @@ public class DefaultContentTypesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testRestMethodAddParsersSerializersAnnotations() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
 		String url = URL + "/testRestMethodAddParsersSerializersAnnotations";
 
-		client.setAccept("").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("").getResponseAsString();
 		assertEquals("s3/p3", r);
 
-		client.setAccept("text/s1").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("").getResponseAsString();
 		assertEquals("s1/p3", r);
 
-		client.setAccept("").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p1").getResponseAsString();
 		assertEquals("s3/p1", r);
 
-		client.setAccept("text/s1").setContentType("text/p1");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s1").contentType("text/p1").getResponseAsString();
 		assertEquals("s1/p1", r);
 
-		client.setAccept("text/s2").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("").getResponseAsString();
 		assertEquals("s2/p3", r);
 
-		client.setAccept("").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p2").getResponseAsString();
 		assertEquals("s3/p2", r);
 
-		client.setAccept("text/s2").setContentType("text/p2");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s2").contentType("text/p2").getResponseAsString();
 		assertEquals("s2/p2", r);
 
-		client.setAccept("text/s3").setContentType("");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("").getResponseAsString();
 		assertEquals("s3/p3", r);
 
-		client.setAccept("").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
 
-		client.setAccept("text/s3").setContentType("text/p3");
-		r = client.doPut(url, "").getResponseAsString();
+		r = client.doPut(url, "").accept("text/s3").contentType("text/p3").getResponseAsString();
 		assertEquals("s3/p3", r);
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ErrorConditionsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ErrorConditionsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ErrorConditionsTest.java
index 7a6f7ce..eb46760 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ErrorConditionsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/ErrorConditionsTest.java
@@ -17,7 +17,6 @@ import static org.apache.juneau.rest.test.TestUtils.*;
 import static org.junit.Assert.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -26,17 +25,9 @@ public class ErrorConditionsTest extends RestTestcase {
 
 	private static String URL = "/testErrorConditions";
 	private static boolean debug = false;
-	private static RestClient client;
+	private RestClient client = TestMicroservice.DEFAULT_CLIENT;
 
-	@BeforeClass
-	public static void beforeClass() {
-		 client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
-	}
 
-	@AfterClass
-	public static void afterClass() {
-		 client.closeQuietly();
-	}
 	//====================================================================================================
 	// Test non-existent properties
 	//====================================================================================================
@@ -163,7 +154,7 @@ public class ErrorConditionsTest extends RestTestcase {
 		}
 
 		try {
-			client.doPut(url + "/1?noTrace=true&p1=1", "").setHeader("h1", "foo").getResponseAsString();
+			client.doPut(url + "/1?noTrace=true&p1=1", "").header("h1", "foo").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_BAD_REQUEST,

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GroupsTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GroupsTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GroupsTest.java
index ad0d052..0429449 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GroupsTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GroupsTest.java
@@ -18,7 +18,6 @@ import static org.junit.Assert.*;
 
 import java.io.*;
 
-import org.apache.juneau.json.*;
 import org.apache.juneau.rest.client.*;
 import org.junit.*;
 
@@ -33,13 +32,12 @@ public class GroupsTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testSerializerDefinedOnClass() throws Exception {
-		RestClient client = new TestRestClient(JsonSerializer.DEFAULT, JsonParser.DEFAULT);
+		RestClient client = TestMicroservice.DEFAULT_CLIENT;
 		String url = URL + "/testSerializerDefinedOnClass";
 		String r;
 
 		try {
-			client.setContentType("text/p1");
-			r = client.doGet(url+"?noTrace=true").getResponseAsString();
+			r = client.doGet(url+"?noTrace=true").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -48,17 +46,14 @@ public class GroupsTest extends RestTestcase {
 			);
 		}
 
-		client.setAccept("text/s1").setContentType("");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/s1").contentType("").getResponseAsString();
 		assertEquals("text/s,GET", r);
 
-		client.setAccept("text/s2").setContentType("");
-		r = client.doGet(url).getResponseAsString();
+		r = client.doGet(url).accept("text/s2").contentType("").getResponseAsString();
 		assertEquals("text/s,GET", r);
 
 		try {
-			client.setAccept("text/s3").setContentType("");
-			r = client.doGet(url+"?noTrace=true").getResponseAsString();
+			r = client.doGet(url+"?noTrace=true").accept("text/s3").contentType("").getResponseAsString();
 			assertEquals("text/s,GET", r);
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -68,8 +63,7 @@ public class GroupsTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/json").setContentType("text/p1");
-			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).accept("text/json").contentType("text/p1").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -79,8 +73,7 @@ public class GroupsTest extends RestTestcase {
 		}
 
 		try {
-			client.setAccept("text/s1").setContentType("text/json");
-			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).accept("text/s1").contentType("text/json").getResponseAsString();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -89,17 +82,14 @@ public class GroupsTest extends RestTestcase {
 			);
 		}
 
-		client.setContentType("text/p1").setAccept("text/s1");
-		r = client.doPut(url, new StringReader("foo")).getResponseAsString();
+		r = client.doPut(url, new StringReader("foo")).contentType("text/p1").accept("text/s1").getResponseAsString();
 		assertEquals("text/s,foo", r);
 
-		client.setContentType("text/p2").setAccept("text/s2");
-		r = client.doPut(url, new StringReader("foo")).getResponseAsString();
+		r = client.doPut(url, new StringReader("foo")).contentType("text/p2").accept("text/s2").getResponseAsString();
 		assertEquals("text/s,foo", r);
 
 		try {
-			client.setContentType("text/p1").setAccept("text/s3");
-			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).contentType("text/p1").accept("text/s3").getResponseAsString();
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
 				"Unsupported media-type in request header 'Accept': 'text/s3'",
@@ -108,15 +98,12 @@ public class GroupsTest extends RestTestcase {
 		}
 
 		try {
-			client.setContentType("text/p3").setAccept("text/s1");
-			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).getResponseAsString();
+			r = client.doPut(url+"?noTrace=true", new StringReader("foo")).contentType("text/p3").accept("text/s1").getResponseAsString();
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
 				"Unsupported media-type in request header 'Content-Type': 'text/p3'",
 				"Supported media-types: [text/p1, text/p2]"
 			);
 		}
-
-		client.closeQuietly();
 	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
----------------------------------------------------------------------
diff --git a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
index 4869b64..6ce05c3 100644
--- a/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
+++ b/juneau-rest-test/src/test/java/org/apache/juneau/rest/test/GzipTest.java
@@ -56,7 +56,7 @@ public class GzipTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testGzipOff() throws Exception {
-		RestClient c = new TestRestClient().setAccept("text/plain").setContentType("text/plain");
+		RestClient c = TestMicroservice.client().accept("text/plain").contentType("text/plain").build();
 		RestCall r;
 		String url = testGzipOff;
 
@@ -65,22 +65,22 @@ public class GzipTest extends RestTestcase {
 		r = c.doGet(url);
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "");
+		r = c.doGet(url).acceptEncoding("");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "*");
+		r = c.doGet(url).acceptEncoding("*");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "identity");
+		r = c.doGet(url).acceptEncoding("identity");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match identity.
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(url).acceptEncoding("mycoding");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Shouldn't match.
 		try {
-			r = c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "mycoding,identity;q=0").connect();
+			r = c.doGet(url+"?noTrace=true").acceptEncoding("mycoding,identity;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -91,7 +91,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match.
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "mycoding,*;q=0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("mycoding,*;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -101,24 +101,24 @@ public class GzipTest extends RestTestcase {
 		}
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "identity;q=0.8,mycoding;q=0.6");
+		r = c.doGet(url).acceptEncoding("identity;q=0.8,mycoding;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding;q=0.8,identity;q=0.6");
+		r = c.doGet(url).acceptEncoding("mycoding;q=0.8,identity;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding;q=0.8,*;q=0.6");
+		r = c.doGet(url).acceptEncoding("mycoding;q=0.8,*;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "*;q=0.8,myencoding;q=0.6");
+		r = c.doGet(url).acceptEncoding("*;q=0.8,myencoding;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "identity;q=0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("identity;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -129,7 +129,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "identity;q=0.0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("identity;q=0.0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -140,7 +140,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "*;q=0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("*;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -151,7 +151,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "*;q=0.0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("*;q=0.0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -166,14 +166,14 @@ public class GzipTest extends RestTestcase {
 		r = c.doPut(url, new StringReader("foo"));
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doPut(url, new StringReader("foo")).setHeader("Content-Encoding", "");
+		r = c.doPut(url, new StringReader("foo")).header("Content-Encoding", "");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doPut(url, new StringReader("foo")).setHeader("Content-Encoding", "identity");
+		r = c.doPut(url, new StringReader("foo")).header("Content-Encoding", "identity");
 		assertEquals("foo", r.getResponseAsString());
 
 		try {
-			c.doPut(url+"?noTrace=true", compress("foo")).setHeader("Content-Encoding", "mycoding").connect();
+			c.doPut(url+"?noTrace=true", compress("foo")).header("Content-Encoding", "mycoding").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_UNSUPPORTED_MEDIA_TYPE,
@@ -192,9 +192,9 @@ public class GzipTest extends RestTestcase {
 	public void testGzipOn() throws Exception {
 
 		// Create a client that disables content compression support so that we can get the gzipped content directly.
-		CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(TestRestClient.getSSLSocketFactory()).disableContentCompression().build();
+		CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(TestMicroservice.getSSLSocketFactory()).disableContentCompression().build();
 
-		RestClient c = new TestRestClient(httpClient).setAccept("text/plain").setContentType("text/plain");
+		RestClient c = TestMicroservice.client().httpClient(httpClient, false).accept("text/plain").contentType("text/plain").build();
 		RestCall r;
 		String url = testGzipOn;
 
@@ -203,44 +203,44 @@ public class GzipTest extends RestTestcase {
 		r = c.doGet(url);
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "");
+		r = c.doGet(url).acceptEncoding("");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "*");
+		r = c.doGet(url).acceptEncoding("*");
 		assertEquals("foo", decompress(r.getInputStream()));
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "identity");
+		r = c.doGet(url).acceptEncoding("identity");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match identity.
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(url).acceptEncoding("mycoding");
 		assertEquals("foo", decompress(r.getInputStream()));
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding,identity;q=0").connect();
+		r = c.doGet(url).acceptEncoding("mycoding,identity;q=0").connect();
 		assertEquals("foo", decompress(r.getInputStream()));
 
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding,*;q=0").connect();
+		r = c.doGet(url).acceptEncoding("mycoding,*;q=0").connect();
 		assertEquals("foo", decompress(r.getInputStream()));
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "identity;q=0.8,mycoding;q=0.6");
+		r = c.doGet(url).acceptEncoding("identity;q=0.8,mycoding;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Should match mycoding
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding;q=0.8,identity;q=0.6");
+		r = c.doGet(url).acceptEncoding("mycoding;q=0.8,identity;q=0.6");
 		assertEquals("foo", decompress(r.getInputStream()));
 
 		// Should match mycoding
-		r = c.doGet(url).setHeader("Accept-Encoding", "mycoding;q=0.8,*;q=0.6");
+		r = c.doGet(url).acceptEncoding("mycoding;q=0.8,*;q=0.6");
 		assertEquals("foo", decompress(r.getInputStream()));
 
 		// Should match identity
-		r = c.doGet(url).setHeader("Accept-Encoding", "*;q=0.8,myencoding;q=0.6");
+		r = c.doGet(url).acceptEncoding("*;q=0.8,myencoding;q=0.6");
 		assertEquals("foo", r.getResponseAsString());
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "identity;q=0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("identity;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -251,7 +251,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "identity;q=0.0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("identity;q=0.0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -262,7 +262,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "*;q=0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("*;q=0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -273,7 +273,7 @@ public class GzipTest extends RestTestcase {
 
 		// Shouldn't match
 		try {
-			c.doGet(url+"?noTrace=true").setHeader("Accept-Encoding", "*;q=0.0").connect();
+			c.doGet(url+"?noTrace=true").acceptEncoding("*;q=0.0").connect();
 			fail("Exception expected");
 		} catch (RestCallException e) {
 			checkErrorResponse(debug, e, SC_NOT_ACCEPTABLE,
@@ -288,16 +288,16 @@ public class GzipTest extends RestTestcase {
 		r = c.doPut(url, new StringReader("foo"));
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doPut(url, new StringReader("foo")).setHeader("Content-Encoding", "");
+		r = c.doPut(url, new StringReader("foo")).header("Content-Encoding", "");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doPut(url, new StringReader("foo")).setHeader("Content-Encoding", "identity");
+		r = c.doPut(url, new StringReader("foo")).header("Content-Encoding", "identity");
 		assertEquals("foo", r.getResponseAsString());
 
-		r = c.doPut(url, compress("foo")).setHeader("Content-Encoding", "mycoding");
+		r = c.doPut(url, compress("foo")).header("Content-Encoding", "mycoding");
 		assertEquals("foo", r.getResponseAsString());
 
-		c.closeQuietly();
+		c.closeQuietly(); // We want to close our client because we created the HttpClient in this method.
 	}
 
 	//====================================================================================================
@@ -306,26 +306,26 @@ public class GzipTest extends RestTestcase {
 	@Test
 	public void testGzipOnDirect() throws Exception {
 		// Create a client that disables content compression support so that we can get the gzipped content directly.
-		CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(TestRestClient.getSSLSocketFactory()).build();
-		RestClient c = new TestRestClient(httpClient).setAccept("text/plain").setContentType("text/plain");
+		CloseableHttpClient httpClient = HttpClientBuilder.create().setSSLSocketFactory(TestMicroservice.getSSLSocketFactory()).build();
+		RestClient c = TestMicroservice.client().httpClient(httpClient, false).accept("text/plain").contentType("text/plain").build();
 		RestCall r = null;
 		String s = null;
 
 		// res.getOutputStream() called....should bypass encoding.
-		r = c.doGet(testGzipOn + "/direct").setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(testGzipOn + "/direct").acceptEncoding("mycoding");
 		s = r.getResponseAsString();
 		assertEquals("test", s);
 		assertTrue(r.getResponse().getHeaders("Content-Type")[0].getValue().contains("text/direct")); // Should get header set manually.
 		assertEquals(0, r.getResponse().getHeaders("Content-Encoding").length);                // Should not be set.
 
 		// res.getWriter() called....should bypass encoding.
-		r = c.doGet(testGzipOn + "/direct2").setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(testGzipOn + "/direct2").acceptEncoding("mycoding");
 		s = r.getResponseAsString();
 		assertEquals("test", s);
 		assertEquals(0, r.getResponse().getHeaders("Content-Encoding").length);                // Should not be set.
 
 		// res.getNegotiateWriter() called....should NOT bypass encoding.
-		r = c.doGet(testGzipOn + "/direct3").setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(testGzipOn + "/direct3").acceptEncoding("mycoding");
 		try {
 			assertEquals("mycoding", r.getResponse().getHeaders("content-encoding")[0].getValue());
 		} catch (RestCallException e) {
@@ -334,11 +334,11 @@ public class GzipTest extends RestTestcase {
 		}
 
 		// res.getNegotiateWriter() called but @RestMethod(encoders={})...should bypass encoding.
-		r = c.doGet(testGzipOn + "/direct4").setHeader("Accept-Encoding", "mycoding");
+		r = c.doGet(testGzipOn + "/direct4").acceptEncoding("mycoding");
 		s = r.getResponseAsString();
 		assertEquals("test", s);
 		assertEquals(0, r.getResponse().getHeaders("Content-Encoding").length);                // Should not be set.
 
-		c.closeQuietly();
+		c.closeQuietly(); // We want to close our client because we created the HttpClient in this method.
 	}
 }


[31/34] incubator-juneau git commit: Add builder classes for all serializers and parsers.

Posted by ja...@apache.org.
http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java b/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
new file mode 100644
index 0000000..9bc6398
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/PropertyStoreTest.java
@@ -0,0 +1,823 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import static org.apache.juneau.TestUtils.*;
+import static org.junit.Assert.*;
+
+import java.util.*;
+
+import org.apache.juneau.xml.*;
+import org.junit.*;
+
+
+@SuppressWarnings({"rawtypes","javadoc"})
+public class PropertyStoreTest {
+
+	//====================================================================================================
+	// testSimpleProperties()
+	//====================================================================================================
+	@Test
+	public void testSimpleProperties() {
+		PropertyStore f = PropertyStore.create();
+
+		f.setProperty("A.f1", "1");
+		f.setProperty("A.f2", "2");
+
+		assertObjectEquals("{'A.f1':'1','A.f2':'2'}", f.getPropertyMap("A").asMap());
+
+		f.setProperty("B.f3", "3");
+		f.setProperty("A.f1", String.class);
+		f.setProperty("A.f2", 4);
+
+		assertObjectEquals("{'A.f1':'java.lang.String','A.f2':4}", f.getPropertyMap("A").asMap());
+
+		f.setProperty("A.f2", null);
+		f.setProperty("A.f2", null);
+		assertObjectEquals("{'A.f1':'java.lang.String'}", f.getPropertyMap("A").asMap());
+
+		try {
+			f.setProperty(null, null);
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Invalid property name specified: 'null'", e.getMessage());
+		}
+
+		try {
+			f.addToProperty("A.f1", "foo");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot add value 'foo' (java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
+		}
+
+		try {
+			f.removeFromProperty("A.f1", "foo");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot remove value 'foo' (java.lang.String) from property 'A.f1' (SIMPLE).", e.getMessage());
+		}
+
+		try {
+			f.putToProperty("A.f1", "foo", "bar");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot put value 'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
+		}
+
+		try {
+			f.putToProperty("A.f1", "foo");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot put value 'foo' (java.lang.String) to property 'A.f1' (SIMPLE).", e.getMessage());
+		}
+	}
+
+	//====================================================================================================
+	// testSetProperties()
+	//====================================================================================================
+	@Test
+	public void testSetProperties() {
+		PropertyStore f = PropertyStore.create();
+		String key = "A.f1.set";
+
+		f.setProperty(key, Arrays.asList(2,3,1));
+		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
+
+		f.addToProperty(key, 0);
+		f.addToProperty(key, new int[]{4,5});
+		assertObjectEquals("[0,1,2,3,4,5]", f.getProperty(key, int[].class, null));
+		f.addToProperty(key, new HashSet<String>(Arrays.asList("6","7")));
+		assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, int[].class, null));
+		f.addToProperty(key, new int[]{4,5});
+		assertObjectEquals("[0,1,2,3,4,5,6,7]", f.getProperty(key, int[].class, null));
+
+		f.removeFromProperty(key, 4);
+		f.removeFromProperty(key, new HashSet<String>(Arrays.asList("1")));
+		f.removeFromProperty(key, new String[]{"2","9"});
+		assertObjectEquals("[0,3,5,6,7]", f.getProperty(key, int[].class, null));
+		assertObjectEquals("['0','3','5','6','7']", f.getProperty(key, String[].class, null));
+
+		f.setProperty(key, Arrays.asList("foo","bar","baz"));
+		assertObjectEquals("['bar','baz','foo']", f.getProperty(key, String[].class, null));
+
+		f.setProperty(key, "[1,2,3]");
+		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
+
+		f.setProperty(key, "['1','2','3']");
+		assertObjectEquals("[1,2,3]", f.getProperty(key, int[].class, null));
+
+		try {
+			f.putToProperty("A.f1.set", "foo");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot put value 'foo' (java.lang.String) to property 'A.f1.set' (SET).", e.getMessage());
+		}
+
+		try {
+			f.putToProperty("A.f1.set", "foo", "bar");
+			fail("Exception expected");
+		} catch (Exception e) {
+			assertEquals("Cannot put value 'foo'(java.lang.String)->'bar'(java.lang.String) to property 'A.f1.set' (SET).", e.getMessage());
+		}
+	}
+
+	//====================================================================================================
+	// testListProperties()
+	//====================================================================================================
+	@Test
+	public void testListProperties() {
+		PropertyStore f = PropertyStore.create();
+		String key = "A.f1.list";
+
+		f.setProperty(key, Arrays.asList(2,3,1));
+		assertObjectEquals("[2,3,1]", f.getProperty(key, int[].class, null));
+
+		f.addToProperty(key, 0);
+		f.addToProperty(key, new int[]{4,5});
+		assertObjectEquals("[4,5,0,2,3,1]", f.getProperty(key, int[].class, null));
+		f.addToProperty(key, new TreeSet<String>(Arrays.asList("6","7")));
+		assertObjectEquals("[6,7,4,5,0,2,3,1]", f.getProperty(key, int[].class, null));
+		f.addToProperty(key, new int[]{4,5});
+		assertObjectEquals("[4,5,6,7,0,2,3,1]", f.getProperty(key, int[].class, null));
+
+		f.removeFromProperty(key, 4);
+		f.removeFromProperty(key, new HashSet<String>(Arrays.asList("1")));
+		f.removeFromProperty(key, new String[]{"2","9"});
+		assertObjectEquals("[5,6,7,0,3]", f.getProperty(key, int[].class, null));
+		assertObjectEquals("['5','6','7','0','3']", f.getProperty(key, String[].class, null));
+
+		f.setProperty(key, Arrays.asList("foo","bar","baz"));
+		assertObjectEquals("['foo','bar','baz']", f.getProperty(key, String[].class, null));
+	}
+
+	//====================================================================================================
+	// testMapProperties()
+	//====================================================================================================
+	@SuppressWarnings("serial")
+	@Test
+	public void testMapProperties() {
+		PropertyStore f = PropertyStore.create();
+		String key = "A.f1.map";
+
+		f.setProperty(key, new HashMap<String,String>(){{put("1","1");put("3","3");put("2","2");}});
+		assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, Integer.class, Integer.class, null));
+
+		f.setProperty(key, "{'1':1,'2':2,'3':3}");
+		assertObjectEquals("{'1':1,'2':2,'3':3}", f.getMap(key, Integer.class, Integer.class, null));
+
+		f.putToProperty(key, "{'3':4,'4':5,'5':6}");
+		assertObjectEquals("{'1':1,'2':2,'3':4,'4':5,'5':6}", f.getMap(key, Integer.class, Integer.class, null));
+	}
+
+	//====================================================================================================
+	// Hash code and comparison
+	//====================================================================================================
+	@SuppressWarnings({ "serial" })
+	@Test
+	public void testHashCodes() throws Exception {
+		PropertyStore f1 = PropertyStore.create();
+		f1.setProperty("A.a", 1);
+		f1.setProperty("A.b", true);
+		f1.setProperty("A.c", String.class);
+		f1.setProperty("A.d.set", new Object[]{1, true, String.class});
+		f1.setProperty("A.e.map", new HashMap<Object,Object>(){{put(true,true);put(1,1);put(String.class,String.class);}});
+
+		PropertyStore f2 = PropertyStore.create();
+		f2.setProperty("A.e.map", new HashMap<Object,Object>(){{put("1","1");put("true","true");put("java.lang.String","java.lang.String");}});
+		f2.setProperty("A.d.set", new Object[]{"true","1","java.lang.String"});
+		f2.setProperty("A.c", "java.lang.String");
+		f2.setProperty("A.b", "true");
+		f2.setProperty("A.a", "1");
+
+		PropertyStore.PropertyMap p1 = f1.getPropertyMap("A");
+		PropertyStore.PropertyMap p2 = f2.getPropertyMap("A");
+		assertEquals(p1.hashCode(), p2.hashCode());
+	}
+
+	@SuppressWarnings("unchecked")
+	private static class ConversionTest {
+		PropertyStore config = PropertyStore.create();
+		String pName;
+		Object in;
+
+		private ConversionTest(String pName, Object in) {
+			this.pName = pName;
+			this.in = in;
+		}
+
+		private ConversionTest test(Class c, String expected) {
+			try {
+				config.setProperty(pName, in);
+				assertObjectEquals(expected, config.getProperty(pName, c, null));
+			} catch (Exception x) {
+				assertEquals(expected.toString(), x.getLocalizedMessage());
+			}
+			return this;
+		}
+
+		private ConversionTest testMap(Class k, Class v, String expected) {
+			try {
+				config.setProperty(pName, in);
+				assertObjectEquals(expected, config.getMap(pName, k, v, null));
+			} catch (Exception x) {
+				assertEquals(expected, x.getLocalizedMessage());
+			}
+			return this;
+		}
+	}
+
+	//====================================================================================================
+	// Conversions on simple properties
+	//====================================================================================================
+	@Test
+	@SuppressWarnings({ "serial" })
+	public void testConversionsOnSimpleProperties() throws Exception {
+		String pName = "A.a";
+
+		//--------------------------------------------------------------------------------
+		// boolean
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, true)
+			.test(boolean.class, "true")
+			.test(int.class, "1")
+			.test(String.class, "'true'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class'.  Value=true.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=true.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.String[]'.  Value=true.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.lang.Class[]'.  Value=true.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=true.")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=true.")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Boolean' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=true.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// int
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, 123)
+			.test(boolean.class, "true")
+			.test(int.class, "123")
+			.test(String.class, "'123'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class'.  Value=123.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=123.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.String[]'.  Value=123.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.lang.Class[]'.  Value=123.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=123.")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=123.")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Integer' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=123.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, String.class)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'int'.  Value='java.lang.String'.")
+			.test(String.class, "'java.lang.String'")
+			.test(Class.class, "'java.lang.String'")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value='java.lang.String'.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.String[]'.  Value='java.lang.String'.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.lang.Class[]'.  Value='java.lang.String'.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='java.lang.String'.")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='java.lang.String'.")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='java.lang.String'.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, "foo")
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'int'.  Value='foo'.")
+			.test(String.class, "'foo'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class'.  Value='foo'.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value='foo'.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.String[]'.  Value='foo'.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.lang.Class[]'.  Value='foo'.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='foo'.")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='foo'.")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='foo'.")
+		;
+		new ConversionTest(pName, "java.lang.String")
+			.test(Class.class, "'java.lang.String'")
+		;
+		new ConversionTest(pName, "true")
+			.test(boolean.class, "true")
+		;
+		new ConversionTest(pName, "ONE")
+			.test(TestEnum.class, "'ONE'")
+		;
+		new ConversionTest(pName, "123")
+			.test(int.class, "123")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, TestEnum.ONE)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'int'.  Value='ONE'.")
+			.test(String.class, "'ONE'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class'.  Value='ONE'.")
+			.test(TestEnum.class, "'ONE'")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.String[]'.  Value='ONE'.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.lang.Class[]'.  Value='ONE'.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value='ONE'.")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value='ONE'.")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value='ONE'.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new String[]{"foo","bar"})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'int'.  Value=['foo','bar'].")
+			.test(String.class, "'[\\'foo\\',\\'bar\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.lang.Class'.  Value=['foo','bar'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['foo','bar'].")
+			.test(String[].class, "['foo','bar']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.lang.Class[]'.  Value=['foo','bar'].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['foo','bar'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['foo','bar'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.String[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['foo','bar'].")
+		;
+		new ConversionTest(pName, new String[]{"ONE","TWO"})
+			.test(TestEnum[].class, "['ONE','TWO']")
+		;
+		new ConversionTest(pName, new String[]{"true","false"})
+			.test(boolean[].class, "[true,false]")
+		;
+		new ConversionTest(pName, new String[]{"java.lang.String","java.lang.Integer"})
+			.test(Class[].class, "['java.lang.String','java.lang.Integer']")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Class[]{String.class,Integer.class})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'int'.  Value=['java.lang.String','java.lang.Integer'].")
+			.test(String.class, "'[\\'java.lang.String\\',\\'java.lang.Integer\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.lang.Class'.  Value=['java.lang.String','java.lang.Integer'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['java.lang.String','java.lang.Integer'].")
+			.test(String[].class, "['java.lang.String','java.lang.Integer']")
+			.test(Class[].class, "['java.lang.String','java.lang.Integer']")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['java.lang.String','java.lang.Integer'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.String','java.lang.Integer'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.lang.Class[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.String','java.lang.Integer'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'int'.  Value=['ONE','TWO'].")
+			.test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.lang.Class'.  Value=['ONE','TWO'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE','TWO'].")
+			.test(String[].class, "['ONE','TWO']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.lang.Class[]'.  Value=['ONE','TWO'].")
+			.test(TestEnum[].class, "['ONE','TWO']")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE','TWO'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'org.apache.juneau.PropertyStoreTest$TestEnum[]' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE','TWO'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<String,String>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
+		m1.put("foo","bar");
+		new ConversionTest(pName, m1)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'int'.  Value={foo:'bar'}.")
+			.test(String.class, "'{foo:\\'bar\\'}'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
+			.testMap(String.class, String.class, "{foo:'bar'}")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value={foo:'bar'}.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<Class,Class>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
+		m2.put(String.class, Integer.class);
+		new ConversionTest(pName, m2)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'int'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
+			.test(Class.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a'.  Invalid data conversion from type 'java.util.LinkedHashMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")
+			.testMap(Class.class, Class.class, "{'java.lang.String':'java.lang.Integer'}")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Namespace
+		//--------------------------------------------------------------------------------
+		final Namespace n = new Namespace("foo","bar");
+		new ConversionTest(pName, n)
+			.test(String.class, "'{name:\\'foo\\',uri:\\'bar\\'}'")
+			.test(Namespace.class, "{name:'foo',uri:'bar'}");
+
+		//--------------------------------------------------------------------------------
+		// Namespace[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Namespace[]{n})
+			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+			.test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
+
+		//--------------------------------------------------------------------------------
+		// Map<Namespace,Namespace>
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
+			.testMap(Namespace.class, Namespace.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
+			.testMap(String.class, String.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
+	}
+
+	//====================================================================================================
+	// Conversions on set properties
+	//====================================================================================================
+	@Test
+	@SuppressWarnings({ "serial" })
+	public void testConversionsOnSetProperties() throws Exception {
+		String pName = "A.a.set";
+
+		//--------------------------------------------------------------------------------
+		// boolean
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, true)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[true].")
+			.test(String.class, "'[true]'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[true].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[true].")
+			.test(String[].class, "['true']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[true].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[true].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[true].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[true].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// int
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, 123)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[123].")
+			.test(String.class, "'[123]'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[123].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[123].")
+			.test(String[].class, "['123']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[123].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[123].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[123].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[123].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, String.class)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['java.lang.String'].")
+			.test(String.class, "'[\\'java.lang.String\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['java.lang.String'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['java.lang.String'].")
+			.test(String[].class, "['java.lang.String']")
+			.test(Class[].class, "['java.lang.String']")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['java.lang.String'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.String'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.String'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, "foo")
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['foo'].")
+			.test(String.class, "'[\\'foo\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['foo'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['foo'].")
+			.test(String[].class, "['foo']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['foo'].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['foo'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['foo'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['foo'].")
+		;
+		new ConversionTest(pName, Arrays.asList("java.lang.String"))
+			.test(Class[].class, "['java.lang.String']")
+		;
+		new ConversionTest(pName, Arrays.asList("true"))
+			.test(boolean[].class, "[true]")
+		;
+		new ConversionTest(pName, Arrays.asList("ONE"))
+			.test(TestEnum[].class, "['ONE']")
+		;
+		new ConversionTest(pName, Arrays.asList("123"))
+			.test(int[].class, "[123]")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, TestEnum.ONE)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['ONE'].")
+			.test(String.class, "'[\\'ONE\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['ONE'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE'].")
+			.test(String[].class, "['ONE']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['ONE'].")
+			.test(TestEnum[].class, "['ONE']")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new String[]{"foo","bar"})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['bar','foo'].")
+			.test(String.class, "'[\\'bar\\',\\'foo\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['bar','foo'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['bar','foo'].")
+			.test(String[].class, "['bar','foo']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['bar','foo'].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['bar','foo'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['bar','foo'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['bar','foo'].")
+		;
+		new ConversionTest(pName, new String[]{"ONE","TWO"})
+			.test(TestEnum[].class, "['ONE','TWO']")
+		;
+		new ConversionTest(pName, new String[]{"true","false"})
+			.test(boolean[].class, "[false,true]")
+		;
+		new ConversionTest(pName, new String[]{"java.lang.String","java.lang.Integer"})
+			.test(Class[].class, "['java.lang.Integer','java.lang.String']")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Class[]{String.class,Integer.class})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['java.lang.Integer','java.lang.String'].")
+			.test(String.class, "'[\\'java.lang.Integer\\',\\'java.lang.String\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['java.lang.Integer','java.lang.String'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['java.lang.Integer','java.lang.String'].")
+			.test(String[].class, "['java.lang.Integer','java.lang.String']")
+			.test(Class[].class, "['java.lang.Integer','java.lang.String']")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=['java.lang.Integer','java.lang.String'].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['java.lang.Integer','java.lang.String'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['java.lang.Integer','java.lang.String'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=['ONE','TWO'].")
+			.test(String.class, "'[\\'ONE\\',\\'TWO\\']'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=['ONE','TWO'].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=['ONE','TWO'].")
+			.test(String[].class, "['ONE','TWO']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=['ONE','TWO'].")
+			.test(TestEnum[].class, "['ONE','TWO']")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=['ONE','TWO'].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=['ONE','TWO'].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<String,String>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
+		m1.put("foo","bar");
+		new ConversionTest(pName, m1)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[{foo:'bar'}].")
+			.test(String.class, "'[{foo:\\'bar\\'}]'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[{foo:'bar'}].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[{foo:'bar'}].")
+			.test(String[].class, "['{foo:\\'bar\\'}']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[{foo:'bar'}].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[{foo:'bar'}].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{foo:'bar'}].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[{foo:'bar'}].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<Class,Class>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
+		m2.put(String.class, Integer.class);
+		new ConversionTest(pName, m2)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'int'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.test(String.class, "'[{\\'java.lang.String\\':\\'java.lang.Integer\\'}]'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.test(String[].class, "['{\\'java.lang.String\\':\\'java.lang.Integer\\'}']")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.lang.Class[]'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value=[{'java.lang.String':'java.lang.Integer'}].")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Namespace
+		//--------------------------------------------------------------------------------
+		final Namespace n = new Namespace("foo","bar");
+		new ConversionTest(pName, Arrays.asList(n))
+			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+			.test(Namespace.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'org.apache.juneau.xml.Namespace'.  Value=[{name:'foo',uri:'bar'}].");
+
+		//--------------------------------------------------------------------------------
+		// Namespace[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Namespace[]{n})
+			.test(String.class, "'[{name:\\'foo\\',uri:\\'bar\\'}]'")
+			.test(Namespace[].class, "[{name:'foo',uri:'bar'}]");
+
+		//--------------------------------------------------------------------------------
+		// Map<Namespace,Namespace>
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
+			.testMap(Namespace.class, Namespace.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<org.apache.juneau.xml.Namespace,org.apache.juneau.xml.Namespace>'.  Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].")
+			.testMap(String.class, String.class, "Could not retrieve property store property 'A.a.set'.  Invalid data conversion from type 'java.util.concurrent.ConcurrentSkipListSet' to type 'java.util.LinkedHashMap<java.lang.String,java.lang.String>'.  Value=[{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}].");
+	}
+
+
+	//====================================================================================================
+	// Conversions on map properties
+	//====================================================================================================
+	@Test
+	@SuppressWarnings({ "serial" })
+	public void testConversionsOnMapProperties() throws Exception {
+		String pName = "A.a.map";
+
+		//--------------------------------------------------------------------------------
+		// boolean
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, true)
+			.test(boolean.class, "Cannot put value true (java.lang.Boolean) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// int
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, 123)
+			.test(int.class, "Cannot put value 123 (java.lang.Integer) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, String.class)
+			.test(Class.class, "Cannot put value 'java.lang.String' (java.lang.Class) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, "foo")
+			.test(String.class, "Cannot put value 'foo' (java.lang.String) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, TestEnum.ONE)
+			.test(TestEnum.class, "Cannot put value 'ONE' (org.apache.juneau.PropertyStoreTest$TestEnum) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// String[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new String[]{"foo","bar"})
+			.test(String[].class, "Cannot put value ['foo','bar'] (java.lang.String[]) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Class[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Class[]{String.class,Integer.class})
+			.test(Class[].class, "Cannot put value ['java.lang.String','java.lang.Integer'] (java.lang.Class[]) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// enum[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new TestEnum[]{TestEnum.ONE,TestEnum.TWO})
+			.test(TestEnum[].class, "Cannot put value ['ONE','TWO'] (org.apache.juneau.PropertyStoreTest$TestEnum[]) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<String,String>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<String,String> m1 = new LinkedHashMap<String,String>();
+		m1.put("foo","bar");
+		new ConversionTest(pName, m1)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'int'.  Value={foo:'bar'}.")
+			.test(String.class, "'{foo:\\'bar\\'}'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={foo:'bar'}.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={foo:'bar'}.")
+			.test(String[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={foo:'bar'}.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={foo:'bar'}.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={foo:'bar'}.")
+			.testMap(String.class, String.class, "{foo:'bar'}")
+			.testMap(Class.class, Class.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.util.LinkedHashMap<java.lang.Class,java.lang.Class>'.  Value={foo:'bar'}.")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<Class,Class>
+		//--------------------------------------------------------------------------------
+		LinkedHashMap<Class,Class> m2 = new LinkedHashMap<Class,Class>();
+		m2.put(String.class, Integer.class);
+		new ConversionTest(pName, m2)
+			.test(boolean.class, "false")
+			.test(int.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'int'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String.class, "'{\\'java.lang.String\\':\\'java.lang.Integer\\'}'")
+			.test(Class.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(TestEnum.class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(String[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.String[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(Class[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'java.lang.Class[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.test(TestEnum[].class, "Could not retrieve property store property 'A.a.map'.  Invalid data conversion from type 'java.util.Collections$SynchronizedMap' to type 'org.apache.juneau.PropertyStoreTest$TestEnum[]'.  Value={'java.lang.String':'java.lang.Integer'}.")
+			.testMap(String.class, String.class, "{'java.lang.String':'java.lang.Integer'}")
+			.testMap(Class.class, Class.class, "{'java.lang.String':'java.lang.Integer'}")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Namespace
+		//--------------------------------------------------------------------------------
+		final Namespace n = new Namespace("foo","bar");
+		new ConversionTest(pName, Arrays.asList(n))
+			.test(String.class, "Cannot put value [{name:'foo',uri:'bar'}] (java.util.Arrays$ArrayList) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Namespace[]
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new Namespace[]{n})
+			.test(String.class, "Cannot put value [{name:'foo',uri:'bar'}] (org.apache.juneau.xml.Namespace[]) to property 'A.a.map' (MAP).")
+		;
+
+		//--------------------------------------------------------------------------------
+		// Map<Namespace,Namespace>
+		//--------------------------------------------------------------------------------
+		new ConversionTest(pName, new LinkedHashMap<Namespace,Namespace>(){{put(n,n);}})
+			.testMap(Namespace.class, Namespace.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':{name:'foo',uri:'bar'}}")
+			.testMap(String.class, String.class, "{'{name:\\'foo\\',uri:\\'bar\\'}':'{name:\\'foo\\',uri:\\'bar\\'}'}");
+	}
+
+	public enum TestEnum {
+		ONE,TWO,TREE;
+	}
+
+	//====================================================================================================
+	// testSystemPropertyDefaults()
+	//====================================================================================================
+	@Test
+	public void testSystemPropertyDefaults() {
+		System.setProperty("Foo.f1", "true");
+		System.setProperty("Foo.f2", "123");
+		System.setProperty("Foo.f3", "TWO");
+
+		PropertyStore f = PropertyStore.create();
+
+		assertObjectEquals("true", f.getProperty("Foo.f1", boolean.class, false));
+		assertObjectEquals("123", f.getProperty("Foo.f2", int.class, 0));
+		assertObjectEquals("'TWO'", f.getProperty("Foo.f3", TestEnum.class, TestEnum.ONE));
+
+		f.setProperty("Foo.f1", false);
+		f.setProperty("Foo.f2", 456);
+		f.setProperty("Foo.f3", TestEnum.TREE);
+
+		assertObjectEquals("false", f.getProperty("Foo.f1", boolean.class, false));
+		assertObjectEquals("456", f.getProperty("Foo.f2", int.class, 0));
+		assertObjectEquals("'TREE'", f.getProperty("Foo.f3", TestEnum.class, TestEnum.ONE));
+	}
+
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java b/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
index a94fcca..ae075e8 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/TestUtils.java
@@ -37,21 +37,29 @@ import org.xml.sax.*;
 @SuppressWarnings({"javadoc"})
 public class TestUtils {
 
-	private static JsonSerializer js = new JsonSerializer.Simple()
-		.setTrimNullProperties(false);
-
-	private static JsonSerializer jsSorted = new JsonSerializer.Simple()
-		.setSortCollections(true)
-		.setSortMaps(true)
-		.setTrimNullProperties(false);
-
-
-	private static JsonSerializer js2 = new JsonSerializer.Simple()
-		.addPojoSwaps(IteratorSwap.class, EnumerationSwap.class);
-
-	private static JsonSerializer js3 = new JsonSerializer.Simple()
-		.addPojoSwaps(IteratorSwap.class, EnumerationSwap.class)
-		.setSortProperties(true);
+	private static JsonSerializer js = new JsonSerializerBuilder()
+		.simple()
+		.trimNullProperties(false)
+		.build();
+
+	private static JsonSerializer jsSorted = new JsonSerializerBuilder()
+		.simple()
+		.sortCollections(true)
+		.sortMaps(true)
+		.trimNullProperties(false)
+		.build();
+
+
+	private static JsonSerializer js2 = new JsonSerializerBuilder()
+		.simple()
+		.pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+		.build();
+
+	private static JsonSerializer js3 = new JsonSerializerBuilder()
+		.simple()
+		.pojoSwaps(IteratorSwap.class, EnumerationSwap.class)
+		.sortProperties(true)
+		.build();
 
 	/**
 	 * Verifies that two objects are equivalent.
@@ -219,7 +227,7 @@ public class TestUtils {
 	 * Test whitespace and generated schema.
 	 */
 	public static void validateXml(Object o, XmlSerializer s) throws Exception {
-		s = s.clone().setUseWhitespace(true).setEnableNamespaces(true).setAddNamespaceUrisToRoot(true);
+		s = s.builder().ws().ns().addNamespaceUrisToRoot(true).build();
 		String xml = s.serialize(o);
 
 		String xmlSchema = null;

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java b/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
index cff0fcb..3101903 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/VisibilityTest.java
@@ -27,131 +27,131 @@ public class VisibilityTest {
 	//====================================================================================================
 	@Test
 	public void testClassDefault() throws Exception {
-		JsonSerializer s1 = JsonSerializer.DEFAULT_LAX.clone().setBeansRequireSomeProperties(false);
-		JsonSerializer s2 = JsonSerializer.DEFAULT_LAX.clone().setBeansRequireSomeProperties(false).setBeanClassVisibility(PROTECTED);
-		JsonSerializer s3 = JsonSerializer.DEFAULT_LAX.clone().setBeansRequireSomeProperties(false).setBeanClassVisibility(Visibility.DEFAULT);
-		JsonSerializer s4 = JsonSerializer.DEFAULT_LAX.clone().setBeansRequireSomeProperties(false).setBeanClassVisibility(PRIVATE);
+		JsonSerializerBuilder s1 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false);
+		JsonSerializerBuilder s2 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(PROTECTED);
+		JsonSerializerBuilder s3 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(Visibility.DEFAULT);
+		JsonSerializerBuilder s4 = new JsonSerializerBuilder().simple().beansRequireSomeProperties(false).beanClassVisibility(PRIVATE);
 
 		A1 a1 = A1.create();
 		String r;
 
-		s1.setBeanFieldVisibility(NONE);
-		s2.setBeanFieldVisibility(NONE);
-		s3.setBeanFieldVisibility(NONE);
-		s4.setBeanFieldVisibility(NONE);
+		s1.beanFieldVisibility(NONE);
+		s2.beanFieldVisibility(NONE);
+		s3.beanFieldVisibility(NONE);
+		s4.beanFieldVisibility(NONE);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f5:5}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f5:5}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f5:5}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f5:5}", r);
 
-		s1.setBeanFieldVisibility(PUBLIC);
-		s2.setBeanFieldVisibility(PUBLIC);
-		s3.setBeanFieldVisibility(PUBLIC);
-		s4.setBeanFieldVisibility(PUBLIC);
+		s1.beanFieldVisibility(PUBLIC);
+		s2.beanFieldVisibility(PUBLIC);
+		s3.beanFieldVisibility(PUBLIC);
+		s4.beanFieldVisibility(PUBLIC);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:{f1:1,f5:5},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f5:5,g2:{f1:1,f5:5},g3:{f1:1,f5:5},g4:{f1:1,f5:5},g5:{f1:1,f5:5}}", r);
 
-		s1.setBeanFieldVisibility(PROTECTED);
-		s2.setBeanFieldVisibility(PROTECTED);
-		s3.setBeanFieldVisibility(PROTECTED);
-		s4.setBeanFieldVisibility(PROTECTED);
+		s1.beanFieldVisibility(PROTECTED);
+		s2.beanFieldVisibility(PROTECTED);
+		s3.beanFieldVisibility(PROTECTED);
+		s4.beanFieldVisibility(PROTECTED);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:{f1:1,f2:2,f5:5},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f5:5,g2:{f1:1,f2:2,f5:5},g3:{f1:1,f2:2,f5:5},g4:{f1:1,f2:2,f5:5},g5:{f1:1,f2:2,f5:5}}", r);
 
-		s1.setBeanFieldVisibility(Visibility.DEFAULT);
-		s2.setBeanFieldVisibility(Visibility.DEFAULT);
-		s3.setBeanFieldVisibility(Visibility.DEFAULT);
-		s4.setBeanFieldVisibility(Visibility.DEFAULT);
+		s1.beanFieldVisibility(Visibility.DEFAULT);
+		s2.beanFieldVisibility(Visibility.DEFAULT);
+		s3.beanFieldVisibility(Visibility.DEFAULT);
+		s4.beanFieldVisibility(Visibility.DEFAULT);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:{f1:1,f2:2,f3:3,f5:5},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f5:5,g2:{f1:1,f2:2,f3:3,f5:5},g3:{f1:1,f2:2,f3:3,f5:5},g4:{f1:1,f2:2,f3:3,f5:5},g5:{f1:1,f2:2,f3:3,f5:5}}", r);
 
-		s1.setBeanFieldVisibility(PRIVATE);
-		s2.setBeanFieldVisibility(PRIVATE);
-		s3.setBeanFieldVisibility(PRIVATE);
-		s4.setBeanFieldVisibility(PRIVATE);
+		s1.beanFieldVisibility(PRIVATE);
+		s2.beanFieldVisibility(PRIVATE);
+		s3.beanFieldVisibility(PRIVATE);
+		s4.beanFieldVisibility(PRIVATE);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:{f1:1,f2:2,f3:3,f4:4,f5:5},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,g2:{f1:1,f2:2,f3:3,f4:4,f5:5},g3:{f1:1,f2:2,f3:3,f4:4,f5:5},g4:{f1:1,f2:2,f3:3,f4:4,f5:5},g5:{f1:1,f2:2,f3:3,f4:4,f5:5}}", r);
 
-		s1.setMethodVisibility(NONE);
-		s2.setMethodVisibility(NONE);
-		s3.setMethodVisibility(NONE);
-		s4.setMethodVisibility(NONE);
+		s1.methodVisibility(NONE);
+		s2.methodVisibility(NONE);
+		s3.methodVisibility(NONE);
+		s4.methodVisibility(NONE);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:{f1:1,f2:2,f3:3,f4:4},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,g2:{f1:1,f2:2,f3:3,f4:4},g3:{f1:1,f2:2,f3:3,f4:4},g4:{f1:1,f2:2,f3:3,f4:4},g5:{f1:1,f2:2,f3:3,f4:4}}", r);
 
-		s1.setMethodVisibility(PROTECTED);
-		s2.setMethodVisibility(PROTECTED);
-		s3.setMethodVisibility(PROTECTED);
-		s4.setMethodVisibility(PROTECTED);
+		s1.methodVisibility(PROTECTED);
+		s2.methodVisibility(PROTECTED);
+		s3.methodVisibility(PROTECTED);
+		s4.methodVisibility(PROTECTED);
 
-		r = s1.serialize(a1);
+		r = s1.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:'A3',g4:'A4',g5:'A5'}", r);
 
-		r = s2.serialize(a1);
+		r = s2.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:'A4',g5:'A5'}", r);
 
-		r = s3.serialize(a1);
+		r = s3.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g5:'A5'}", r);
 
-		r = s4.serialize(a1);
+		r = s4.build().serialize(a1);
 		assertEquals("{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6,g2:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g3:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g4:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6},g5:{f1:1,f2:2,f3:3,f4:4,f5:5,f6:6}}", r);
 
 	}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java b/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
index 34a3ff9..ed182dd 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParser.java
@@ -30,7 +30,7 @@ import org.apache.juneau.xml.*;
 public class XmlValidatorParser extends XmlParser {
 
 	public XmlValidatorParser() {
-		super();
+		super(PropertyStore.create());
 	}
 
 	@Override /* Parser */
@@ -66,9 +66,4 @@ public class XmlValidatorParser extends XmlParser {
 		parser.nextTag();
 		return parser;
 	}
-
-	@Override /* Lockable */
-	public XmlValidatorParser clone() {
-		return (XmlValidatorParser)super.clone();
-	}
 }

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java b/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
new file mode 100644
index 0000000..f7ba051
--- /dev/null
+++ b/juneau-core-test/src/test/java/org/apache/juneau/XmlValidatorParserBuilder.java
@@ -0,0 +1,26 @@
+// ***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                                                              *
+// *                                                                                                                         *
+// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
+// *                                                                                                                         *
+// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the License.                                              *
+// ***************************************************************************************************************************
+package org.apache.juneau;
+
+import org.apache.juneau.xml.*;
+
+public class XmlValidatorParserBuilder extends XmlParserBuilder {
+	
+	public XmlValidatorParserBuilder() {
+		super(PropertyStore.create());
+	}
+
+	public XmlValidatorParser build() {
+		return new XmlValidatorParser();
+	}
+}

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
index cbf7630..d8e2388 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripAddClassAttrsTest.java
@@ -24,6 +24,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.serializer.*;
+import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
 import org.apache.juneau.xml.*;
 import org.junit.*;
@@ -41,68 +42,68 @@ public class RoundTripAddClassAttrsTest extends RoundTripTest {
 		return Arrays.asList(new Object[][] {
 			{ /* 0 */
 				"JsonSerializer.DEFAULT/JsonParser.DEFAULT",
-				new JsonSerializer().setAddBeanTypeProperties(true),
-				new JsonParser().setUseInterfaceProxies(false),
+				new JsonSerializerBuilder().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 1 */
 				"JsonSerializer.DEFAULT_LAX/JsonParser.DEFAULT",
-				new JsonSerializer.Simple().setAddBeanTypeProperties(true),
-				new JsonParser().setUseInterfaceProxies(false),
+				new JsonSerializerBuilder().simple().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 2 */
 				"JsonSerializer.DEFAULT_SQ/JsonParser.DEFAULT",
-				new JsonSerializer.Simple().setAddBeanTypeProperties(true),
-				new JsonParser().setUseInterfaceProxies(false),
+				new JsonSerializerBuilder().simple().addBeanTypeProperties(true),
+				new JsonParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 3 */
 				"XmlSerializer.DEFAULT/XmlParser.DEFAULT",
-				new XmlSerializer().setAddBeanTypeProperties(true),
-				new XmlParser().setUseInterfaceProxies(false),
+				new XmlSerializerBuilder().addBeanTypeProperties(true),
+				new XmlParserBuilder().useInterfaceProxies(false),
 				CHECK_XML_WHITESPACE | VALIDATE_XML
 			},
 			{ /* 4 */
 				"HtmlSerializer.DEFAULT/HtmlParser.DEFAULT",
-				new HtmlSerializer().setAddBeanTypeProperties(true),
-				new HtmlParser().setUseInterfaceProxies(false),
+				new HtmlSerializerBuilder().addBeanTypeProperties(true),
+				new HtmlParserBuilder().useInterfaceProxies(false),
 				CHECK_XML_WHITESPACE
 			},
 			{ /* 5 */
 				"UonSerializer.DEFAULT_ENCODING/UonParser.DEFAULT_DECODING",
-				new UonSerializer.Encoding().setAddBeanTypeProperties(true),
-				new UonParser.Decoding().setUseInterfaceProxies(false),
+				new UonSerializerBuilder().encoding().addBeanTypeProperties(true),
+				new UonParserBuilder().decoding().useInterfaceProxies(false),
 				0
 			},
 			{ /* 6 */
 				"UonSerializer.DEFAULT/UonParser.DEFAULT",
-				new UonSerializer().setAddBeanTypeProperties(true),
-				new UonParser().setUseInterfaceProxies(false),
+				new UonSerializerBuilder().addBeanTypeProperties(true),
+				new UonParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 7 */
 				"UrlEncodingSerializer.DEFAULT/UrlEncodingParser.DEFAULT",
-				new UrlEncodingSerializer().setAddBeanTypeProperties(true),
-				new UrlEncodingParser().setUseInterfaceProxies(false),
+				new UrlEncodingSerializerBuilder().addBeanTypeProperties(true),
+				new UrlEncodingParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 8 */
 				"RdfSerializer.Xml/RdfParser.Xml",
-				new RdfSerializer.Xml().setAddBeanTypeProperties(true),
-				new RdfParser.Xml().setUseInterfaceProxies(false),
+				new RdfSerializerBuilder().addBeanTypeProperties(true),
+				new RdfParserBuilder().useInterfaceProxies(false),
 				0
 			},
 			{ /* 9 */
 				"MsgPackSerializer.DEFAULT/MsgPackParser.DEFAULT",
-				new MsgPackSerializer().setAddBeanTypeProperties(true),
-				new MsgPackParser().setUseInterfaceProxies(false),
+				new MsgPackSerializerBuilder().addBeanTypeProperties(true),
+				new MsgPackParserBuilder().useInterfaceProxies(false),
 				0
 			}
 		});
 	}
 
-	public RoundTripAddClassAttrsTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripAddClassAttrsTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}
 

http://git-wip-us.apache.org/repos/asf/incubator-juneau/blob/95e832e1/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
----------------------------------------------------------------------
diff --git a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
index 0c4eef6..dfe8dd6 100755
--- a/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
+++ b/juneau-core-test/src/test/java/org/apache/juneau/a/rttests/RoundTripBeanInheritanceTest.java
@@ -27,7 +27,7 @@ import org.junit.*;
 @SuppressWarnings("javadoc")
 public class RoundTripBeanInheritanceTest extends RoundTripTest {
 
-	public RoundTripBeanInheritanceTest(String label, Serializer s, Parser p, int flags) throws Exception {
+	public RoundTripBeanInheritanceTest(String label, SerializerBuilder s, ParserBuilder p, int flags) throws Exception {
 		super(label, s, p, flags);
 	}