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:51:01 UTC

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

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.");
 			}
 		}
 	}