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 2020/03/05 01:47:32 UTC

[juneau] branch master updated: New RestClient API.

This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git


The following commit(s) were added to refs/heads/master by this push:
     new d2d9d0a  New RestClient API.
d2d9d0a is described below

commit d2d9d0a2256cf5d2a5b618eaefead35373397be3
Author: JamesBognar <ja...@apache.org>
AuthorDate: Wed Mar 4 20:47:08 2020 -0500

    New RestClient API.
---
 TODO.txt                                           |   43 +
 eclipse-preferences/user-dictionary.txt            |    1 +
 .../transforms/StackTraceElementSwapTest.java      |  115 +-
 .../java/org/apache/juneau/jena/RdfParser.java     |   17 +-
 .../java/org/apache/juneau/jena/RdfSerializer.java |   16 +-
 .../src/main/java/org/apache/juneau/BeanMeta.java  |   18 +-
 .../src/main/java/org/apache/juneau/ObjectMap.java |   18 +
 .../main/java/org/apache/juneau/http/Accept.java   |   15 +-
 .../java/org/apache/juneau/http/AcceptCharset.java |   11 +-
 .../org/apache/juneau/http/AcceptEncoding.java     |   11 +-
 .../org/apache/juneau/http/AcceptLanguage.java     |   11 +-
 .../java/org/apache/juneau/http/AcceptRanges.java  |   11 +-
 .../src/main/java/org/apache/juneau/http/Age.java  |   13 +-
 .../main/java/org/apache/juneau/http/Allow.java    |    6 +-
 .../java/org/apache/juneau/http/Authorization.java |    4 +-
 .../http/{HeaderDate.java => BasicDateHeader.java} |    6 +-
 .../http/{HeaderEnum.java => BasicEnumHeader.java} |    7 +-
 .../http/{HeaderDate.java => BasicHeader.java}     |   49 +-
 ...{HeaderInteger.java => BasicIntegerHeader.java} |   31 +-
 .../http/{HeaderLong.java => BasicLongHeader.java} |   28 +-
 ...tringArray.java => BasicStringArrayHeader.java} |   22 +-
 .../{HeaderString.java => BasicStringHeader.java}  |   34 +-
 .../java/org/apache/juneau/http/CacheControl.java  |    4 +-
 ...java => ComplexEntityValidatorArrayHeader.java} |   11 +-
 .../java/org/apache/juneau/http/ComplexHeader.java |   74 +-
 ...angeArray.java => ComplexRangeArrayHeader.java} |   11 +-
 .../java/org/apache/juneau/http/Connection.java    |    6 +-
 .../org/apache/juneau/http/ContentEncoding.java    |    4 +-
 .../org/apache/juneau/http/ContentLanguage.java    |    6 +-
 .../java/org/apache/juneau/http/ContentLength.java |    6 +-
 .../org/apache/juneau/http/ContentLocation.java    |    2 +-
 .../java/org/apache/juneau/http/ContentRange.java  |    4 +-
 .../java/org/apache/juneau/http/ContentType.java   |   13 +-
 .../src/main/java/org/apache/juneau/http/Date.java |    6 +-
 .../src/main/java/org/apache/juneau/http/ETag.java |    4 +-
 .../main/java/org/apache/juneau/http/Expect.java   |    4 +-
 .../main/java/org/apache/juneau/http/Expires.java  |    4 +-
 .../src/main/java/org/apache/juneau/http/From.java |    4 +-
 .../java/org/apache/juneau/http/HeaderUri.java     |    7 +-
 .../src/main/java/org/apache/juneau/http/Host.java |    4 +-
 .../java/org/apache/juneau/http/HttpHeader.java    |   68 +-
 .../java/org/apache/juneau/http/HttpMethod.java    |   39 +-
 .../main/java/org/apache/juneau/http/IfMatch.java  |    4 +-
 .../org/apache/juneau/http/IfModifiedSince.java    |    4 +-
 .../java/org/apache/juneau/http/IfNoneMatch.java   |    4 +-
 .../main/java/org/apache/juneau/http/IfRange.java  |   10 +-
 .../org/apache/juneau/http/IfUnmodifiedSince.java  |    4 +-
 .../java/org/apache/juneau/http/LastModified.java  |    4 +-
 .../main/java/org/apache/juneau/http/Location.java |    2 +-
 .../java/org/apache/juneau/http/MaxForwards.java   |    6 +-
 .../java/org/apache/juneau/http/MediaType.java     |    2 +-
 .../main/java/org/apache/juneau/http/Pragma.java   |    4 +-
 .../org/apache/juneau/http/ProxyAuthenticate.java  |    4 +-
 .../org/apache/juneau/http/ProxyAuthorization.java |    4 +-
 .../main/java/org/apache/juneau/http/Range.java    |    4 +-
 .../main/java/org/apache/juneau/http/Referer.java  |    2 +-
 .../java/org/apache/juneau/http/RetryAfter.java    |   10 +-
 .../main/java/org/apache/juneau/http/Server.java   |    4 +-
 .../src/main/java/org/apache/juneau/http/TE.java   |    4 +-
 .../main/java/org/apache/juneau/http/Trailer.java  |    4 +-
 .../org/apache/juneau/http/TransferEncoding.java   |    4 +-
 .../main/java/org/apache/juneau/http/Upgrade.java  |    6 +-
 .../java/org/apache/juneau/http/UserAgent.java     |    4 +-
 .../src/main/java/org/apache/juneau/http/Vary.java |    4 +-
 .../src/main/java/org/apache/juneau/http/Via.java  |    6 +-
 .../main/java/org/apache/juneau/http/Warning.java  |    4 +-
 .../org/apache/juneau/http/WwwAuthenticate.java    |    4 +-
 .../org/apache/juneau/internal/StringUtils.java    |   23 +
 .../HeaderLong.java => mstat/ExceptionHasher.java} |   76 +-
 .../org/apache/juneau/mstat/ExceptionInfo.java     |  141 +
 .../org/apache/juneau/mstat/ExceptionStats.java    |  128 +
 .../org/apache/juneau/mstat/ExceptionStore.java    |  136 +
 .../org/apache/juneau/mstat/MethodExecStats.java   |  182 ++
 .../java/org/apache/juneau/mstat/package-info.java |   20 +-
 .../org/apache/juneau/transform/DefaultSwaps.java  |    3 +
 .../apache/juneau/transforms/MatchResultSwap.java  |   31 +-
 .../StackTraceElementSwap.java}                    |  146 +-
 .../main/java/org/apache/juneau/utils/Mutable.java |  130 +
 juneau-doc/docs/ReleaseNotes/8.1.4.html            |   18 +-
 .../21.JsonDetails/02.Serializers.html             |    3 +-
 .../21.JsonDetails/04.Parsers.html                 |    3 +-
 .../22.XmlDetails/02.Serializers.html              |    3 +-
 .../22.XmlDetails/03.Parsers.html                  |    3 +-
 .../23.HtmlDetails/02.Serializers.html             |    3 +-
 .../23.HtmlDetails/03.Parsers.html                 |    3 +-
 .../24.UonDetails/02.Serializers.html              |    3 +-
 .../24.UonDetails/03.Parsers.html                  |    3 +-
 .../25.UrlEncodingDetails/02.Serializers.html      |    3 +-
 .../25.UrlEncodingDetails/03.Parsers.html          |    3 +-
 .../26.MsgPackDetails/01.Serializers.html          |    3 +-
 .../26.MsgPackDetails/02.Parsers.html              |    3 +-
 .../01.RdfDetails/01.Serializers.html              |    3 +-
 .../01.RdfDetails/02.Parsers.html                  |    3 +-
 .../Topics/06.juneau-rest-server/07.restRPC.html   |   12 +-
 .../33.LoggingAndDebugging.html                    |    2 +-
 juneau-doc/docs/Topics/09.juneau-rest-client.html  |   85 +-
 .../09.juneau-rest-client/01.RestProxies.html      |    8 +-
 ....Authentication.html => 02.Authentication.html} |    0
 .../01.BASIC.html                                  |    2 +-
 .../02.FORM.html                                   |    6 +-
 .../03.OIDC.html                                   |    0
 .../docs/Topics/09.juneau-rest-client/02.SSL.html  |   50 -
 ...ponsePatterns.html => 03.ResponsePatterns.html} |    2 +-
 .../{05.PipingOutput.html => 04.PipingOutput.html} |    0
 .../{06.Debugging.html => 05.Debugging.html}       |    4 +-
 .../{07.Logging.html => 06.Logging.html}           |    6 +-
 .../{08.Interceptors.html => 07.Interceptors.html} |    3 +-
 .../{09.Other.html => 08.Other.html}               |   23 +-
 .../Topics/10.juneau-rest-mock/02.MockRemote.html  |    4 +-
 .../Topics/19.juneau-petstore/04.PetstoreApp.html  |   15 +
 juneau-doc/src/main/javadoc/overview.html          |  468 +--
 juneau-doc/src/main/javadoc/resources/docs.txt     |   11 +-
 .../src/main/javadoc/resources/fragments/toc.html  |   21 +-
 .../src/main/javadoc/resources/juneau-code.css     |   13 +-
 .../src/main/javadoc/resources/juneau-doc.css      |   15 +-
 .../juneau/examples/rest/ContentComboTestBase.java |    5 +-
 .../juneau/examples/rest/RootContentTest.java      |   45 +-
 .../juneau/examples/rest/RootResourcesTest.java    |   76 +-
 .../juneau/examples/rest/SamplesMicroservice.java  |    2 +-
 .../juneau/microservice/testutils/TestUtils.java   |    2 +-
 .../org/apache/juneau/rest/test/ConfigTest.java    |   26 +-
 .../org/apache/juneau/rest/test/MockRestTest.java  |    6 +-
 .../org/apache/juneau/rest/test/RestTestcase.java  |    2 +-
 .../apache/juneau/rest/test/TestMicroservice.java  |   16 +-
 .../rest/test/client/CallbackStringsTest.java      |   16 +-
 .../juneau/rest/test/client/ClientFuturesTest.java |   19 +-
 .../juneau/rest/test/client/FormDataTest.java      |   24 +-
 .../rest/test/client/RequestBeanProxyTest.java     |   18 +-
 .../juneau/rest/test/client/RestClientTest.java    |  148 +-
 .../rest/test/client/ThirdPartyProxyTest.java      |    2 +-
 .../{client => client2}/BodyAnnotationTest.java    |    3 +-
 .../{client => client2}/EndToEndInterfaceTest.java |    2 +-
 .../FormDataAnnotationTest.java                    |    3 +-
 .../{client => client2}/HeaderAnnotationTest.java  |    3 +-
 .../{client => client2}/PathAnnotationTest.java    |    3 +-
 .../{client => client2}/QueryAnnotationTest.java   |    5 +-
 .../RemoteMethodAnnotationTest.java                |    2 +-
 .../RemoteResourceAnnotationTest.java              |    2 +-
 .../{client => client2}/RequestAnnotationTest.java |    4 +-
 .../ResponseAnnotationTest.java                    |    4 +-
 .../juneau/rest/client/AllowAllRedirects.java      |    3 +
 .../org/apache/juneau/rest/client/DateHeader.java  |    8 +-
 .../org/apache/juneau/rest/client/HttpMethod.java  |    3 +
 .../apache/juneau/rest/client/NameValuePairs.java  |    3 +
 .../apache/juneau/rest/client/ResponsePattern.java |    3 +
 .../org/apache/juneau/rest/client/RestCall.java    |    3 +
 .../juneau/rest/client/RestCallException.java      |    3 +
 .../apache/juneau/rest/client/RestCallHandler.java |    3 +
 .../juneau/rest/client/RestCallInterceptor.java    |    3 +
 .../apache/juneau/rest/client/RestCallLogger.java  |    3 +
 .../org/apache/juneau/rest/client/RestClient.java  |    3 +
 .../juneau/rest/client/RestClientBuilder.java      |    6 +
 .../juneau/rest/client/RestRequestEntity.java      |    3 +
 .../org/apache/juneau/rest/client/RetryOn.java     |    4 +
 .../rest/client/SerializedNameValuePair.java       |    3 +
 .../juneau/rest/client/SimpleX509TrustManager.java |    3 +
 .../{client => client2}/RestCallException.java     |   49 +-
 .../rest/{client => client2}/RestCallHandler.java  |   51 +-
 .../{client => client2}/RestCallInterceptor.java   |   41 +-
 .../org/apache/juneau/rest/client2/RestClient.java | 3095 ++++++++++++++++++++
 .../{client => client2}/RestClientBuilder.java     | 1320 ++++++---
 .../apache/juneau/rest/client2/RestRequest.java    | 2737 +++++++++++++++++
 .../apache/juneau/rest/client2/RestResponse.java   |  634 ++++
 .../juneau/rest/client2/RestResponseBody.java      | 1880 ++++++++++++
 .../juneau/rest/client2/RestResponseHeader.java    |  714 +++++
 .../ext/AllRedirectsStrategy.java}                 |    4 +-
 .../ext/BasicHttpRequestRetryHandler.java}         |   90 +-
 .../{client => client2/ext}/NameValuePairs.java    |   65 +-
 .../ext/SerializedHttpEntity.java}                 |    8 +-
 .../rest/client2/ext/SerializedNameValuePair.java  |  195 ++
 .../rest/client2/ext/SimpleNameValuePair.java      |  107 +-
 .../juneau/rest/client2/ext/package-info.java      |   20 +-
 .../rest/client2/logging/BasicRestCallLogger.java  |  132 +-
 .../client2/logging/ConsoleRestCallLogger.java     |  107 +-
 .../rest/client2/logging/RestCallLogger.java       |  120 +
 .../juneau/rest/client2/logging/package-info.java  |   20 +-
 .../apache/juneau/rest/client2/package-info.java   |   20 +-
 .../org/apache/juneau/rest/mock2/MockRemote.java   |    2 +-
 .../apache/juneau/rest/mock2/MockRestClient.java   |    2 +-
 .../juneau/rest/mock2/MockServletRequest.java      |    4 +-
 .../apache/juneau/rest/BasicRestCallLogger.java    |    4 +-
 .../main/java/org/apache/juneau/rest/RestCall.java |   23 +
 .../org/apache/juneau/rest/RestCallRouter.java     |    8 +-
 .../java/org/apache/juneau/rest/RestContext.java   |   46 +
 .../org/apache/juneau/rest/RestMethodContext.java  |   22 +
 .../java/org/apache/juneau/rest/StatusStats.java   |   94 +
 pom.xml                                            |    5 +-
 187 files changed, 12925 insertions(+), 1895 deletions(-)

diff --git a/TODO.txt b/TODO.txt
new file mode 100644
index 0000000..3a80929
--- /dev/null
+++ b/TODO.txt
@@ -0,0 +1,43 @@
+	// TODO - Add a new RestCallLogger that sends the result to the console.
+	TODO: wrapper for httpClient.getState();
+	TODO: header() and query() should persist objects that can be converted to strings at runtime.
+	
+	ContentDisposition header bean.
+	StreamResource/ReaderResource classes should take in header beans.
+	
+	Need the ability to turn on debug in REST via environment variables (e.g. debug=MyServlet.myMethod)
+	$Contains{} variable.
+	
+	
+	TODO:  @BeanConfig(bpi) doesn't override @Bean(bpi)?
+	
+
+TODO - This isn't working.	
+	    public static class InstanceMetrics {
+    	public List<SimpleMetric> instance = new ArrayList<>();
+    	public Map<Integer,List<SimpleMetric>> racNode = new TreeMap<>();
+    	public Map<Integer,List<SimpleMetric>> partition = new TreeMap<>();
+    }
+
+    @Bean(bpi="name,value,received")
+    @Html(noTableHeaders=true)
+    public static class SimpleMetric {
+    	public String name;
+    	public Long value;
+    	public Calendar received;
+
+    	public SimpleMetric(Metric m) {
+    		this.name = m.getMetric();
+    		this.value = m.getValue();
+    		this.received = m.getReceived();
+    	}
+    }
+    
+TODO @Beanp(*) isn't working?
+    public static class InstanceCopySummary {
+    	public String instance;
+    	public int total;
+    	@Beanp(name="*")
+    	public Map<String,Integer> perPartition = new TreeMap<>();
+
+TODO:  Need a SimpleLink(name, uri) again.
\ No newline at end of file
diff --git a/eclipse-preferences/user-dictionary.txt b/eclipse-preferences/user-dictionary.txt
index d146886..ce41e11 100644
--- a/eclipse-preferences/user-dictionary.txt
+++ b/eclipse-preferences/user-dictionary.txt
@@ -500,3 +500,4 @@ enablement
 stacktraces
 timezones
 beanp
+irs
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/StackTraceElementSwapTest.java
similarity index 50%
copy from juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java
copy to juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/StackTraceElementSwapTest.java
index ed7cb83..943239d 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java
+++ b/juneau-core/juneau-core-utest/src/test/java/org/apache/juneau/transforms/StackTraceElementSwapTest.java
@@ -1,59 +1,56 @@
-// ***************************************************************************************************************************
-// * 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 static org.apache.juneau.http.HttpMethodName.*;
-import static org.junit.Assert.*;
-
-import org.apache.juneau.http.annotation.Body;
-import org.apache.juneau.json.*;
-import org.apache.juneau.marshall.*;
-import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
-import org.apache.juneau.rest.mock2.*;
-import org.junit.*;
-import org.junit.runners.*;
-
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-public class MockRestTest {
-
-	//=================================================================================================================
-	// Basic tests
-	//=================================================================================================================
-
-	@Rest
-	public static class A {
-		@RestMethod(name=PUT, path="/a01")
-		public String a01(@Body String body) {
-			return body;
-		}
-
-		@RestMethod(name=PUT, path="/a02", serializers=JsonSerializer.class, parsers=JsonParser.class)
-		public String a02(@Body String body) {
-			return body;
-		}
-	}
-
-	@Test
-	public void a01() throws Exception {
-		RestClient rc = MockRestClient.build(A.class, null);
-		assertEquals("OK", rc.doPut("/a01", "OK").getResponseAsString());
-	}
-
-	@Test
-	public void a02() throws Exception {
-		RestClient rc = MockRestClient.build(A.class, Json.DEFAULT);
-		assertEquals("OK", rc.doPut("/a02", "OK").getResponse(String.class));
-	}
-}
-
+// ***************************************************************************************************************************
+// * 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.transforms;
+
+import static org.junit.Assert.*;
+
+import org.apache.juneau.marshall.*;
+import org.junit.*;
+
+/**
+ * Tests the {@link StackTraceElementSwap} class.
+ */
+public class StackTraceElementSwapTest {
+
+	private String write(StackTraceElement ste) {
+		return SimpleJson.DEFAULT.toString(ste);
+	}
+
+	private StackTraceElement read(String in) throws Exception {
+		return SimpleJson.DEFAULT.read(in, StackTraceElement.class);
+	}
+
+	//------------------------------------------------------------------------------------------------------------------
+	// Basic tests
+	//------------------------------------------------------------------------------------------------------------------
+	@Test
+	public void basicTests() throws Exception {
+		StackTraceElement ste;
+
+		ste = new StackTraceElement("foo.bar.Baz", "qux", "Baz.java", 123);
+		assertEquals("'foo.bar.Baz.qux(Baz.java:123)'", write(ste));
+		assertEquals("'foo.bar.Baz.qux(Baz.java:123)'", write(read("'foo.bar.Baz.qux(Baz.java:123)'")));
+
+		ste = new StackTraceElement("foo.bar.Baz", "qux", "Baz.java", -2);
+		assertEquals("'foo.bar.Baz.qux(Native Method)'", write(ste));
+		assertEquals("'foo.bar.Baz.qux(Native Method)'", write(read("'foo.bar.Baz.qux(Native Method)'")));
+
+		ste = new StackTraceElement("foo.bar.Baz", "qux", null, 0);
+		assertEquals("'foo.bar.Baz.qux(Unknown Source)'", write(ste));
+		assertEquals("'foo.bar.Baz.qux(Unknown Source)'", write(read("'foo.bar.Baz.qux(Unknown Source)'")));
+
+		ste = new StackTraceElement("foo.bar.Baz", "qux", "Baz.java", -1);
+		assertEquals("'foo.bar.Baz.qux(Baz.java)'", write(ste));
+		assertEquals("'foo.bar.Baz.qux(Baz.java)'", write(read("'foo.bar.Baz.qux(Baz.java)'")));
+	}
+}
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
index 538735f..1f0f1c9 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfParser.java
@@ -149,7 +149,22 @@ public class RdfParser extends ReaderParser implements RdfCommon, RdfMetaProvide
 	 * @param ps The property store containing all the settings for this object.
 	 */
 	public RdfParser(PropertyStore ps) {
-		this(ps, "text/xml+rdf");
+		this(ps, getConsumes(ps));
+	}
+
+	private static String getConsumes(PropertyStore ps) {
+		String rdfLanguage = ps.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
+		switch(rdfLanguage) {
+			case "RDF/XML":
+			case "RDF/XML-ABBREV": return "text/xml+rdf";
+			case "N-TRIPLE": return "text/n-triple";
+			case "N3": return "text/n3";
+			case "N3-PP": return "text/n3-pp";
+			case "N3-PLAIN": return "text/n3-plain";
+			case "N3-TRIPLES": return "text/n3-triples";
+			case "TURTLE": return "text/turtle";
+			default: return "text/xml+rdf";
+		}
 	}
 
 	@Override /* Context */
diff --git a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
index 45d98c1..94542c5 100644
--- a/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
+++ b/juneau-core/juneau-marshall-rdf/src/main/java/org/apache/juneau/jena/RdfSerializer.java
@@ -317,9 +317,23 @@ public class RdfSerializer extends WriterSerializer implements RdfCommon, RdfMet
 	 * 	The property store containing all the settings for this object.
 	 */
 	public RdfSerializer(PropertyStore ps) {
-		this(ps, "text/xml+rdf", (String)null);
+		this(ps, getProduces(ps), (String)null);
 	}
 
+	private static String getProduces(PropertyStore ps) {
+		String rdfLanguage = ps.getProperty(RDF_language, String.class, "RDF/XML-ABBREV");
+		switch(rdfLanguage) {
+			case "RDF/XML": return "text/xml+rdf+abbrev";
+			case "RDF/XML-ABBREV": return "text/xml+rdf";
+			case "N-TRIPLE": return "text/n-triple";
+			case "N3": return "text/n3";
+			case "N3-PP": return "text/n3-pp";
+			case "N3-PLAIN": return "text/n3-plain";
+			case "N3-TRIPLES": return "text/n3-triples";
+			case "TURTLE": return "text/turtle";
+			default: return "text/xml+rdf";
+		}
+	}
 
 	@Override /* Context */
 	public RdfSerializerBuilder builder() {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
index 3758c7a..808c056 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BeanMeta.java
@@ -205,7 +205,7 @@ public class BeanMeta<T> {
 				if (! (cVis.isVisible(c.getModifiers()) || c.isAnonymousClass()))
 					return "Class is not public";
 
-				if (ctx.hasAnnotation(BeanIgnore.class, c))
+				if (isIgnored(c))
 					return "Class is annotated with @BeanIgnore";
 
 				// Make sure it's serializable.
@@ -482,6 +482,22 @@ public class BeanMeta<T> {
 			return null;
 		}
 
+		private boolean isIgnored(Class<?> c) {
+			if (c == null)
+				return false;
+			if (ctx.hasDeclaredAnnotation(BeanIgnore.class, c))
+				return true;
+			if (ctx.hasDeclaredAnnotation(Bean.class, c))
+				return false;
+			for (Class<?> ci : c.getInterfaces()) {
+				if (ctx.hasDeclaredAnnotation(BeanIgnore.class, ci))
+					return true;
+				if (ctx.hasDeclaredAnnotation(Bean.class, ci))
+					return false;
+			}
+			return isIgnored(c.getSuperclass());
+		}
+
 		private String findDictionaryName(ClassMeta<?> cm) {
 			BeanRegistry br = cm.getBeanRegistry();
 			if (br != null) {
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
index f0e7145..8194cfc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/ObjectMap.java
@@ -200,6 +200,24 @@ public class ObjectMap extends LinkedHashMap<String,Object> {
 		parseReader(r, JsonParser.DEFAULT);
 	}
 
+	/**
+	 * Construct a JSON map and fill it with the specified freeform key-value pairs.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode w800'>
+	 * 	ObjectMap m = <jk>new</jk> ObjectMap(<js>"key1"</js>,<js>"val1"</js>,<js>"key2"</js>,<js>"val2"</js>);
+	 * </p>
+	 *
+	 * @param o A list of key/value pairs to add to this map.
+	 */
+	public ObjectMap(Object... o) {
+		if (o.length % 2 != 0)
+			throw new RuntimeException("Odd number of parameters passed into ObjectMap(Object...)");
+		for (int i = 0; i < o.length; i+=2)
+			put(stringify(o[i]), o[i+1]);
+	}
+
+
 	private void parseReader(Reader r, Parser p) throws ParseException {
 		if (p == null)
 			p = JsonParser.DEFAULT;
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
index 426ec49..271a266 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Accept.java
@@ -144,7 +144,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Accept")
-public final class Accept {
+public final class Accept extends ComplexHeader {
 
 	private static final Cache<String,Accept> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -167,7 +167,13 @@ public final class Accept {
 	private final MediaTypeRange[] mediaRanges;
 	private final List<MediaTypeRange> mediaRangesList;
 
-	private Accept(String value) {
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public Accept(String value) {
+		super("Accept");
 		this.mediaRanges = MediaTypeRange.parse(value);
 		this.mediaRangesList = immutableList(mediaRanges);
 	}
@@ -294,4 +300,9 @@ public final class Accept {
 	public String toString() {
 		return join(mediaRanges, ',');
 	}
+
+	@Override /* HttpHeader */
+	public Object getValue() {
+		return toString();
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptCharset.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptCharset.java
index ac1a377..0a457a7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptCharset.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptCharset.java
@@ -71,7 +71,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Accept-Charset")
-public final class AcceptCharset extends HeaderRangeArray {
+public final class AcceptCharset extends ComplexRangeArrayHeader {
 
 	private static final Cache<String,AcceptCharset> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -90,7 +90,12 @@ public final class AcceptCharset extends HeaderRangeArray {
 		return a;
 	}
 
-	private AcceptCharset(String value) {
-		super(value);
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public AcceptCharset(String value) {
+		super("Accept-Charset", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptEncoding.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptEncoding.java
index d3dd98f..ec612af 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptEncoding.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptEncoding.java
@@ -91,7 +91,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Accept-Encoding")
-public final class AcceptEncoding extends HeaderRangeArray {
+public final class AcceptEncoding extends ComplexRangeArrayHeader {
 
 	private static final Cache<String,AcceptEncoding> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -110,7 +110,12 @@ public final class AcceptEncoding extends HeaderRangeArray {
 		return a;
 	}
 
-	private AcceptEncoding(String value) {
-		super(value);
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public AcceptEncoding(String value) {
+		super("Accept-Encoding", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptLanguage.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptLanguage.java
index 2475a0d..8565bf3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptLanguage.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptLanguage.java
@@ -103,7 +103,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Accept-Language")
-public final class AcceptLanguage extends HeaderRangeArray {
+public final class AcceptLanguage extends ComplexRangeArrayHeader {
 
 	private static final Cache<String,AcceptLanguage> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -122,7 +122,12 @@ public final class AcceptLanguage extends HeaderRangeArray {
 		return a;
 	}
 
-	private AcceptLanguage(String raw) {
-		super(raw);
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public AcceptLanguage(String value) {
+		super("Accept-Language", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptRanges.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptRanges.java
index d13cd67..f8c9177 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptRanges.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/AcceptRanges.java
@@ -61,7 +61,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Accept-Ranges")
-public final class AcceptRanges extends HeaderString {
+public final class AcceptRanges extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Accept-Ranges</c> header.
@@ -75,7 +75,12 @@ public final class AcceptRanges extends HeaderString {
 		return new AcceptRanges(value);
 	}
 
-	private AcceptRanges(String value) {
-		super(value);
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public AcceptRanges(Object value) {
+		super("Accept-Ranges", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Age.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Age.java
index 770ed43..dc98f0c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Age.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Age.java
@@ -56,7 +56,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Age")
-public final class Age extends HeaderInteger {
+public final class Age extends BasicIntegerHeader {
 
 	/**
 	 * Constructor.
@@ -64,7 +64,7 @@ public final class Age extends HeaderInteger {
 	 * @param value The value for this header.
 	 */
 	public Age(Integer value) {
-		super(value);
+		super("Age", value);
 	}
 
 	/**
@@ -79,7 +79,12 @@ public final class Age extends HeaderInteger {
 		return new Age(value);
 	}
 
-	private Age(String value) {
-		super(value);
+	/**
+	 * Constructor
+	 *
+	 * @param value HTTP header value.
+	 */
+	public Age(Object value) {
+		super("Age", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Allow.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Allow.java
index fc9b9a9..45ed13e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Allow.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Allow.java
@@ -66,7 +66,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Allow")
-public final class Allow extends HeaderStringArray {
+public final class Allow extends BasicStringArrayHeader {
 
 	/**
 	 * Constructor.
@@ -74,7 +74,7 @@ public final class Allow extends HeaderStringArray {
 	 * @param value The value for this header.
 	 */
 	public Allow(String[] value) {
-		super(value);
+		super("Allow", value);
 	}
 
 	/**
@@ -90,6 +90,6 @@ public final class Allow extends HeaderStringArray {
 	}
 
 	private Allow(String value) {
-		super(value);
+		super("Allow", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Authorization.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Authorization.java
index 2fa8e5b..0dc82ad 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Authorization.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Authorization.java
@@ -70,7 +70,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Authorization")
-public final class Authorization extends HeaderString {
+public final class Authorization extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Authorization</c> header.
@@ -85,6 +85,6 @@ public final class Authorization extends HeaderString {
 	}
 
 	private Authorization(String value) {
-		super(value);
+		super("Authorization", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicDateHeader.java
similarity index 93%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicDateHeader.java
index 80d0ec5..7a88fb2 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicDateHeader.java
@@ -27,7 +27,7 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-public class HeaderDate {
+public class BasicDateHeader extends BasicHeader {
 
 	private final java.util.Date date;
 	private final String raw;
@@ -35,9 +35,11 @@ public class HeaderDate {
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param raw The raw header value.
 	 */
-	protected HeaderDate(String raw) {
+	protected BasicDateHeader(String name, String raw) {
+		super(name, raw);
 		this.raw = raw;
 		this.date = DateUtils.parseDate(raw);
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEnum.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicEnumHeader.java
similarity index 92%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEnum.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicEnumHeader.java
index 838fd9f..0838891 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEnum.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicEnumHeader.java
@@ -27,7 +27,7 @@ package org.apache.juneau.http;
  *
  * @param <E> The enum type.
  */
-public class HeaderEnum<E extends Enum<E>> {
+public class BasicEnumHeader<E extends Enum<E>> extends BasicHeader {
 
 	private final String value;
 	private final E enumValue;
@@ -35,11 +35,13 @@ public class HeaderEnum<E extends Enum<E>> {
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 * @param enumClass The enum class.
 	 * @param def The default enum value if the value could not be parsed.
 	 */
-	protected HeaderEnum(String value, Class<E> enumClass, E def) {
+	protected BasicEnumHeader(String name, String value, Class<E> enumClass, E def) {
+		super(name, value);
 		this.value = value;
 		E _enumValue = def;
 		try {
@@ -67,6 +69,7 @@ public class HeaderEnum<E extends Enum<E>> {
 	 *
 	 * @return This header as a simple string.
 	 */
+	@Override
 	public String asString() {
 		return value;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeader.java
similarity index 68%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeader.java
index 80d0ec5..31c8370 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderDate.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeader.java
@@ -12,47 +12,46 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
-import org.apache.juneau.internal.*;
-
 /**
- * Category of headers that consist of a single HTTP-date.
- *
- * <p>
- * <h5 class='figure'>Example</h5>
- * <p class='bcode w800'>
- * 	If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT
- * </p>
- *
- * <ul class='seealso'>
- * 	<li class='extlink'>{@doc RFC2616}
- * </ul>
+ * Superclass of all HTTP headers defined in this package.
  */
-public class HeaderDate {
+public class BasicHeader implements HttpHeader {
 
-	private final java.util.Date date;
-	private final String raw;
+	private final String name;
+	final Object value;
 
 	/**
 	 * Constructor.
 	 *
-	 * @param raw The raw header value.
+	 * @param name The HTTP header name.
+	 * @param value The HTTP header value;
 	 */
-	protected HeaderDate(String raw) {
-		this.raw = raw;
-		this.date = DateUtils.parseDate(raw);
+	public BasicHeader(String name, Object value) {
+		this.name = name;
+		this.value = value;
+	}
+
+	@Override /* HttpHeader */
+	public String getName() {
+		return name;
+	}
+
+	@Override /* HttpHeader */
+	public Object getValue() {
+		return value;
 	}
 
 	/**
-	 * Returns this header value as a {@link java.util.Date}.
+	 * Returns the value as a string.
 	 *
-	 * @return This header value as a {@link java.util.Date}, or <jk>null</jk> if the header could not be parsed.
+	 * @return The value as a string, or an empty string if the value is <jk>null</jk>.
 	 */
-	public java.util.Date asDate() {
-		return date;
+	public String asString() {
+		return value == null ? "" : value.toString();
 	}
 
 	@Override /* Object */
 	public String toString() {
-		return raw;
+		return asString();
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderInteger.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicIntegerHeader.java
similarity index 84%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderInteger.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicIntegerHeader.java
index 6eb1dc8..a0b9893 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderInteger.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicIntegerHeader.java
@@ -28,35 +28,34 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header(type="integer",format="int32")
-public class HeaderInteger {
+public class BasicIntegerHeader extends BasicHeader {
 
 	private final Integer value;
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderInteger(String value) {
-		int _value = 0;
+	protected BasicIntegerHeader(String name, Object value) {
+		super(name, toInt(value));
+		this.value = (Integer)(super.value);
+	}
+
+	private static Integer toInt(Object value) {
+		if (value instanceof Integer)
+			return (Integer)value;
+		String s = value.toString();
 		try {
-			_value = Integer.parseInt(value);
+			return Integer.parseInt(s);
 		} catch (NumberFormatException e) {
 			try {
-				Long.parseLong(value);
-				_value = Integer.MAX_VALUE;
+				Long.parseLong(s);
+				return Integer.MAX_VALUE;
 			} catch (NumberFormatException e2) {}
 		}
-		this.value = _value;
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param value The parsed header value.
-	 */
-	protected HeaderInteger(Integer value) {
-		this.value = value;
+		return 0;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicLongHeader.java
similarity index 84%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicLongHeader.java
index 76afa42..8715ca8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicLongHeader.java
@@ -28,31 +28,29 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header(type="integer",format="int64")
-public class HeaderLong {
+public class BasicLongHeader extends BasicHeader {
 
 	private final Long value;
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderLong(String value) {
-		long _value = 0;
-		try {
-			_value = Long.parseLong(value);
-		} catch (NumberFormatException e) {
-		}
-		this.value = _value;
+	protected BasicLongHeader(String name, Object value) {
+		super(name, toLong(value));
+		this.value = (Long)(super.value);
 	}
 
-	/**
-	 * Constructor.
-	 *
-	 * @param value The parsed header value.
-	 */
-	protected HeaderLong(Long value) {
-		this.value = value;
+	private static Long toLong(Object value) {
+		if (value instanceof Long)
+			return (Long)value;
+		String s = value.toString();
+		try {
+			return Long.parseLong(s);
+		} catch (NumberFormatException e2) {}
+		return 0l;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderStringArray.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringArrayHeader.java
similarity index 87%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderStringArray.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringArrayHeader.java
index db9af92..419bd15 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderStringArray.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringArrayHeader.java
@@ -30,26 +30,34 @@ import org.apache.juneau.jsonschema.annotation.Items;
  * </ul>
  */
 @Header(type="array",collectionFormat="csv",items=@Items(type="string"))
-public class HeaderStringArray {
+public class BasicStringArrayHeader extends BasicHeader {
 
 	private final String[] value;
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderStringArray(String[] value) {
+	protected BasicStringArrayHeader(String name, String[] value) {
+		super(name, StringUtils.joine(value, ','));
 		this.value = value;
 	}
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderStringArray(String value) {
-		this.value = StringUtils.split(value);
+	protected BasicStringArrayHeader(String name, String value) {
+		super(name, value);
+		this.value = split(value);
+	}
+
+	private static String[] split(String value) {
+		return StringUtils.split(value);
 	}
 
 	/**
@@ -60,6 +68,7 @@ public class HeaderStringArray {
 	 *
 	 * @return This header as a simple string.
 	 */
+	@Override
 	public String asString() {
 		return StringUtils.joine(value, ',');
 	}
@@ -91,9 +100,4 @@ public class HeaderStringArray {
 					return true;
 		return false;
 	}
-
-	@Override /* Object */
-	public String toString() {
-		return asString();
-	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderString.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringHeader.java
similarity index 79%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderString.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringHeader.java
index 154073c..e5c0814 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderString.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStringHeader.java
@@ -12,8 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
-import org.apache.juneau.internal.*;
-
 /**
  * Category of headers that consist of a single string value.
  *
@@ -27,17 +25,16 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-public class HeaderString {
-
-	final String value;
+public abstract class BasicStringHeader extends BasicHeader {
 
 	/**
 	 * Constructor.
 	 *
-	 * @param value The raw header value.
+	 * @param name The HTTP header name.
+	 * @param value The HTTP header value.
 	 */
-	protected HeaderString(String value) {
-		this.value = StringUtils.trim(value);
+	protected BasicStringHeader(String name, Object value) {
+		super(name, value);
 	}
 
 	/**
@@ -47,7 +44,7 @@ public class HeaderString {
 	 * @return <jk>true</jk> if the specified value is the same.
 	 */
 	public boolean eqIC(String compare) {
-		return value.equalsIgnoreCase(compare);
+		return asString().equalsIgnoreCase(compare);
 	}
 
 	/**
@@ -57,23 +54,6 @@ public class HeaderString {
 	 * @return <jk>true</jk> if the specified value is the same.
 	 */
 	public boolean eq(String compare) {
-		return value.equals(compare);
-	}
-
-	/**
-	 * Returns this header as a simple string value.
-	 *
-	 * <p>
-	 * Functionally equivalent to calling {@link #toString()}.
-	 *
-	 * @return This header as a simple string.
-	 */
-	public String asString() {
-		return value;
-	}
-
-	@Override /* Object */
-	public String toString() {
-		return value == null ? "" : value;
+		return asString().equals(compare);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/CacheControl.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/CacheControl.java
index 05efff8..22f1672 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/CacheControl.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/CacheControl.java
@@ -94,7 +94,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Cache-Control")
-public final class CacheControl extends HeaderString {
+public final class CacheControl extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Cache-Control</c> header.
@@ -109,6 +109,6 @@ public final class CacheControl extends HeaderString {
 	}
 
 	private CacheControl(String value) {
-		super(value);
+		super("Cache-Control", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexEntityValidatorArrayHeader.java
similarity index 89%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexEntityValidatorArrayHeader.java
index bb2e587..ec45b98 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderEntityValidatorArray.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexEntityValidatorArrayHeader.java
@@ -29,16 +29,18 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-public class HeaderEntityValidatorArray {
+public class ComplexEntityValidatorArrayHeader extends ComplexHeader {
 
 	private final EntityValidator[] value;
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderEntityValidatorArray(String value) {
+	protected ComplexEntityValidatorArrayHeader(String name, String value) {
+		super(name);
 		String[] s = StringUtils.split(value);
 		this.value = new EntityValidator[s.length];
 		for (int i = 0; i < s.length; i++) {
@@ -55,6 +57,11 @@ public class HeaderEntityValidatorArray {
 		return value;
 	}
 
+	@Override /* HttpHeader */
+	public Object getValue() {
+		return StringUtils.join(value, ", ");
+	}
+
 	@Override /* Object */
 	public String toString() {
 		return StringUtils.join(value, ", ");
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexHeader.java
similarity index 72%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexHeader.java
index 41c026a..31ba033 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexHeader.java
@@ -1,32 +1,42 @@
-// ***************************************************************************************************************************
-// * 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 org.apache.http.impl.client.*;
-
-/**
- * Redirect strategy that allows for redirects on any request type, not just <c>GET</c> or <c>HEAD</c>.
- *
- * <ul class='notes'>
- * 	<li>
- * 		This class is similar to <c>org.apache.http.impl.client.LaxRedirectStrategy</c>
- * 		in Apache HttpClient 4.2, but also allows for redirects on <c>PUTs</c> and <c>DELETEs</c>.
- * </ul>
- */
-public class AllowAllRedirects extends DefaultRedirectStrategy {
-
-	@Override /* DefaultRedirectStrategy */
-	protected boolean isRedirectable(final String method) {
-		return true;
-	}
-}
+// ***************************************************************************************************************************
+// * 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.http;
+
+/**
+ * Category of headers that consist of complex parsed values.
+ *
+ * <ul class='seealso'>
+ * 	<li class='extlink'>{@doc RFC2616}
+ * </ul>
+ */
+public abstract class ComplexHeader implements HttpHeader {
+
+	private final String name;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param name The HTTP header name.
+	 */
+	public ComplexHeader(String name) {
+		this.name = name;
+	}
+
+	@Override /* HttpHeader */
+	public String getName() {
+		return name;
+	}
+
+	@Override /* HttpHeader */
+	public abstract Object getValue();
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderRangeArray.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexRangeArrayHeader.java
similarity index 92%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderRangeArray.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexRangeArrayHeader.java
index b0cc2ce..b18d3e6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderRangeArray.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ComplexRangeArrayHeader.java
@@ -31,7 +31,7 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-public class HeaderRangeArray {
+public class ComplexRangeArrayHeader extends ComplexHeader {
 
 	final StringRange[] typeRanges;
 	private final List<StringRange> typeRangesList;
@@ -39,9 +39,11 @@ public class HeaderRangeArray {
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderRangeArray(String value) {
+	protected ComplexRangeArrayHeader(String name, String value) {
+		super(name);
 		this.typeRanges = StringRange.parse(value);
 		this.typeRangesList = immutableList(typeRanges);
 	}
@@ -80,4 +82,9 @@ public class HeaderRangeArray {
 	public String toString() {
 		return StringUtils.join(typeRanges, ',');
 	}
+
+	@Override /* HttpHeader */
+	public Object getValue() {
+		return toString();
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Connection.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Connection.java
index 1d08290..3ff3f6f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Connection.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Connection.java
@@ -12,7 +12,6 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http;
 
-import org.apache.juneau.annotation.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -76,8 +75,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Connection")
-@BeanIgnore
-public final class Connection extends HeaderString {
+public final class Connection extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Connection</c> header.
@@ -93,7 +91,7 @@ public final class Connection extends HeaderString {
 
 
 	private Connection(String value) {
-		super(value);
+		super("Connection", value);
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentEncoding.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentEncoding.java
index fa59c6b..ab7df12 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentEncoding.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentEncoding.java
@@ -67,7 +67,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header(name="Content-Encoding",_enum={"gzip","compress","deflate","identity","other"})
-public final class ContentEncoding extends HeaderEnum<ContentEncodingEnum> {
+public final class ContentEncoding extends BasicEnumHeader<ContentEncodingEnum> {
 
 	/**
 	 * Returns a parsed <c>Content-Encoding</c> header.
@@ -82,6 +82,6 @@ public final class ContentEncoding extends HeaderEnum<ContentEncodingEnum> {
 	}
 
 	private ContentEncoding(String value) {
-		super(value, ContentEncodingEnum.class, ContentEncodingEnum.OTHER);
+		super("Content-Encoding", value, ContentEncodingEnum.class, ContentEncodingEnum.OTHER);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLanguage.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLanguage.java
index 362eb45..0c6aee2 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLanguage.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLanguage.java
@@ -71,7 +71,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Content-Language")
-public final class ContentLanguage extends HeaderStringArray {
+public final class ContentLanguage extends BasicStringArrayHeader {
 
 	/**
 	 * Constructor.
@@ -79,7 +79,7 @@ public final class ContentLanguage extends HeaderStringArray {
 	 * @param value The value for this header.
 	 */
 	public ContentLanguage(String[] value) {
-		super(value);
+		super("Allow", value);
 	}
 
 	/**
@@ -95,6 +95,6 @@ public final class ContentLanguage extends HeaderStringArray {
 	}
 
 	private ContentLanguage(String value) {
-		super(value);
+		super("Allow", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLength.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLength.java
index 047fe98..7e76f0e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLength.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLength.java
@@ -59,7 +59,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Content-Length")
-public final class ContentLength extends HeaderLong {
+public final class ContentLength extends BasicLongHeader {
 
 	/**
 	 * Constructor.
@@ -67,7 +67,7 @@ public final class ContentLength extends HeaderLong {
 	 * @param value The value for this header.
 	 */
 	public ContentLength(Long value) {
-		super(value);
+		super("Content-Length", value);
 	}
 
 	/**
@@ -83,6 +83,6 @@ public final class ContentLength extends HeaderLong {
 	}
 
 	private ContentLength(String value) {
-		super(value);
+		super("Content-Length", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLocation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLocation.java
index 4a91b29..249a4ea 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLocation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentLocation.java
@@ -80,6 +80,6 @@ public final class ContentLocation extends HeaderUri {
 	}
 
 	private ContentLocation(String value) {
-		super(value);
+		super("Content-Location", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentRange.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentRange.java
index 972b8b6..471daff 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentRange.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentRange.java
@@ -127,7 +127,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Content-Range")
-public final class ContentRange extends HeaderString {
+public final class ContentRange extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Content-Range</c> header.
@@ -142,6 +142,6 @@ public final class ContentRange extends HeaderString {
 	}
 
 	private ContentRange(String value) {
-		super(value);
+		super("Content-Range", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
index 7080fb4..c58d1dc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ContentType.java
@@ -48,7 +48,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Content-Type")
-public class ContentType extends MediaType {
+public class ContentType extends MediaType implements HttpHeader {
 
 	private static Cache<String,ContentType> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -100,4 +100,15 @@ public class ContentType extends MediaType {
 		}
 		return matchIndex;
 	}
+
+	@Override /* HttpHeader */
+	public String getName() {
+		return "Content-Type";
+	}
+
+
+	@Override /* HttpHeader */
+	public Object getValue() {
+		return toString();
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Date.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Date.java
index 762547f..55c2ffd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Date.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Date.java
@@ -76,8 +76,8 @@ import org.apache.juneau.http.annotation.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-@Header(name="Date")
-public final class Date extends HeaderDate {
+@Header("Date")
+public final class Date extends BasicDateHeader {
 
 	/**
 	 * Returns a parsed <c>Date</c> header.
@@ -92,6 +92,6 @@ public final class Date extends HeaderDate {
 	}
 
 	private Date(String value) {
-		super(value);
+		super("Date", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ETag.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ETag.java
index 5ab135f..200082e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ETag.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ETag.java
@@ -48,7 +48,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("ETag")
-public final class ETag extends HeaderString {
+public final class ETag extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>ETag</c> header.
@@ -63,6 +63,6 @@ public final class ETag extends HeaderString {
 	}
 
 	private ETag(String value) {
-		super(value);
+		super("ETag", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expect.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expect.java
index d5f36d0..4c4efd9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expect.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expect.java
@@ -67,7 +67,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Expect")
-public final class Expect extends HeaderString {
+public final class Expect extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Expect</c> header.
@@ -82,6 +82,6 @@ public final class Expect extends HeaderString {
 	}
 
 	private Expect(String value) {
-		super(value);
+		super("Expect", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expires.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expires.java
index 5d666fc..a7096f6 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expires.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Expires.java
@@ -78,7 +78,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Expires")
-public final class Expires extends HeaderDate {
+public final class Expires extends BasicDateHeader {
 
 	/**
 	 * Returns a parsed <c>Expires</c> header.
@@ -93,6 +93,6 @@ public final class Expires extends HeaderDate {
 	}
 
 	private Expires(String value) {
-		super(value);
+		super("Expires", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/From.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/From.java
index 19807cb..114bb6e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/From.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/From.java
@@ -65,7 +65,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("From")
-public final class From extends HeaderString {
+public final class From extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>From</c> header.
@@ -80,6 +80,6 @@ public final class From extends HeaderString {
 	}
 
 	private From(String value) {
-		super(value);
+		super("From", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderUri.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderUri.java
index 819b637..8b34d08 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderUri.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderUri.java
@@ -29,16 +29,18 @@ import org.apache.juneau.internal.*;
  * 	<li class='extlink'>{@doc RFC2616}
  * </ul>
  */
-public class HeaderUri{
+public class HeaderUri extends BasicHeader {
 
 	final String value;
 
 	/**
 	 * Constructor.
 	 *
+	 * @param name The HTTP header name.
 	 * @param value The raw header value.
 	 */
-	protected HeaderUri(String value) {
+	protected HeaderUri(String name, String value) {
+		super(name, value);
 		this.value = StringUtils.trim(value);
 	}
 
@@ -59,6 +61,7 @@ public class HeaderUri{
 	 *
 	 * @return This header as a simple string.
 	 */
+	@Override
 	public String asString() {
 		return value;
 	}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Host.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Host.java
index 781ad8f..e16cea0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Host.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Host.java
@@ -67,7 +67,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Host")
-public final class Host extends HeaderString {
+public final class Host extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Host</c> header.
@@ -82,6 +82,6 @@ public final class Host extends HeaderString {
 	}
 
 	private Host(String value) {
-		super(value);
+		super("Host", value);
 	}
 }
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpHeader.java
similarity index 71%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpHeader.java
index 41c026a..8bfff73 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpHeader.java
@@ -1,32 +1,36 @@
-// ***************************************************************************************************************************
-// * 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 org.apache.http.impl.client.*;
-
-/**
- * Redirect strategy that allows for redirects on any request type, not just <c>GET</c> or <c>HEAD</c>.
- *
- * <ul class='notes'>
- * 	<li>
- * 		This class is similar to <c>org.apache.http.impl.client.LaxRedirectStrategy</c>
- * 		in Apache HttpClient 4.2, but also allows for redirects on <c>PUTs</c> and <c>DELETEs</c>.
- * </ul>
- */
-public class AllowAllRedirects extends DefaultRedirectStrategy {
-
-	@Override /* DefaultRedirectStrategy */
-	protected boolean isRedirectable(final String method) {
-		return true;
-	}
-}
+// ***************************************************************************************************************************
+// * 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.http;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Parent interface for all headers.
+ */
+@BeanIgnore
+public interface HttpHeader {
+
+	/**
+	 * Returns the HTTP header name.
+	 *
+	 * @return The HTTP header name.
+	 */
+	String getName();
+
+	/**
+	 * Returns the HTTP header value.
+	 *
+	 * @return The HTTP header value.
+	 */
+	Object getValue();
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java
index 9c0c950..beb6771 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java
@@ -24,31 +24,43 @@ import java.util.*;
 public enum HttpMethod {
 
 	/** {@doc RFC2616.section9#sec9.2 OPTIONS} */
-	OPTIONS,
+	OPTIONS(false),
 
 	/** {@doc RFC2616.section9#sec9.3 GET} */
-	GET,
+	GET(false),
 
 	/** {@doc RFC2616.section9#sec9.4 HEAD} */
-	HEAD,
+	HEAD(false),
 
 	/** {@doc RFC2616.section9#sec9.5 POST} */
-	POST,
+	POST(true),
 
 	/** {@doc RFC2616.section9#sec9.6 PUT} */
-	PUT,
+	PUT(true),
+
+	/** PATH */
+	PATCH(true),
 
 	/** {@doc RFC2616.section9#sec9.7 DELETE} */
-	DELETE,
+	DELETE(false),
 
 	/** {@doc RFC2616.section9#sec9.8 TRACE} */
-	TRACE,
+	TRACE(false),
 
 	/** {@doc RFC2616.section9#sec9.9 CONNECT} */
-	CONNECT,
+	CONNECT(false),
+
+	/** HTTP MOVE */
+	MOVE(false),
 
 	/** A non-standard value. */
-	OTHER;
+	OTHER(true);
+
+	private boolean hasContent;
+
+	HttpMethod(boolean hasContent) {
+		this.hasContent = hasContent;
+	}
 
 	private static final Map<String,HttpMethod> cache = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
 	static {
@@ -63,6 +75,15 @@ public enum HttpMethod {
 	}
 
 	/**
+	 * Returns whether this HTTP method normally has content.
+	 *
+	 * @return <jk>true</jk> if this HTTP method normally has content.
+	 */
+	public boolean hasContent() {
+		return hasContent;
+	}
+
+	/**
 	 * Returns the enum for the specified key.
 	 *
 	 * <p>
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfMatch.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfMatch.java
index 179c313..469c306 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfMatch.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfMatch.java
@@ -89,7 +89,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("If-Match")
-public final class IfMatch extends HeaderEntityValidatorArray {
+public final class IfMatch extends ComplexEntityValidatorArrayHeader {
 
 	/**
 	 * Returns a parsed <c>If-Match</c> header.
@@ -104,6 +104,6 @@ public final class IfMatch extends HeaderEntityValidatorArray {
 	}
 
 	private IfMatch(String value) {
-		super(value);
+		super("If-Match", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfModifiedSince.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfModifiedSince.java
index 80522a6..b8830b8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfModifiedSince.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfModifiedSince.java
@@ -89,7 +89,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("If-Modified-Since")
-public final class IfModifiedSince extends HeaderDate {
+public final class IfModifiedSince extends BasicDateHeader {
 
 	/**
 	 * Returns a parsed <c>If-Modified-Since</c> header.
@@ -104,6 +104,6 @@ public final class IfModifiedSince extends HeaderDate {
 	}
 
 	private IfModifiedSince(String value) {
-		super(value);
+		super("If-Modified-Since", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfNoneMatch.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfNoneMatch.java
index 3876fd6..d0787fb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfNoneMatch.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfNoneMatch.java
@@ -92,7 +92,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("If-None-Match")
-public final class IfNoneMatch extends HeaderEntityValidatorArray {
+public final class IfNoneMatch extends ComplexEntityValidatorArrayHeader {
 
 	/**
 	 * Returns a parsed <c>If-None-Match</c> header.
@@ -107,6 +107,6 @@ public final class IfNoneMatch extends HeaderEntityValidatorArray {
 	}
 
 	private IfNoneMatch(String value) {
-		super(value);
+		super("If-None-Match", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfRange.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfRange.java
index 24da810..4cdd1b1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfRange.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfRange.java
@@ -62,7 +62,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("If-Range")
-public final class IfRange extends HeaderString {
+public final class IfRange extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>If-Range</c> header.
@@ -77,7 +77,7 @@ public final class IfRange extends HeaderString {
 	}
 
 	private IfRange(String value) {
-		super(value);
+		super("If-Range", value);
 	}
 
 	/**
@@ -86,7 +86,7 @@ public final class IfRange extends HeaderString {
 	 * @return This header value as a {@link java.util.Date} object, or <jk>null</jk> if the value is not a date.
 	 */
 	public java.util.Date asDate() {
-		char c0 = charAt(value, 0), c1 = charAt(value, 1);
+		char c0 = charAt(asString(), 0), c1 = charAt(asString(), 1);
 		if (c0 == '*' || c0 == '"' || (c0 == 'W' && c1 == '/'))
 			return null;
 		return DateUtils.parseDate(toString());
@@ -100,9 +100,9 @@ public final class IfRange extends HeaderString {
 	 * 	validator.
 	 */
 	public EntityValidator asValidator() {
-		char c0 = charAt(value, 0), c1 = charAt(value, 1);
+		char c0 = charAt(asString(), 0), c1 = charAt(asString(), 1);
 		if (c0 == '*' || c0 == '"' || (c0 == 'W' && c1 == '/'))
-			return new EntityValidator(value);
+			return new EntityValidator(asString());
 		return null;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
index 89fae16..540d0fd 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/IfUnmodifiedSince.java
@@ -61,7 +61,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("If-Unmodified-Since")
-public final class IfUnmodifiedSince extends HeaderDate {
+public final class IfUnmodifiedSince extends BasicDateHeader {
 
 	/**
 	 * Returns a parsed <c>If-Unmodified-Since</c> header.
@@ -76,6 +76,6 @@ public final class IfUnmodifiedSince extends HeaderDate {
 	}
 
 	private IfUnmodifiedSince(String value) {
-		super(value);
+		super("If-Unmodified-Since", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/LastModified.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/LastModified.java
index 6294da2..273e8d7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/LastModified.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/LastModified.java
@@ -68,7 +68,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Last-Modified")
-public final class LastModified extends HeaderDate {
+public final class LastModified extends BasicDateHeader {
 
 	/**
 	 * Returns a parsed <c>Last-Modified</c> header.
@@ -83,6 +83,6 @@ public final class LastModified extends HeaderDate {
 	}
 
 	private LastModified(String value) {
-		super(value);
+		super("Last-Modified", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Location.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Location.java
index 98cd98e..668fbe5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Location.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Location.java
@@ -69,6 +69,6 @@ public final class Location extends HeaderUri {
 	}
 
 	private Location(String value) {
-		super(value);
+		super("Location", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MaxForwards.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MaxForwards.java
index 05cd4d2..fa9abc3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MaxForwards.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MaxForwards.java
@@ -57,7 +57,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Max-Forwards")
-public final class MaxForwards extends HeaderInteger {
+public final class MaxForwards extends BasicIntegerHeader {
 
 	/**
 	 * Constructor.
@@ -65,7 +65,7 @@ public final class MaxForwards extends HeaderInteger {
 	 * @param value The value for this header.
 	 */
 	public MaxForwards(Integer value) {
-		super(value);
+		super("Max-Forwards", value);
 	}
 
 	/**
@@ -81,6 +81,6 @@ public final class MaxForwards extends HeaderInteger {
 	}
 
 	private MaxForwards(String value) {
-		super(value);
+		super("Max-Forwards", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
index 6677196..1ad074d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/MediaType.java
@@ -32,7 +32,7 @@ import org.apache.juneau.json.*;
  * </ul>
  */
 @BeanIgnore
-public class MediaType implements Comparable<MediaType> {
+public class MediaType implements Comparable<MediaType>  {
 
 	private static final boolean NOCACHE = Boolean.getBoolean("juneau.nocache");
 	private static final ConcurrentHashMap<String,MediaType> CACHE = new ConcurrentHashMap<>();
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Pragma.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Pragma.java
index 4993dd7..92ead94 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Pragma.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Pragma.java
@@ -65,7 +65,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Pragma")
-public final class Pragma extends HeaderString {
+public final class Pragma extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Pragma</c> header.
@@ -80,6 +80,6 @@ public final class Pragma extends HeaderString {
 	}
 
 	private Pragma(String value) {
-		super(value);
+		super("Pragma", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
index 8dc97cc..123271f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthenticate.java
@@ -48,7 +48,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Proxy-Authenticate")
-public final class ProxyAuthenticate extends HeaderString {
+public final class ProxyAuthenticate extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Proxy-Authenticate</c> header.
@@ -63,6 +63,6 @@ public final class ProxyAuthenticate extends HeaderString {
 	}
 
 	private ProxyAuthenticate(String value) {
-		super(value);
+		super("Proxy-Authenticate", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthorization.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
index ff1cd9e..920c55b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/ProxyAuthorization.java
@@ -50,7 +50,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Proxy-Authorization")
-public final class ProxyAuthorization extends HeaderString {
+public final class ProxyAuthorization extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Proxy-Authorization</c> header.
@@ -65,6 +65,6 @@ public final class ProxyAuthorization extends HeaderString {
 	}
 
 	private ProxyAuthorization(String value) {
-		super(value);
+		super("Proxy-Authorization", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Range.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Range.java
index 738bb78..def1b0f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Range.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Range.java
@@ -140,7 +140,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Range")
-public final class Range extends HeaderString {
+public final class Range extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Range</c> header.
@@ -155,6 +155,6 @@ public final class Range extends HeaderString {
 	}
 
 	private Range(String value) {
-		super(value);
+		super("Range", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Referer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Referer.java
index 85eeca6..0a399c9 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Referer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Referer.java
@@ -71,6 +71,6 @@ public final class Referer extends HeaderUri {
 	}
 
 	private Referer(String value) {
-		super(value);
+		super("Referer", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/RetryAfter.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/RetryAfter.java
index fa4fc2b..4c1739f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/RetryAfter.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/RetryAfter.java
@@ -58,7 +58,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("Retry-After")
-public final class RetryAfter extends HeaderString {
+public final class RetryAfter extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Retry-After</c> header.
@@ -73,7 +73,7 @@ public final class RetryAfter extends HeaderString {
 	}
 
 	private RetryAfter(String value) {
-		super(value);
+		super("Retry-After", value);
 	}
 
 	/**
@@ -82,7 +82,7 @@ public final class RetryAfter extends HeaderString {
 	 * @return This header value as a {@link java.util.Date} object, or <jk>null</jk> if the value is not a date.
 	 */
 	public java.util.Date asDate() {
-		char c0 = charAt(value, 0);
+		char c0 = charAt(asString(), 0);
 		if (c0 >= '0' && c0 <= '9')
 			return null;
 		return DateUtils.parseDate(toString());
@@ -94,10 +94,10 @@ public final class RetryAfter extends HeaderString {
 	 * @return This header value as a integer, or <c>-1</c> if the value is not an integer.
 	 */
 	public int asInt() {
-		char c0 = charAt(value, 0);
+		char c0 = charAt(asString(), 0);
 		if (c0 >= '0' && c0 <= '9') {
 			try {
-				return Integer.parseInt(value);
+				return Integer.parseInt(asString());
 			} catch (NumberFormatException e) {
 				return -1;
 			}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Server.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Server.java
index 9956ece..c453ad4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Server.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Server.java
@@ -57,7 +57,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Server")
-public final class Server extends HeaderString {
+public final class Server extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Server</c> header.
@@ -72,6 +72,6 @@ public final class Server extends HeaderString {
 	}
 
 	private Server(String value) {
-		super(value);
+		super("Server", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TE.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TE.java
index 95894ee..4e8e84f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TE.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TE.java
@@ -88,7 +88,7 @@ import org.apache.juneau.internal.*;
  * </ul>
  */
 @Header("TE")
-public final class TE extends HeaderRangeArray {
+public final class TE extends ComplexRangeArrayHeader {
 
 	private static final Cache<String,TE> cache = new Cache<>(NOCACHE, CACHE_MAX_SIZE);
 
@@ -108,6 +108,6 @@ public final class TE extends HeaderRangeArray {
 	}
 
 	private TE(String value) {
-		super(value);
+		super("TE", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Trailer.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Trailer.java
index ac520aa..5833703 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Trailer.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Trailer.java
@@ -57,7 +57,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Trailer")
-public final class Trailer extends HeaderString {
+public final class Trailer extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Trailer</c> header.
@@ -72,6 +72,6 @@ public final class Trailer extends HeaderString {
 	}
 
 	private Trailer(String value) {
-		super(value);
+		super("Trailer", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TransferEncoding.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TransferEncoding.java
index 870788c..e98fd60 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TransferEncoding.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/TransferEncoding.java
@@ -57,7 +57,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Transfer-Encoding")
-public final class TransferEncoding extends HeaderString {
+public final class TransferEncoding extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Transfer-Encoding</c> header.
@@ -72,6 +72,6 @@ public final class TransferEncoding extends HeaderString {
 	}
 
 	private TransferEncoding(String value) {
-		super(value);
+		super("Transfer-Encoding", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Upgrade.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Upgrade.java
index be0a819..381880d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Upgrade.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Upgrade.java
@@ -80,7 +80,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Upgrade")
-public final class Upgrade extends HeaderStringArray {
+public final class Upgrade extends BasicStringArrayHeader {
 
 	/**
 	 * Constructor.
@@ -88,7 +88,7 @@ public final class Upgrade extends HeaderStringArray {
 	 * @param value The value for this header.
 	 */
 	public Upgrade(String[] value) {
-		super(value);
+		super("Upgrade", value);
 	}
 
 	/**
@@ -104,6 +104,6 @@ public final class Upgrade extends HeaderStringArray {
 	}
 
 	private Upgrade(String value) {
-		super(value);
+		super("Upgrade", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/UserAgent.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/UserAgent.java
index 874744f..69b7a6c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/UserAgent.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/UserAgent.java
@@ -50,7 +50,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("User-Agent")
-public final class UserAgent extends HeaderString {
+public final class UserAgent extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>User-Agent</c> header.
@@ -65,6 +65,6 @@ public final class UserAgent extends HeaderString {
 	}
 
 	private UserAgent(String value) {
-		super(value);
+		super("User-Agent", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Vary.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Vary.java
index 8dc20a0..e5ec550 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Vary.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Vary.java
@@ -70,7 +70,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Vary")
-public final class Vary extends HeaderString {
+public final class Vary extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Vary</c> header.
@@ -85,6 +85,6 @@ public final class Vary extends HeaderString {
 	}
 
 	private Vary(String value) {
-		super(value);
+		super("Vary", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Via.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Via.java
index f5f8d9f..a3bc2ce 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Via.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Via.java
@@ -116,7 +116,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Via")
-public final class Via extends HeaderStringArray {
+public final class Via extends BasicStringArrayHeader {
 
 	/**
 	 * Constructor.
@@ -124,7 +124,7 @@ public final class Via extends HeaderStringArray {
 	 * @param value The value for this header.
 	 */
 	public Via(String[] value) {
-		super(value);
+		super("Via", value);
 	}
 
 	/**
@@ -140,6 +140,6 @@ public final class Via extends HeaderStringArray {
 	}
 
 	private Via(String value) {
-		super(value);
+		super("Via", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Warning.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Warning.java
index acd5028..bb39e55 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Warning.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Warning.java
@@ -124,7 +124,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("Warning")
-public final class Warning extends HeaderString {
+public final class Warning extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>Warning</c> header.
@@ -139,6 +139,6 @@ public final class Warning extends HeaderString {
 	}
 
 	private Warning(String value) {
-		super(value);
+		super("Warning", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/WwwAuthenticate.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
index c952d17..0b67abf 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/WwwAuthenticate.java
@@ -46,7 +46,7 @@ import org.apache.juneau.http.annotation.*;
  * </ul>
  */
 @Header("WWW-Authenticate")
-public final class WwwAuthenticate extends HeaderString {
+public final class WwwAuthenticate extends BasicStringHeader {
 
 	/**
 	 * Returns a parsed <c>WWW-Authenticate</c> header.
@@ -61,6 +61,6 @@ public final class WwwAuthenticate extends HeaderString {
 	}
 
 	private WwwAuthenticate(String value) {
-		super(value);
+		super("WWW-Authenticate", value);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
index f200785..ca2a349 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/internal/StringUtils.java
@@ -1306,6 +1306,16 @@ public final class StringUtils {
 	}
 
 	/**
+	 * Shortcut for calling generateUUID(int).
+	 *
+	 * @param numchars The number of characters in the generated UUID.
+	 * @return A new random UUID.
+	 */
+	public static String random(int numchars) {
+		return generateUUID(numchars);
+	}
+
+	/**
 	 * Same as {@link String#trim()} but prevents <c>NullPointerExceptions</c>.
 	 *
 	 * @param s The string to trim.
@@ -2730,4 +2740,17 @@ public final class StringUtils {
 			return in;
 		return in.substring(0, length-3) + "...";
 	}
+
+	/**
+	 * Truncates a string.
+	 *
+	 * @param in The input string.
+	 * @param length The max length of the resulting string.
+	 * @return The truncated string.
+	 */
+	public static String truncate(String in, int length) {
+		if (in == null || in.length() <= length)
+			return in;
+		return in.substring(0, length);
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionHasher.java
similarity index 59%
rename from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java
rename to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionHasher.java
index 76afa42..d5f9437 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HeaderLong.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionHasher.java
@@ -10,65 +10,59 @@
 // * "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.http;
+package org.apache.juneau.mstat;
 
-import org.apache.juneau.http.annotation.*;
+import java.util.*;
 
 /**
- * Category of headers that consist of a single long value.
- *
- * <p>
- * <h5 class='figure'>Example</h5>
- * <p class='bcode w800'>
- * 	Content-Length: 300
- * </p>
- *
- * <ul class='seealso'>
- * 	<li class='extlink'>{@doc RFC2616}
- * </ul>
+ * Stack trace utility methods.
  */
-@Header(type="integer",format="int64")
-public class HeaderLong {
+public class ExceptionHasher {
 
-	private final Long value;
+	private final String stopClass;
 
 	/**
-	 * Constructor.
+	 * TODO
 	 *
-	 * @param value The raw header value.
+	 * @param stopClass TODO
 	 */
-	protected HeaderLong(String value) {
-		long _value = 0;
-		try {
-			_value = Long.parseLong(value);
-		} catch (NumberFormatException e) {
-		}
-		this.value = _value;
+	public ExceptionHasher(Class<?> stopClass) {
+		this.stopClass = stopClass == null ? null : stopClass.getName();
 	}
 
 	/**
-	 * Constructor.
+	 * Calculates a 16-bit hash for the specified throwable based on it's stack trace.
 	 *
-	 * @param value The parsed header value.
+	 * @param t The throwable to calculate the stack trace on.
+	 * @return A calculated hash.
 	 */
-	protected HeaderLong(Long value) {
-		this.value = value;
+	public int hash(Throwable t) {
+		int i = 0;
+		while (t != null) {
+			for (StackTraceElement e : t.getStackTrace()) {
+				if (e.getClassName().equals(stopClass))
+					break;
+				if (e.getClassName().indexOf('$') == -1)
+					i ^= e.hashCode();
+			}
+			t = t.getCause();
+		}
+		return i;
 	}
 
 	/**
-	 * Returns this header as a simple string value.
-	 *
-	 * <p>
-	 * Functionally equivalent to calling {@link #toString()}.
+	 * TODO
 	 *
-	 * @return This header as a simple string.
+	 * @param t TODO
+	 * @return TODO
 	 */
-	public long asLong() {
-		return value;
-	}
-
-	@Override /* Object */
-	public String toString() {
-		return String.valueOf(value);
+	public List<StackTraceElement> getStackTrace(Throwable t) {
+		List<StackTraceElement> l = new ArrayList<>();
+		for (StackTraceElement e : t.getStackTrace()) {
+			if (e.getClassName().equals(stopClass))
+				break;
+			l.add(e);
+		}
+		return Collections.unmodifiableList(l);
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionInfo.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionInfo.java
new file mode 100644
index 0000000..22e814b
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionInfo.java
@@ -0,0 +1,141 @@
+// ***************************************************************************************************************************
+// * 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.mstat;
+
+import java.util.*;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Stores information about an exception.
+ */
+@Bean(bpi="hash,exceptionClass,message,stackTrace,causedBy", fluentSetters=true)
+public class ExceptionInfo implements Cloneable {
+
+	private String hash;
+	private String exceptionClass;
+	private String message;
+	private List<StackTraceElement> stackTrace;
+	private ExceptionInfo causedBy;
+
+	/**
+	 * TODO
+	 *
+	 * @return TODO
+	 */
+	public static ExceptionInfo create() {
+		return new ExceptionInfo();
+	}
+
+	/**
+	 * Returns an 8-byte hash of the stack trace.
+	 *
+	 * @return An 8-byte hash of the stack trace.
+	 */
+	public String getHash() {
+		return hash;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionInfo hash(String value) {
+		this.hash = value;
+		return this;
+	}
+
+	/**
+	 * Returns the simple class name of the exception.
+	 *
+	 * @return The simple class name of the exception, or <jk>null</jk> if not specified.
+	 */
+	public String getExceptionClass() {
+		return exceptionClass;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionInfo exceptionClass(String value) {
+		this.exceptionClass = value;
+		return this;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @return TODO
+	 */
+	public String getMessage() {
+		return message;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionInfo message(String value) {
+		this.message = value;
+		return this;
+	}
+
+
+	/**
+	 * TODO
+	 *
+	 * @return TODO
+	 */
+	public List<StackTraceElement> getStackTrace() {
+		return stackTrace;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionInfo stackTrace(List<StackTraceElement> value) {
+		this.stackTrace = value;
+		return this;
+	}
+
+
+	/**
+	 * TODO
+	 *
+	 * @return TODO
+	 */
+	public ExceptionInfo getCausedBy() {
+		return causedBy;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionInfo causedBy(ExceptionInfo value) {
+		this.causedBy = value;
+		return this;
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStats.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStats.java
new file mode 100644
index 0000000..c8125e8
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStats.java
@@ -0,0 +1,128 @@
+// ***************************************************************************************************************************
+// * 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.mstat;
+
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+import org.apache.juneau.annotation.*;
+
+/**
+ * Represents an entry in {@link ExceptionStore}.
+ */
+@Bean(bpi="hash,count,exceptionClass,message,stackTrace,causedBy", fluentSetters=true)
+public class ExceptionStats extends ExceptionInfo implements Comparable<ExceptionStats> {
+	private final AtomicInteger count = new AtomicInteger(0);
+	private transient long timeout = -1;
+
+	public static ExceptionStats create() {
+		return new ExceptionStats();
+	}
+
+	/**
+	 * Returns the number of times this stack trace was encountered.
+	 *
+	 * @return The number of times this stack trace was encountered.
+	 */
+	public int getCount() {
+		return count.intValue();
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionStats count(int value) {
+		count.set(value);
+		return this;
+	}
+
+	/**
+	 * Increments the occurrence count of this exception.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionStats increment() {
+		count.incrementAndGet();
+		return this;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @param value TODO
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionStats timeout(long value) {
+		this.timeout = value;
+		return this;
+	}
+
+	/**
+	 * TODO
+	 *
+	 * @return TODO
+	 */
+	public boolean isExpired() {
+		return timeout >= 0 && System.currentTimeMillis() > timeout;
+	}
+
+
+	@Override
+	public ExceptionStats hash(String value) {
+		super.hash(value);
+		return this;
+	}
+
+	@Override
+	public ExceptionStats exceptionClass(String value) {
+		super.exceptionClass(value);
+		return this;
+	}
+
+	@Override
+	public ExceptionStats message(String value) {
+		super.message(value);
+		return this;
+	}
+
+	@Override
+	public ExceptionStats stackTrace(List<StackTraceElement> value) {
+		super.stackTrace(value);
+		return this;
+	}
+
+	@Override
+	public ExceptionStats causedBy(ExceptionInfo value) {
+		super.causedBy(value);
+		return this;
+	}
+
+
+
+	@Override /* Comparable */
+	public int compareTo(ExceptionStats o) {
+		return Integer.compare(o.getCount(), getCount());
+	}
+
+	@Override /* Object */
+	public ExceptionStats clone() {
+		try {
+			return (ExceptionStats) super.clone();
+		} catch (CloneNotSupportedException e) {
+			throw new RuntimeException(e);
+		}
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStore.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStore.java
new file mode 100644
index 0000000..58370bb
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/ExceptionStore.java
@@ -0,0 +1,136 @@
+// ***************************************************************************************************************************
+// * 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.mstat;
+
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.stream.*;
+
+/**
+ * An in-memory cache of stack traces.
+ *
+ * <p>
+ * Used for preventing duplication of stack traces in log files and replacing them with small hashes.
+ */
+public class ExceptionStore {
+
+	private final ConcurrentHashMap<Integer,ExceptionStats> sdb = new ConcurrentHashMap<>();
+	private final ConcurrentHashMap<Integer,ExceptionInfo> idb = new ConcurrentHashMap<>();
+	private final ExceptionHasher hasher;
+	private final long cacheTimeout;
+
+	/**
+	 * Constructor.
+	 */
+	public ExceptionStore() {
+		this(-1, null);
+	}
+
+
+
+	/**
+	 * Constructor.
+	 *
+	 * @param cacheTimeout
+	 * 	The amount of time in milliseconds to cache stack trace info in this database before discarding.
+	 * 	<br>If <c>-1</c>, never discard.
+	 * @param stopClass
+	 * 	When this class is encountered in a stack trace, stop calculating the hash.
+	 * 	<br>Can be <jk>null</jk>.
+	 */
+	public ExceptionStore(long cacheTimeout, Class<?> stopClass) {
+		this.hasher = new ExceptionHasher(stopClass);
+		this.cacheTimeout = cacheTimeout;
+	}
+
+	/**
+	 * Adds the specified throwable to this database.
+	 *
+	 * @param e The exception to add.
+	 * @return This object (for method chaining).
+	 */
+	public ExceptionStore add(Throwable e) {
+		find(e).increment();
+		return this;
+	}
+
+	/**
+	 * Retrieves the stack trace information for the specified exception.
+	 *
+	 * @param e The exception.
+	 * @return A clone of the stack trace info, never <jk>null</jk>.
+	 */
+	public ExceptionStats getStackTraceInfo(Throwable e) {
+		return find(e).clone();
+	}
+
+	/**
+	 * Clears out the stack trace cache.
+	 */
+	public void reset() {
+		sdb.clear();
+	}
+
+	/**
+	 * Returns the list of all stack traces in this database.
+	 *
+	 * @return The list of all stack traces in this database, cloned and sorted by count descending.
+	 */
+	public List<ExceptionStats> getClonedStats() {
+		return sdb.values().stream().map(x -> x.clone()).sorted().collect(Collectors.toList());
+	}
+
+	private ExceptionStats find(Throwable e) {
+
+		if (e == null)
+			return null;
+
+		int hash = hasher.hash(e);
+
+		ExceptionStats stc = sdb.get(hash);
+		if (stc != null && ! stc.isExpired())
+			return stc;
+
+		stc = ExceptionStats
+			.create()
+			.hash(Integer.toHexString(hash))
+			.timeout(cacheTimeout == -1 ? Long.MAX_VALUE : System.currentTimeMillis() + cacheTimeout)
+			.message(e.getMessage())
+			.exceptionClass(e.getClass().getName())
+			.stackTrace(hasher.getStackTrace(e))
+			.causedBy(e.getCause() == null ? null : findInfo(e.getCause()));
+
+		sdb.put(hash, stc);
+
+		return sdb.get(hash);
+	}
+
+	private ExceptionInfo findInfo(Throwable e) {
+
+		int hash = hasher.hash(e);
+
+		ExceptionInfo ei = sdb.get(hash);
+		if (ei == null) {
+			ei = ExceptionInfo
+				.create()
+				.hash(Integer.toHexString(hash))
+				.message(e.getMessage())
+				.exceptionClass(e.getClass().getName())
+				.stackTrace(hasher.getStackTrace(e))
+				.causedBy(e.getCause() == null ? null : findInfo(e.getCause()));
+			idb.put(hash, ei);
+		}
+
+		return ei;
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/MethodExecStats.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/MethodExecStats.java
new file mode 100644
index 0000000..7d81ba4
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/MethodExecStats.java
@@ -0,0 +1,182 @@
+// ***************************************************************************************************************************
+// * 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.mstat;
+
+import java.lang.reflect.*;
+import java.util.*;
+import java.util.concurrent.atomic.*;
+
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.marshall.*;
+import org.apache.juneau.utils.*;
+
+/**
+ * Basic timing information.
+ *
+ * Keeps track of number of starts/finishes on tasks and keeps an average run time.
+ */
+@Bean(bpi="method,runs,running,errors,minTime,maxTime,avgTime,totalTime,exceptions")
+public class MethodExecStats implements Comparable<MethodExecStats> {
+
+	private String method;
+	private volatile int minTime = -1, maxTime;
+
+	private AtomicInteger
+		starts = new AtomicInteger(),
+		finishes = new AtomicInteger(),
+		errors = new AtomicInteger();
+
+	private AtomicLong
+		totalTime = new AtomicLong();
+
+	private ExceptionStore stackTraceDb;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param method Arbitrary label.  Should be kept to less than 50 characters.
+	 * @param stackTraceStopClass Don't calculate stack traces when this class is encountered.
+	 */
+	public MethodExecStats(Method method, Class<?> stackTraceStopClass) {
+		this.method = method.getDeclaringClass().getSimpleName() + "." + method.getName();
+		this.stackTraceDb = new ExceptionStore(-1, stackTraceStopClass);
+	}
+
+	/**
+	 * Constructor.
+	 *
+	 * @param method Arbitrary label.  Should be kept to less than 50 characters.
+	 */
+	public MethodExecStats(Method method) {
+		this(method, MethodInvoker.class);
+	}
+
+	/**
+	 * Call when task is started.
+	 */
+	public void started() {
+		starts.incrementAndGet();
+	}
+
+	/**
+	 * Call when task is finished.
+	 * @param nanoTime The execution time of the task in nanoseconds.
+	 */
+	public void finished(long nanoTime) {
+		finishes.incrementAndGet();
+		int milliTime = (int)(nanoTime/1_000_000);
+		totalTime.addAndGet(nanoTime);
+		minTime = minTime == -1 ? milliTime : Math.min(minTime, milliTime);
+		maxTime = Math.max(maxTime, milliTime);
+	}
+
+	/**
+	 * Call when an error occurs.
+	 * @param e The exception thrown.  Can be <jk>null</jk>.
+	 */
+	public void error(Throwable e) {
+		errors.incrementAndGet();
+		stackTraceDb.add(e);
+	}
+
+	/**
+	 * Returns the method name of these stats.
+	 *
+	 * @return The method name of these stats.
+	 */
+	public String getMethod() {
+		return method;
+	}
+
+	/**
+	 * Returns the number of times the {@link #started()} method was called.
+	 *
+	 * @return The number of times the {@link #started()} method was called.
+	 */
+	public int getRuns() {
+		return starts.get();
+	}
+
+	/**
+	 * Returns the number currently running method invocations.
+	 *
+	 * @return The number of currently running method invocations.
+	 */
+	public int getRunning() {
+		return starts.get() - finishes.get();
+	}
+
+	/**
+	 * Returns the number of times the {@link #error(Throwable)} method was called.
+	 *
+	 * @return The number of times the {@link #error(Throwable)} method was called.
+	 */
+	public int getErrors() {
+		return errors.get();
+	}
+
+	/**
+	 * Returns the max execution time.
+	 *
+	 * @return The average execution time in milliseconds.
+	 */
+	public int getMinTime() {
+		return minTime == -1 ? 0 : minTime;
+	}
+
+	/**
+	 * Returns the max execution time.
+	 *
+	 * @return The average execution time in milliseconds.
+	 */
+	public int getMaxTime() {
+		return maxTime;
+	}
+
+	/**
+	 * Returns the average execution time.
+	 *
+	 * @return The average execution time in milliseconds.
+	 */
+	public int getAvgTime() {
+		return (int)(getTotalTime() / getRuns());
+	}
+
+	/**
+	 * Returns the total execution time.
+	 *
+	 * @return The total execution time in milliseconds.
+	 */
+	public long getTotalTime() {
+		return totalTime.get() / 1_000_000;
+	}
+
+	/**
+	 * Returns information on all stack traces of all exceptions encountered.
+	 *
+	 * @return Information on all stack traces of all exceptions encountered.
+	 */
+	public List<ExceptionStats> getExceptions() {
+		return stackTraceDb.getClonedStats();
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return SimpleJson.DEFAULT.toString(this);
+	}
+
+	@Override /* Comparable */
+	public int compareTo(MethodExecStats o) {
+		return Long.compare(o.getTotalTime(), getTotalTime());
+	}
+}
\ No newline at end of file
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication.html b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/package-info.java
similarity index 76%
copy from juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication.html
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/package-info.java
index b19fe70..06ca9c9 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication.html
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/mstat/package-info.java
@@ -1,24 +1,18 @@
-<!--
 /***************************************************************************************************************************
  * 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.
+ *
  ***************************************************************************************************************************/
- -->
 
-Authentication
-
-<p>
-	The Juneau REST client itself does not implement any support for authentication.  
-	Instead, it delegates it to the underlying Apache HTTP Client interface.
-</p>
-<p>
-	The following sections show how some common authentication mechanisms can be set up using HTTP Client APIs.
-</p>
\ No newline at end of file
+/**
+ * Method exec stats utilities
+ */
+package org.apache.juneau.mstat;
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
index 0667bfe..7334bb7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transform/DefaultSwaps.java
@@ -16,6 +16,7 @@ import java.time.*;
 import java.time.temporal.*;
 import java.util.*;
 import java.util.concurrent.*;
+import java.util.regex.*;
 
 import javax.xml.datatype.*;
 
@@ -42,12 +43,14 @@ public class DefaultSwaps {
 		POJO_SWAPS.put(LocalTime.class, new TemporalSwap.IsoLocalTime());
 		POJO_SWAPS.put(OffsetDateTime.class, new TemporalSwap.IsoOffsetDateTime());
 		POJO_SWAPS.put(OffsetTime.class, new TemporalSwap.IsoOffsetTime());
+		POJO_SWAPS.put(StackTraceElement.class, new StackTraceElementSwap());
 		POJO_SWAPS.put(Year.class, new TemporalSwap.IsoYear());
 		POJO_SWAPS.put(YearMonth.class, new TemporalSwap.IsoYearMonth());
 		POJO_SWAPS.put(Temporal.class, new TemporalSwap.IsoInstant());
 		POJO_SWAPS.put(TimeZone.class, new TimeZoneSwap());
 		POJO_SWAPS.put(XMLGregorianCalendar.class, new XMLGregorianCalendarSwap());
 		POJO_SWAPS.put(ZoneId.class, new ZoneIdSwap());
+		POJO_SWAPS.put(MatchResult.class, new MatchResultSwap());
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/MatchResultSwap.java
similarity index 69%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/MatchResultSwap.java
index a040588..92f8cee 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/MatchResultSwap.java
@@ -10,33 +10,30 @@
 // * "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;
+package org.apache.juneau.transforms;
 
 import java.util.*;
+import java.util.regex.*;
 
-import org.apache.http.client.utils.*;
-import org.apache.http.message.*;
+import org.apache.juneau.*;
+import org.apache.juneau.transform.*;
 
 /**
- * Convenience class for setting date headers in RFC2616 format.
+ * Transforms {@link MatchResult MatchResults} to {@code List} objects.
  *
  * <p>
- * Equivalent to the following code:
- * <p class='bcode w800'>
- * 	Header h = <jk>new</jk> Header(name, DateUtils.<jsm>formatDate</jsm>(value));
- * </p>
+ * Entries in the list represent matched groups in a regular expression.
  */
-public final class DateHeader extends BasicHeader {
-
-	private static final long serialVersionUID = 1L;
+public class MatchResultSwap extends PojoSwap<MatchResult,List<String>> {
 
 	/**
-	 * Creates a date request property in RFC2616 format.
-	 *
-	 * @param name The header name.
-	 * @param value The header value.
+	 * Converts the specified {@link Enumeration} to a {@link List}.
 	 */
-	public DateHeader(String name, Date value) {
-		super(name, DateUtils.formatDate(value));
+	@Override /* PojoSwap */
+	public List<String> swap(BeanSession session, MatchResult o) {
+		List<String> l = new ArrayList<>(o.groupCount());
+		for (int i = 0; i <= o.groupCount(); i++)
+			l.add(o.group(i));
+		return l;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/StackTraceElementSwap.java
similarity index 52%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/StackTraceElementSwap.java
index 9c0c950..3654c77 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/HttpMethod.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/transforms/StackTraceElementSwap.java
@@ -1,78 +1,68 @@
-// ***************************************************************************************************************************
-// * 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.http;
-
-import java.util.*;
-
-/**
- * Represents valid HTTP 1.1 method names per the RFC 2616 spec.
- *
- * <ul class='seealso'>
- * 	<li class='extlink'>{@doc RFC2616}
- * </ul>
- */
-public enum HttpMethod {
-
-	/** {@doc RFC2616.section9#sec9.2 OPTIONS} */
-	OPTIONS,
-
-	/** {@doc RFC2616.section9#sec9.3 GET} */
-	GET,
-
-	/** {@doc RFC2616.section9#sec9.4 HEAD} */
-	HEAD,
-
-	/** {@doc RFC2616.section9#sec9.5 POST} */
-	POST,
-
-	/** {@doc RFC2616.section9#sec9.6 PUT} */
-	PUT,
-
-	/** {@doc RFC2616.section9#sec9.7 DELETE} */
-	DELETE,
-
-	/** {@doc RFC2616.section9#sec9.8 TRACE} */
-	TRACE,
-
-	/** {@doc RFC2616.section9#sec9.9 CONNECT} */
-	CONNECT,
-
-	/** A non-standard value. */
-	OTHER;
-
-	private static final Map<String,HttpMethod> cache = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
-	static {
-		cache.put("OPTIONS", OPTIONS);
-		cache.put("GET", GET);
-		cache.put("HEAD", HEAD);
-		cache.put("POST", POST);
-		cache.put("PUT", PUT);
-		cache.put("DELETE", DELETE);
-		cache.put("TRACE", TRACE);
-		cache.put("CONNECT", CONNECT);
-	}
-
-	/**
-	 * Returns the enum for the specified key.
-	 *
-	 * <p>
-	 * Case is ignored.
-	 *
-	 * @param key The HTTP method name.
-	 * @return The HttpMethod enum, or {@link #OTHER} if it's not a standard method name.
-	 */
-	public static HttpMethod forString(String key) {
-		HttpMethod m = cache.get(key);
-		return m == null ? OTHER : m;
-	}
-}
+// ***************************************************************************************************************************
+// * 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.transforms;
+
+import java.util.*;
+
+import org.apache.juneau.*;
+import org.apache.juneau.transform.*;
+
+/**
+ * Transforms {@link StackTraceElement StackTraceElements} to {@code String} objects.
+ *
+ * <p>
+ * The swap is identical to just calling {@link StackTraceElement#toString()}, but provides the ability to
+ * parse the resulting string back into a bean.
+ */
+public class StackTraceElementSwap extends PojoSwap<StackTraceElement,String> {
+
+	/**
+	 * Converts the specified {@link Enumeration} to a {@link List}.
+	 */
+	@Override /* PojoSwap */
+	public String swap(BeanSession session, StackTraceElement o) {
+		return o.toString();
+	}
+
+	@Override /* PojoSwap */
+	public StackTraceElement unswap(BeanSession session, String in, ClassMeta<?> hint) {
+		String methodName = "", fileName = null;
+		int lineNumber = -1;
+
+		if (in == null)
+			return null;
+
+		int i = in.indexOf('(');
+		if (i != -1) {
+			String s = in.substring(i+1, in.lastIndexOf(')'));
+			in = in.substring(0, i);
+			i = s.indexOf(':');
+			if (i != -1) {
+				fileName = s.substring(0, i);
+				lineNumber = Integer.parseInt(s.substring(i+1));
+			} else if ("Native Method".equals(s)) {
+				lineNumber = -2;
+			} else if (! "Unknown Source".equals(s)) {
+				fileName = s;
+			}
+ 		}
+
+		i = in.lastIndexOf('.');
+		if (i != -1) {
+			methodName = in.substring(i+1);
+			in = in.substring(0, i);
+		}
+
+		return new StackTraceElement(in, methodName, fileName, lineNumber);
+	}
+}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Mutable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Mutable.java
new file mode 100644
index 0000000..8d5cbe0
--- /dev/null
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/utils/Mutable.java
@@ -0,0 +1,130 @@
+// ***************************************************************************************************************************
+// * 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.utils;
+
+import java.util.*;
+
+/**
+ * Represents a settable object.
+ *
+ * Typically passed as method parameters to provide by-reference support.
+ *
+ * <p class='bcode w800'>
+ * 	Mutable&lt;String&gt; m = Mutable.<jsm>create</jsm>(String.<jk>class</jk>);
+ * 	callSomeMethodThatSetsValue(m);
+ * 	String val = m.get();
+ * </p>
+ *
+ * <ul class='notes'>
+ * 	<li>
+ * 		This class is not thread safe.
+ * 	<li>
+ * 		This object can be used as hashmap keys.
+ * </ul>
+ *
+ * @param <T> The inner object type.
+ */
+public class Mutable<T> {
+
+	private T value;
+
+	/**
+	 * Creates an empty mutable.
+	 *
+	 * @param <T> The inner object type.
+	 * @param c The inner object type.
+	 * @return The new mutable object.
+	 */
+	public static <T> Mutable<T> create(Class<T> c) {
+		return new Mutable<>();
+	}
+
+	/**
+	 * Creates a mutable initialized with the specified object.
+	 *
+	 * @param <T> The inner object type.
+	 * @param t The inner object.
+	 * @return The new mutable object.
+	 */
+	public static <T> Mutable<T> create(T t) {
+		return new Mutable<>(t);
+	}
+
+	/**
+	 * Creates an empty mutable.
+	 *
+	 * @param <T> The inner object type.
+	 * @return The new mutable object.
+	 */
+	public static <T> Mutable<T> create() {
+		return new Mutable<>();
+	}
+
+	/**
+	 * Creates an empty mutable.
+	 */
+	public Mutable() {}
+
+	/**
+	 * Creates a mutable initialized with the specified object.
+	 *
+	 * @param t The inner object.
+	 */
+	public Mutable(T t) {
+		this.value = t;
+	}
+
+	/**
+	 * Returns the inner object.
+	 *
+	 * @return The inner object, or <jk>null</jk> if empty.
+	 */
+	public T get() {
+		return value;
+	}
+
+	/**
+	 * Sets the inner object.
+	 *
+	 * @param t The inner object.
+	 * @return This object (for method chaining).
+	 */
+	public Mutable<T> set(T t) {
+		this.value = t;
+		return this;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if inner object is set.
+	 *
+	 * @return <jk>true</jk> if inner object is set.
+	 */
+	public boolean isSet() {
+		return value != null;
+	}
+
+	@Override /* Object */
+	public boolean equals(Object o) {
+		return Objects.equals(o, value);
+	}
+
+	@Override /* Object */
+	public int hashCode() {
+		return value == null ? 0 : value.hashCode();
+	}
+
+	@Override /* Object */
+	public String toString() {
+		return value == null ? "null" : value.toString();
+	}
+}
diff --git a/juneau-doc/docs/ReleaseNotes/8.1.4.html b/juneau-doc/docs/ReleaseNotes/8.1.4.html
index 4615401..aa33c3b 100644
--- a/juneau-doc/docs/ReleaseNotes/8.1.4.html
+++ b/juneau-doc/docs/ReleaseNotes/8.1.4.html
@@ -20,6 +20,17 @@
 
 <h5 class='topic w800'>juneau-marshall</h5>
 <ul class='spaced-list'>
+	<li>
+		<ja>@BeanIgnore</ja> and <ja>@Bean</ja> annotations can alternately occur in parent class hierarchy.
+		The first one found dictates whether a class is ignored as a bean or not.
+	<li>
+		New {@link oaj.ObjectMap(Object...)} constructor.
+	<li>
+		New swaps auto-added to all serializers/parsers:
+		<ul>
+			<li class='jc'>{@link oaj.transforms.MatchResultSwap} 
+			<li class='jc'>{@link oaj.transforms.StackTraceElementSwap} 
+		</ul>		
 </ul>
 
 <h5 class='topic w800'>juneau-rest-server</h5>
@@ -37,7 +48,12 @@
 <h5 class='topic w800'>juneau-rest-client</h5>
 <ul class='spaced-list'>
 	<li>
-		New {@link oajrc.RestCallHandler} interface for custom handling of HTTP requests.
+		Completely revamped RestClient API.
+		<ul>
+			<li>All APIs now extend from HttpClient interfaces.
+			<li>Better integration with HttpClient.
+			<li>New fluent-style methods with many new convenience methods.
+		</ul>
 </ul>
 
 <h5 class='topic w800'>juneau-doc</h5>
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/02.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/02.Serializers.html
index a49d9e1..5f03588 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/02.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/02.Serializers.html
@@ -22,8 +22,7 @@ JSON Serializers
 	The JSON serializer provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.json.JsonSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.json.JsonSerializer#JSON_addBeanTypes JSON_addBeanTypes}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/04.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/04.Parsers.html
index 4cacc7a..6e2bcf3 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/04.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/21.JsonDetails/04.Parsers.html
@@ -22,8 +22,7 @@ JSON Parsers
 	The JSON parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.json.JsonParser}
 	<ul>
 		<li class='jf'>{@link oaj.json.JsonParser#JSON_validateEnd JSON_validateEnd}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/02.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/02.Serializers.html
index 7f6fb78..d2bf23c 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/02.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/02.Serializers.html
@@ -26,8 +26,7 @@ XML Serializers
 	The XML serializers provide the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.xml.XmlSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.xml.XmlSerializer#XML_addBeanTypes XML_addBeanTypes}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/03.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/03.Parsers.html
index 6994cb3..1ebd905 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/03.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/22.XmlDetails/03.Parsers.html
@@ -22,8 +22,7 @@ XML Parsers
 	The XML parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.xml.XmlParser}
 	<ul>
 		<li class='jf'>{@link oaj.xml.XmlParser#XML_eventAllocator XML_eventAllocator}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/02.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/02.Serializers.html
index e39a1ef..6025fd9 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/02.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/02.Serializers.html
@@ -26,8 +26,7 @@ HTML Serializers
 	The HTML serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.html.HtmlSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.html.HtmlSerializer#HTML_addBeanTypes HTML_addBeanTypes}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/03.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/03.Parsers.html
index a1096f2..c632c62 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/03.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/23.HtmlDetails/03.Parsers.html
@@ -23,8 +23,7 @@ HTML Parsers
 	The HTML parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 </ul>
 <p>
 	The following pre-configured parsers are provided for convenience:
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/02.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/02.Serializers.html
index db83842..79cd27f 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/02.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/02.Serializers.html
@@ -22,8 +22,7 @@ UON Serializers
 	The UON serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.uon.UonSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.uon.UonSerializer#UON_addBeanTypes UON_addBeanTypes}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/03.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/03.Parsers.html
index 23c9c5b..03abccd 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/03.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/24.UonDetails/03.Parsers.html
@@ -22,8 +22,7 @@ UON Parsers
 	The UON parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.uon.UonParser}
 	<ul>
 		<li class='jf'>{@link oaj.uon.UonParser#UON_decoding UON_decoding}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/02.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/02.Serializers.html
index 5c3f0de..ded510f 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/02.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/02.Serializers.html
@@ -22,8 +22,7 @@ URL-Encoding Serializers
 	The URL-Encoding serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.urlencoding.UrlEncodingSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.urlencoding.UrlEncodingSerializer#URLENC_expandedParams URLENC_expandedParams}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/03.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/03.Parsers.html
index f89e509..447e318 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/03.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/25.UrlEncodingDetails/03.Parsers.html
@@ -22,8 +22,7 @@ URL-Encoding Parsers
 	The URL-Encoding parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.urlencoding.UrlEncodingParser}
 	<ul>
 		<li class='jf'>{@link oaj.urlencoding.UrlEncodingParser#URLENC_expandedParams URLENC_expandedParams}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/01.Serializers.html b/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/01.Serializers.html
index b3669cd..34a8fd4 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/01.Serializers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/01.Serializers.html
@@ -22,8 +22,7 @@ MessagePack Serializers
 	The MessagePack serializer provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link oaj.msgpack.MsgPackSerializer}
 	<ul>
 		<li class='jf'>{@link oaj.msgpack.MsgPackSerializer#MSGPACK_addBeanTypes MSGPACK_addBeanTypes}
diff --git a/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/02.Parsers.html b/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/02.Parsers.html
index d09acef..3388461 100644
--- a/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/02.Parsers.html
+++ b/juneau-doc/docs/Topics/02.juneau-marshall/26.MsgPackDetails/02.Parsers.html
@@ -22,8 +22,7 @@ MessagePack Parsers
 	The MessagePack parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 </ul>
 <p>
 	The following pre-configured parsers are provided for convenience:
diff --git a/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/01.Serializers.html b/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/01.Serializers.html
index 10c60e4..366404d 100644
--- a/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/01.Serializers.html
+++ b/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/01.Serializers.html
@@ -31,8 +31,7 @@ RDF Serializers
 </ul>
 
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jic'>{@link oaj.jena.RdfCommon}
 	<ul>
 		<li class='jf'>{@link oaj.jena.RdfCommon#RDF_arp_embedding RDF_arp_embedding}
diff --git a/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/02.Parsers.html b/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/02.Parsers.html
index 3072472..dd3e737 100644
--- a/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/02.Parsers.html
+++ b/juneau-doc/docs/Topics/03.juneau-marshall-rdf/01.RdfDetails/02.Parsers.html
@@ -35,8 +35,7 @@ RDF Parsers
 	The RDF parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jic'>{@link oaj.jena.RdfCommon}
 	<ul>
 		<li class='jf'>{@link oaj.jena.RdfCommon#RDF_arp_embedding RDF_arp_embedding}
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/07.restRPC.html b/juneau-doc/docs/Topics/06.juneau-rest-server/07.restRPC.html
index e496bed..c3b7fb7 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/07.restRPC.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/07.restRPC.html
@@ -14,10 +14,10 @@
  -->
 
 {8.0.0-updated} 
-restRPC
+REST/RPC
 
 <p>
-	The restRPC (RPC over REST) API allows the creation of client-side remote proxy interfaces for calling methods on server-side POJOs using entirely REST.
+	The REST/RPC (RPC over REST) API allows the creation of client-side remote proxy interfaces for calling methods on server-side POJOs using entirely REST.
 </p>
 
 <h5 class='topic'>Remote Interfaces</h5>
@@ -70,11 +70,11 @@ restRPC
 	Remote Interface proxies are instantiated on the client side using one of the following methods:
 </p>
 <ul class='javatree'>
-	<li class='jc'>{@link oajrc.RestClient}
+	<li class='jc'>{@link oajr.client2.RestClient}
 	<ul>
-		<li class='jm'>{@link oajrc.RestClient#getRrpcInterface(Class) getRrpcInterface(Class)}
-		<li class='jm'>{@link oajrc.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class,Object)}
-		<li class='jm'>{@link oajrc.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class,Object,Serializer,Parser)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRrpcInterface(Class) getRrpcInterface(Class)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class,Object)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class,Object,Serializer,Parser)}
 	</ul>
 </ul>
 <p>
diff --git a/juneau-doc/docs/Topics/06.juneau-rest-server/33.LoggingAndDebugging.html b/juneau-doc/docs/Topics/06.juneau-rest-server/33.LoggingAndDebugging.html
index e902334..3d04f59 100644
--- a/juneau-doc/docs/Topics/06.juneau-rest-server/33.LoggingAndDebugging.html
+++ b/juneau-doc/docs/Topics/06.juneau-rest-server/33.LoggingAndDebugging.html
@@ -145,7 +145,7 @@ Logging / Debugging
 <p>
 <p class='bpcode'>
 	WARNING: 
-	=== HTTP Request (incoming) ===================================================
+	=== HTTP Call (incoming) ===================================================
 	[500] HTTP POST /foo?foo=bar
 		Request length: 3 bytes
 		Response code: 500
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client.html b/juneau-doc/docs/Topics/09.juneau-rest-client.html
index b2bc35d..55653d7 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client.html
@@ -13,6 +13,7 @@
  ***************************************************************************************************************************/
  -->
 
+{8.1.4-updated} 
 juneau-rest-client
 
 <h5 class='figure'>Maven Dependency</h5>
@@ -51,17 +52,17 @@ juneau-rest-client
 		
 		<jc>// Do a REST GET against a remote REST interface and convert
 		// the response to an unstructured ObjectMap object.</jc>
-		ObjectMap m1 = client.doGet(url).getResponse(ObjectMap.<jk>class</jk>);
+		ObjectMap m1 = client.get(url).run().getBody().as(ObjectMap.<jk>class</jk>);
 		
 		<jc>// Same as above, except parse the JSON as a bean.</jc>
-		AddressBook a2 = client.doGet(url).getResponse(AddressBook.<jk>class</jk>);
+		AddressBook a2 = client.get(url).run().getBody().as(AddressBook.<jk>class</jk>);
 	}
 		
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().serializer(XmlSerializer.<jk>class</jk>).parser(XmlSerializer.<jk>class</jk>).build()) {
 		<jc>// Add a person to the address book.
 		// Use XML as the transport medium.</jc>
 		Person p = <jk>new</jk> Person(<js>"Joe Smith"</js>, 21);
-		<jk>int</jk> returnCode = client.doPost(url + <js>"/entries"</js>, p).run();
+		<jk>int</jk> returnCode = client.post(url + <js>"/entries"</js>, p).execute().getStatusCode();
 	}
 </p>
 <p>
@@ -107,8 +108,8 @@ juneau-rest-client
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().json().build()) {
 	
 		<jc>// GET request, ignoring output</jc>
-		<jk>try</jk> {
-			<jk>int</jk> rc = client.doGet(<js>"http://localhost:10000/addressBook"</js>).run();
+		<jk>try</jk> (RestResponse r = client.get(<js>"http://localhost:10000/addressBook"</js>).run()) {
+			<jk>int</jk> rc = r.getStatusCode();
 			<jc>// Succeeded!</jc>
 		} <jk>catch</jk> (RestCallException e) {
 			<jc>// Failed!</jc>
@@ -120,75 +121,97 @@ juneau-rest-client
 		<jc>// Remaining examples ignore thrown exceptions.</jc>		
 				
 		<jc>// GET request, secure, ignoring output</jc>
-		client.doGet(<js>"https://localhost:9443/sample/addressBook"</js>).run();
+		client.get(<js>"https://localhost:9443/sample/addressBook"</js>).execute();
 				
 		<jc>// GET request, getting output as a String.  No POJO parsing is performed.
 		// Note that when calling one of the getX() methods, you don't need to call connect() or disconnect(), since
 		//	it's automatically called for you.</jc>
-		String output = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponseAsString();
+		String output = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().asString();
 				
 		<jc>// GET request, getting output as a Reader</jc>
-		Reader r = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getReader();
+		Reader r = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().asReader();
 				
 		<jc>// GET request, getting output as an untyped map</jc>
 		<jc>// Input must be an object (e.g. "{...}")</jc>
-		ObjectMap m = client.doGet(<js>"http://localhost:10000/addressBook/0"</js>)
-			.getResponse(ObjectMap.<jk>class</jk>);
+		ObjectMap m = client
+			.get(<js>"http://localhost:10000/addressBook/0"</js>)
+			.run()
+			.getBody().as(ObjectMap.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as an untyped list</jc>
 		<jc>// Input must be an array (e.g. "[...]")</jc>
-		ObjectList l = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(ObjectList.<jk>class</jk>);
+		ObjectList l = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(ObjectList.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed bean</jc>
 		<jc>// Input must be an object (e.g. "{...}")</jc>
 		<jc>// Note that you don't have to do any casting!</jc>
-		Person p = client.doGet(<js>"http://localhost:10000/addressBook/0"</js>)
-			.getResponse(Person.<jk>class</jk>);
+		Person p = client
+			.get(<js>"http://localhost:10000/addressBook/0"</js>)
+			.run()
+			.getBody().as(Person.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed bean</jc>
 		<jc>// Input must be an array of objects (e.g. "[{...},{...}]")</jc>
-		Person[] pa = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(Person[].<jk>class</jk>);
+		Person[] pa = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(Person[].<jk>class</jk>);
 				
 		<jc>// Same as above, except as a List&lt;Person&gt;</jc>
-		List&lt;Person&gt; pl = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(List.<jk>class</jk>, Person.<jk>class</jk>);
+		List&lt;Person&gt; pl = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(List.<jk>class</jk>, Person.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed string</jc>
 		<jc>// Input must be a string (e.g. "&lt;string&gt;foo&lt;/string&gt;" or "'foo'")</jc>
-		String name = client.doGet(<js>"http://localhost:10000/addressBook/0/name"</js>)
-			.getResponse(String.<jk>class</jk>);
+		String name = client
+			.get(<js>"http://localhost:10000/addressBook/0/name"</js>)
+			.run()
+			.getBody().as(String.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed number</jc>
 		<jc>// Input must be a number (e.g. "&lt;number&gt;123&lt;/number&gt;" or "123")</jc>
-		<jk>int</jk> age = client.doGet(<js>"http://localhost:10000/addressBook/0/age"</js>)
-			.getResponse(Integer.<jk>class</jk>);
+		<jk>int</jk> age = client
+			.get(<js>"http://localhost:10000/addressBook/0/age"</js>)
+			.run()
+			.getBody().as(Integer.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed boolean</jc>
 		<jc>// Input must be a boolean (e.g. "&lt;boolean&gt;true&lt;/boolean&gt;" or "true")</jc>
-		<jk>boolean</jk> isCurrent = client.doGet(<js>"http://localhost:10000/addressBook/0/addresses/0/isCurrent"</js>)
-			.getResponse(Boolean.<jk>class</jk>);
+		<jk>boolean</jk> isCurrent = client
+			.get(<js>"http://localhost:10000/addressBook/0/addresses/0/isCurrent"</js>)
+			.run()
+			.getBody().as(Boolean.<jk>class</jk>);
 	}
 				
 	<jc>// GET request, getting a filtered object</jc>
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().pojoSwaps(TemporalCalendarSwap.IsoInstant.<jk>class</jk>).build()) {
-		Calendar birthDate = client.doGet(<js>"http://localhost:10000/addressBook/0/birthDate"</js>)
-			.getResponse(GregorianCalendar.<jk>class</jk>);
+		Calendar birthDate = client
+			.get(<js>"http://localhost:10000/addressBook/0/birthDate"</js>)
+			.run()
+			.getBody().as(GregorianCalendar.<jk>class</jk>);
 	
 		<jc>// PUT request on regular field</jc>
 		String newName = <js>"John Smith"</js>;
-		<jk>int</jk> rc = client.doPut(<js>"http://localhost:10000/addressBook/0/name"</js>, newName).run();
+		<jk>int</jk> rc = client.put(<js>"http://localhost:10000/addressBook/0/name"</js>, newName).execute().getStatusCode();
 		
 		<jc>// PUT request on filtered field</jc>
 		Calendar newBirthDate = <jk>new</jk> GregorianCalendar(1, 2, 3, 4, 5, 6);
-		rc = client.doPut(<js>"http://localhost:10000/addressBook/0/birthDate"</js>, newBirthDate).run();
+		rc = client.put(<js>"http://localhost:10000/addressBook/0/birthDate"</js>, newBirthDate).execute().getStatusCode();
 		
 		<jc>// POST of a new entry to a list</jc>
 		Address newAddress = <jk>new</jk> Address(<js>"101 Main St"</js>, <js>"Anywhere"</js>, <js>"NY"</js>, 12121, <jk>false</jk>);
-		rc = client.doPost(<js>"http://localhost:10000/addressBook/0/addresses"</js>, newAddress).run();	
+		rc = client.post(<js>"http://localhost:10000/addressBook/0/addresses"</js>, newAddress).execute().getStatusCode();	
 	}
 </p>
 
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/01.RestProxies.html b/juneau-doc/docs/Topics/09.juneau-rest-client/01.RestProxies.html
index 1344d69..5e84350 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/01.RestProxies.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/01.RestProxies.html
@@ -24,11 +24,11 @@ REST Proxies
 	Remote resources are instantiated using one of the following methods:
 </p>
 <ul class='javatree'>
-	<li class='jc'>{@link oajrc.RestClient}
+	<li class='jc'>{@link oajr.client2.RestClient}
 	<ul>
-		<li class='jm'>{@link oajrc.RestClient#getRemote(Class) getRemote(Class)}
-		<li class='jm'>{@link oajrc.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
-		<li class='jm'>{@link oajrc.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRemote(Class) getRemote(Class)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
+		<li class='jm'>{@link oajr.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
 	</ul>
 </ul>
 <p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication.html
similarity index 100%
copy from juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication.html
copy to juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication.html
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/01.BASIC.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/01.BASIC.html
similarity index 95%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/01.BASIC.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/01.BASIC.html
index 7a2595f..bda52f8 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/01.BASIC.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/01.BASIC.html
@@ -16,7 +16,7 @@
 BASIC Authentication
 
 <p>
-	The {@link oajrc.RestClientBuilder#basicAuth(String,int,String,String)} method 
+	The {@link oajr.client2.RestClientBuilder#basicAuth(String,int,String,String)} method 
 	can be used to quickly enable BASIC authentication support.
 </p>
 
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/02.FORM.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/02.FORM.html
similarity index 95%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/02.FORM.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/02.FORM.html
index 872c9fa..0f2614d 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/02.FORM.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/02.FORM.html
@@ -16,11 +16,11 @@
 FORM-based Authentication
 
 <p>
-	The {@link oajrc.RestClientBuilder} class does not itself provide FORM-based 
+	The {@link oajr.client2.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 oajrc.RestClientBuilder} and override the 
-	{@link oajrc.RestClientBuilder#createHttpClient()} method to provide an 
+	subclass of {@link oajr.client2.RestClientBuilder} and override the 
+	{@link oajr.client2.RestClientBuilder#createHttpClient()} method to provide an 
 	authenticated client.
 </p>
 <p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/03.OIDC.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/03.OIDC.html
similarity index 100%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/03.Authentication/03.OIDC.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/02.Authentication/03.OIDC.html
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/02.SSL.html b/juneau-doc/docs/Topics/09.juneau-rest-client/02.SSL.html
deleted file mode 100644
index cbbfee2..0000000
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/02.SSL.html
+++ /dev/null
@@ -1,50 +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.
- ***************************************************************************************************************************/
- -->
-
-SSL Support
-
-<p>
-	The simplest way to enable SSL support in the client is to use the 
-	{@link oajrc.RestClientBuilder#enableLaxSSL()} method.
-</p>
-
-<h5 class='figure'>Example:</h5>
-<p class='bpcode w800'>
-	<jc>// Create a client that ignores self-signed or otherwise invalid certificates.</jc>
-	RestClient rc = RestClient.<jsm>create</jsm>().enableLaxSSL().build();
-</p>
-<p>
-	A more typical scenario using default cert and hostname verification is shown here:
-</p>
-<p class='bpcode w800'>
-	RestClient rc = RestClient.create().enableSSL().sslProtocols(<js>"TLSv1.2"</js>).build();
-</p>
-<p>
-	The following convenience methods are provided in the builder class for specifying SSL parameters:
-</p>
-<ul class='javatree'>
-	<li class='jc'>{@link oajrc.RestClientBuilder}
-	<ul>
-		<li class='jf'>{@link oajrc.RestClientBuilder#sslProtocols(String...) sslProtocols(String...)}
-		<li class='jf'>{@link oajrc.RestClientBuilder#cipherSuites(String...) cipherSuites(String...)}
-		<li class='jf'>{@link oajrc.RestClientBuilder#hostnameVerifier(HostnameVerifier) hostnameVerifier(HostnameVerifier)}
-		<li class='jf'>{@link oajrc.RestClientBuilder#keyManagers(KeyManager...) keyManagers(KeyManager...)}
-		<li class='jf'>{@link oajrc.RestClientBuilder#trustManagers(TrustManager...)}
-		<li class='jf'>{@link oajrc.RestClientBuilder#secureRandom(SecureRandom)}
-	</ul>
-</ul>
-<p>
-	SSL support can also be enabled by passing in your own connection manager using {@link oajrc.RestClientBuilder#httpClientConnectionManager(HttpClientConnectionManager)}.
-</p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/04.ResponsePatterns.html b/juneau-doc/docs/Topics/09.juneau-rest-client/03.ResponsePatterns.html
similarity index 99%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/04.ResponsePatterns.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/03.ResponsePatterns.html
index 59d372f..c9cbfa2 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/04.ResponsePatterns.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/03.ResponsePatterns.html
@@ -13,7 +13,7 @@
  ***************************************************************************************************************************/
  -->
 
-Using Response Patterns
+{todo} Using Response Patterns
 
 <p>
 	One issue with REST (and HTTP in general) is that the HTTP response code must be set as a header before the 
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/05.PipingOutput.html b/juneau-doc/docs/Topics/09.juneau-rest-client/04.PipingOutput.html
similarity index 100%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/05.PipingOutput.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/04.PipingOutput.html
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/06.Debugging.html b/juneau-doc/docs/Topics/09.juneau-rest-client/05.Debugging.html
similarity index 94%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/06.Debugging.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/05.Debugging.html
index 9e98ddb..e760a58 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/06.Debugging.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/05.Debugging.html
@@ -16,7 +16,7 @@
 Debugging
 
 <p>
-	Use the {@link oajrc.RestClientBuilder#debug()} method to enable logging for HTTP requests
+	Use the {@link oajr.client2.RestClientBuilder#debug()} method to enable logging for HTTP requests
 	made from the client.
 </p>
 <p>
@@ -52,7 +52,7 @@ Debugging
 	server side as well.
 </p>
 <p class='bpcode w800 console'>
-	=== HTTP Request (incoming) ====================================================
+	=== HTTP Call (incoming) =======================================================
 	HTTP POST /testUrl
 	---Headers---
 		Host: localhost:10000
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/07.Logging.html b/juneau-doc/docs/Topics/09.juneau-rest-client/06.Logging.html
similarity index 85%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/07.Logging.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/06.Logging.html
index 2d5a0a0..d073e00 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/07.Logging.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/06.Logging.html
@@ -16,15 +16,15 @@
 Logging
 
 <p>
-	Use the {@link oajrc.RestClientBuilder#logTo(Level,Logger)} and 
-	{@link oajrc.RestCall#logTo(Level,Logger)} methods to log HTTP calls.
+	Use the {@link oajr.client2.RestClientBuilder#logTo(Level,Logger)} and 
+	{@link oajr.client2.RestRequest#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>
 
 <h5 class='figure'>Example:</h5>
 <p class='bpcode w800'>
 	<jc>// Log the HTTP request/response to the specified logger.</jc>
-	<jk>int</jk> rc = restClient.doGet(<jsf>URL</jsf>).logTo(<jsf>INFO</jsf>, getLogger()).run();
+	<jk>int</jk> rc = restClient.get(<jsf>URL</jsf>).logTo(<jsf>INFO</jsf>, getLogger()).run().getStatusCode();
 </p>
 <p>
 	The method call is ignored if the logger level is below the specified level.
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/08.Interceptors.html b/juneau-doc/docs/Topics/09.juneau-rest-client/07.Interceptors.html
similarity index 96%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/08.Interceptors.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/07.Interceptors.html
index e659206..8c60346 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/08.Interceptors.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/07.Interceptors.html
@@ -16,8 +16,7 @@
 Interceptors
 
 <p>
-	The {@link oajrc.RestClientBuilder#interceptors(RestCallInterceptor...)} and 
-	{@link oajrc.RestCall#interceptor(RestCallInterceptor)} methods can be used to 
+	The {@link oajr.client2.RestClientBuilder#interceptors(RestCallInterceptor...)} method can be used to 
 	intercept responses during specific connection lifecycle events.
 </p>
 <p>
diff --git a/juneau-doc/docs/Topics/09.juneau-rest-client/09.Other.html b/juneau-doc/docs/Topics/09.juneau-rest-client/08.Other.html
similarity index 67%
rename from juneau-doc/docs/Topics/09.juneau-rest-client/09.Other.html
rename to juneau-doc/docs/Topics/09.juneau-rest-client/08.Other.html
index 35ffa30..20f391a 100644
--- a/juneau-doc/docs/Topics/09.juneau-rest-client/09.Other.html
+++ b/juneau-doc/docs/Topics/09.juneau-rest-client/08.Other.html
@@ -13,19 +13,19 @@
  ***************************************************************************************************************************/
  -->
 
-Other Useful Methods
+{8.1.4-updated} Other Useful Methods
 
 <p>
-	The {@link oajrc.RestClientBuilder#rootUrl(Object)} method can be used to specify a 
+	The {@link oajr.client2.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='bpcode w800'>
 	<jc>// Create a rest client with a root URL</jc>
 	RestClient rc = RestClient.<jsm>create</jsm>().rootUrl(<js>"http://localhost:9080/foobar"</js>).build();
-	String r = rc.doGet(<js>"/baz"</js>).getResponseAsString();  <jc>// Gets "http://localhost:9080/foobar/baz"</jc>
+	String r = rc.get(<js>"/baz"</js>).run().getBody().asString();  <jc>// Gets "http://localhost:9080/foobar/baz"</jc>
 </p>
 <p>
-	The {@link oajrc.RestClientBuilder#set(String,Object)} method can be used to 
+	The {@link oajr.client2.RestClientBuilder#set(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 oaj.BeanContext#BEAN_ignoreUnknownBeanProperties} property.
@@ -36,18 +36,5 @@ Other Useful Methods
 		.set(<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 oajrc.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.
-</p>
-<p class='bpcode w800'>
-	<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>)
-		.retryable(180, 10000, RetryOn.<jsf>DEFAULT</jsf>)
-		.run();
+	MyPojo myPojo = rc.get(<jsf>URL</jsf>).run().getBody().as(MyPojo.<jk>class</jk>);
 </p>
diff --git a/juneau-doc/docs/Topics/10.juneau-rest-mock/02.MockRemote.html b/juneau-doc/docs/Topics/10.juneau-rest-mock/02.MockRemote.html
index 6e5ec16..9f6e8c3 100644
--- a/juneau-doc/docs/Topics/10.juneau-rest-mock/02.MockRemote.html
+++ b/juneau-doc/docs/Topics/10.juneau-rest-mock/02.MockRemote.html
@@ -54,8 +54,8 @@ MockRemote
 	It looks simple, but there's a lot going on here.   
 </p>
 <p>
-	Remote resource interfaces are normally created through the {@link oajrc.RestClient#getRemote(Class)} method.
-	The {@link oajr.mock2.MockRemote} will create a {@link oajrc.RestClient} using a specialized <c>HttpClientConnectionManager</c>
+	Remote resource interfaces are normally created through the {@link oajr.client2.RestClient#getRemote(Class)} method.
+	The {@link oajr.mock2.MockRemote} will create a {@link oajr.client2.RestClient} using a specialized <c>HttpClientConnectionManager</c>
 	designed to transform client-side <c>HttpRequest</c>/<c>HttpResponse</c> objects into server-side 
 	{@link oajr.mock2.MockServletRequest}/{@link oajr.mock2.MockServletResponse} objects and then pass those to the {@link oajr.mock2.MockRest} 
 	object described in the previous section.
diff --git a/juneau-doc/docs/Topics/19.juneau-petstore/04.PetstoreApp.html b/juneau-doc/docs/Topics/19.juneau-petstore/04.PetstoreApp.html
index 102093f..430f497 100644
--- a/juneau-doc/docs/Topics/19.juneau-petstore/04.PetstoreApp.html
+++ b/juneau-doc/docs/Topics/19.juneau-petstore/04.PetstoreApp.html
@@ -1,3 +1,18 @@
+<!--
+/***************************************************************************************************************************
+ * 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.
+ ***************************************************************************************************************************/
+ -->
+
 {8.1.4-new}
 About Petstore App <br>
 <div style="width: 70%;">
diff --git a/juneau-doc/src/main/javadoc/overview.html b/juneau-doc/src/main/javadoc/overview.html
index 88bf69d..3a9defc 100644
--- a/juneau-doc/src/main/javadoc/overview.html
+++ b/juneau-doc/src/main/javadoc/overview.html
@@ -378,7 +378,7 @@
 			<li><p><a class='doclink' href='#juneau-rest-server.RestMethod.PredefinedExceptions'>Predefined Exceptions</a></p>
 			<li><p><a class='doclink' href='#juneau-rest-server.RestMethod.PredefinedHelperBeans'>Predefined Helper Beans</a></p>
 		</ol>
-		<li><p><a class='doclink' href='#juneau-rest-server.restRPC'>restRPC</a><span class='update'>8.0.0-updated</span></p>
+		<li><p><a class='doclink' href='#juneau-rest-server.restRPC'>REST/RPC</a><span class='update'>8.0.0-updated</span></p>
 		<li><p><a class='doclink' href='#juneau-rest-server.OpenApiSchemaPartParsing'>OpenAPI Schema Part Parsing</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-server.OpenApiSchemaPartSerializing'>OpenAPI Schema Part Serializing</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-server.HttpPartAnnotations'>HTTP-Part Annotations</a></p>
@@ -458,7 +458,7 @@
 		<li><p><a class='doclink' href='#juneau-rest-server-springboot.Overview'>Overview</a><span class='update'>8.0.0-new</span></p>
 		<li><p><a class='doclink' href='#juneau-rest-server-springboot.ChildResources'>Child Resources</a><span class='update'>8.1.0-new</span></p>
 	</ol>
-	<li><p class='toc2'><a class='doclink' href='#juneau-rest-client'>juneau-rest-client</a></p>
+	<li><p class='toc2'><a class='doclink' href='#juneau-rest-client'>juneau-rest-client</a><span class='update'><b>8.1.4-updated</b></span></p>
 	<ol>
 		<li><p><a class='doclink' href='#juneau-rest-client.RestProxies'>REST Proxies</a></p>
 		<ol>
@@ -473,19 +473,18 @@
 			<li><p><a class='doclink' href='#juneau-rest-client.RestProxies.Response'>@Response</a></p>
 			<li><p><a class='doclink' href='#juneau-rest-client.RestProxies.DualPurposeInterfaces'>Dual-purpose (end-to-end) interfaces</a><span class='update'>8.0.0-new</span></p>
 		</ol>
-		<li><p><a class='doclink' href='#juneau-rest-client.SSL'>SSL Support</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-client.Authentication'>Authentication</a></p>
 		<ol>
 			<li><p><a class='doclink' href='#juneau-rest-client.Authentication.BASIC'>BASIC Authentication</a></p>
 			<li><p><a class='doclink' href='#juneau-rest-client.Authentication.FORM'>FORM-based Authentication</a></p>
 			<li><p><a class='doclink' href='#juneau-rest-client.Authentication.OIDC'>OIDC Authentication</a></p>
 		</ol>
-		<li><p><a class='doclink' href='#juneau-rest-client.ResponsePatterns'>Using Response Patterns</a></p>
+		<li><p><a class='doclink' href='#juneau-rest-client.ResponsePatterns'></a><span class='update'>todo</span></p>
 		<li><p><a class='doclink' href='#juneau-rest-client.PipingOutput'>Piping Response Output</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-client.Debugging'>Debugging</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-client.Logging'>Logging</a></p>
 		<li><p><a class='doclink' href='#juneau-rest-client.Interceptors'>Interceptors</a></p>
-		<li><p><a class='doclink' href='#juneau-rest-client.Other'>Other Useful Methods</a></p>
+		<li><p><a class='doclink' href='#juneau-rest-client.Other'></a><span class='update'><b>8.1.4-updated</b></span></p>
 	</ol>
 	<li><p class='toc2'><a class='doclink' href='#juneau-rest-mock'>juneau-rest-mock</a><span class='update'>8.1.0-new</span></p>
 	<ol>
@@ -554,18 +553,18 @@
 		<li><p><a class='doclink' href='#juneau-examples-rest-springboot.Building'>Building and Running from Command-Line</a><span class='update'>8.0.0-new</span></p>
 		<li><p><a class='doclink' href='#juneau-examples-rest-springboot.DeployingToHeroku'>Deploying to Heroku</a><span class='update'>8.0.0-new</span></p>
 	</ol>
+	<li><p class='toc2'><a class='doclink' href='#juneau-petstore'>juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></p>
+	<ol>
+		<li><p><a class='doclink' href='#juneau-petstore.Installing'>Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
+		<li><p><a class='doclink' href='#juneau-petstore.Running'>Running Petstore manually</a><span class='update'><b>8.1.4-new</b></span></p>
+		<li><p><a class='doclink' href='#juneau-petstore.Building'>Building and Running from Command-Line (Using Dockerfiles)</a><span class='update'><b>8.1.4-new</b></span></p>
+	</ol>
 	<li><p class='toc2'><a class='doclink' href='#Glossaries'>Glossaries</a><span class='update'>8.1.3-new</span></p>
 	<ol>
 		<li><p><a class='doclink' href='#Glossaries.LanguageSupport'>Language Support</a><span class='update'>8.1.3-new</span></p>
 		<li><p><a class='doclink' href='#Glossaries.Annotations'>Annotations</a><span class='update'>8.1.3-new</span></p>
 		<li><p><a class='doclink' href='#Glossaries.ConfigurableProperties'>Configurable Properties</a><span class='update'>8.1.3-new</span></p>
 	</ol>
-	<li><p class='toc2'><a class='doclink' href='#juneau-petstore'>juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></p>
-	<ol>
-		<li><p><a class='doclink' href='#juneau-petstore.Installing'>Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
-		<li><p><a class='doclink' href='#juneau-petstore.Running'>Running in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
-		<li><p><a class='doclink' href='#juneau-petstore.Building'>Building and Running from Command-Line</a><span class='update'><b>8.1.4-new</b></span></p>
-	</ol>
 	<li><p class='toc2'><a class='doclink' href='#Security'>Security Best-Practices</a></p>
 	<ol>
 		<li><p><a class='doclink' href='#Security.juneau-marshall'>juneau-marshall</a></p>
@@ -4917,8 +4916,7 @@
 	The JSON serializer provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.json.JsonSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.json.JsonSerializer#JSON_addBeanTypes JSON_addBeanTypes}
@@ -5015,8 +5013,7 @@
 	The JSON parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.json.JsonParser}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.json.JsonParser#JSON_validateEnd JSON_validateEnd}
@@ -5700,8 +5697,7 @@
 	The XML serializers provide the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.xml.XmlSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.xml.XmlSerializer#XML_addBeanTypes XML_addBeanTypes}
@@ -5742,8 +5738,7 @@
 	The XML parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.xml.XmlParser}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.xml.XmlParser#XML_eventAllocator XML_eventAllocator}
@@ -8020,8 +8015,7 @@
 	The HTML serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.html.HtmlSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.html.HtmlSerializer#HTML_addBeanTypes HTML_addBeanTypes}
@@ -8076,8 +8070,7 @@
 	The HTML parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 </ul>
 <p>
 	The following pre-configured parsers are provided for convenience:
@@ -8706,8 +8699,7 @@
 	The UON serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.uon.UonSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.uon.UonSerializer#UON_addBeanTypes UON_addBeanTypes}
@@ -8739,8 +8731,7 @@
 	The UON parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.uon.UonParser}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.uon.UonParser#UON_decoding UON_decoding}
@@ -8905,8 +8896,7 @@
 	The URL-Encoding serializers provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.urlencoding.UrlEncodingSerializer#URLENC_expandedParams URLENC_expandedParams}
@@ -8938,8 +8928,7 @@
 	The URL-Encoding parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.urlencoding.UrlEncodingParser}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.urlencoding.UrlEncodingParser#URLENC_expandedParams URLENC_expandedParams}
@@ -9003,8 +8992,7 @@
 	The MessagePack serializer provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jc'>{@link org.apache.juneau.msgpack.MsgPackSerializer}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.msgpack.MsgPackSerializer#MSGPACK_addBeanTypes MSGPACK_addBeanTypes}
@@ -9033,8 +9021,7 @@
 	The MessagePack parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 </ul>
 <p>
 	The following pre-configured parsers are provided for convenience:
@@ -10501,8 +10488,7 @@
 </ul>
 
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonSerializer Common Serializer Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jic'>{@link org.apache.juneau.jena.RdfCommon}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.jena.RdfCommon#RDF_arp_embedding RDF_arp_embedding}
@@ -10604,8 +10590,7 @@
 	The RDF parser provides the following settings:
 </p>
 <ul class='javatree'>
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.Common Common Properties}
-	<li class='link'>{@doc juneau-marshall.ConfigurableProperties.CommonParser Common Parser Properties}
+	<li class='link'>{@doc juneau-marshall.ConfigurableProperties Configurable Properties}
 	<li class='jic'>{@link org.apache.juneau.jena.RdfCommon}
 	<ul>
 		<li class='jf'>{@link org.apache.juneau.jena.RdfCommon#RDF_arp_embedding RDF_arp_embedding}
@@ -15674,10 +15659,10 @@
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.restRPC' id='juneau-rest-server.restRPC'>6.7 - restRPC</a><span class='update'>8.0.0-updated</span></h3>
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-server.restRPC' id='juneau-rest-server.restRPC'>6.7 - REST/RPC</a><span class='update'>8.0.0-updated</span></h3>
 <div class='topic'><!-- START: 6.7 - juneau-rest-server.restRPC -->
 <p>
-	The restRPC (RPC over REST) API allows the creation of client-side remote proxy interfaces for calling methods on server-side POJOs using entirely REST.
+	The REST/RPC (RPC over REST) API allows the creation of client-side remote proxy interfaces for calling methods on server-side POJOs using entirely REST.
 </p>
 
 <h5 class='topic'>Remote Interfaces</h5>
@@ -15730,11 +15715,11 @@
 	Remote Interface proxies are instantiated on the client side using one of the following methods:
 </p>
 <ul class='javatree'>
-	<li class='jc'>{@link org.apache.juneau.rest.client.RestClient}
+	<li class='jc'>{@link org.apache.juneau.rest.client2.RestClient}
 	<ul>
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRrpcInterface(Class) getRrpcInterface(Class)}
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class,Object)}
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class,Object,Serializer,Parser)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class) getRrpcInterface(Class)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class,Object)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class,Object,Serializer,Parser)}
 	</ul>
 </ul>
 <p>
@@ -21536,7 +21521,7 @@
 <p>
 <p class='bpcode'>
 	WARNING: 
-	=== HTTP Request (incoming) ===================================================
+	=== HTTP Call (incoming) ===================================================
 	[500] HTTP POST /foo?foo=bar
 		Request length: 3 bytes
 		Response code: 500
@@ -22488,7 +22473,7 @@
 
 <!-- ==================================================================================================== -->
 
-<h2 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client' id='juneau-rest-client'>9 - juneau-rest-client</a></h2>
+<h2 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client' id='juneau-rest-client'>9 - juneau-rest-client</a><span class='update'><b>8.1.4-updated</b></span></h2>
 <div class='topic'><!-- START: 9 - juneau-rest-client -->
 <h5 class='figure'>Maven Dependency</h5>
 <p class='bpcode w500'>
@@ -22526,17 +22511,17 @@
 		
 		<jc>// Do a REST GET against a remote REST interface and convert
 		// the response to an unstructured ObjectMap object.</jc>
-		ObjectMap m1 = client.doGet(url).getResponse(ObjectMap.<jk>class</jk>);
+		ObjectMap m1 = client.get(url).run().getBody().as(ObjectMap.<jk>class</jk>);
 		
 		<jc>// Same as above, except parse the JSON as a bean.</jc>
-		AddressBook a2 = client.doGet(url).getResponse(AddressBook.<jk>class</jk>);
+		AddressBook a2 = client.get(url).run().getBody().as(AddressBook.<jk>class</jk>);
 	}
 		
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().serializer(XmlSerializer.<jk>class</jk>).parser(XmlSerializer.<jk>class</jk>).build()) {
 		<jc>// Add a person to the address book.
 		// Use XML as the transport medium.</jc>
 		Person p = <jk>new</jk> Person(<js>"Joe Smith"</js>, 21);
-		<jk>int</jk> returnCode = client.doPost(url + <js>"/entries"</js>, p).run();
+		<jk>int</jk> returnCode = client.post(url + <js>"/entries"</js>, p).execute().getStatusCode();
 	}
 </p>
 <p>
@@ -22582,8 +22567,8 @@
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().json().build()) {
 	
 		<jc>// GET request, ignoring output</jc>
-		<jk>try</jk> {
-			<jk>int</jk> rc = client.doGet(<js>"http://localhost:10000/addressBook"</js>).run();
+		<jk>try</jk> (RestResponse r = client.get(<js>"http://localhost:10000/addressBook"</js>).run()) {
+			<jk>int</jk> rc = r.getStatusCode();
 			<jc>// Succeeded!</jc>
 		} <jk>catch</jk> (RestCallException e) {
 			<jc>// Failed!</jc>
@@ -22595,75 +22580,97 @@
 		<jc>// Remaining examples ignore thrown exceptions.</jc>		
 				
 		<jc>// GET request, secure, ignoring output</jc>
-		client.doGet(<js>"https://localhost:9443/sample/addressBook"</js>).run();
+		client.get(<js>"https://localhost:9443/sample/addressBook"</js>).execute();
 				
 		<jc>// GET request, getting output as a String.  No POJO parsing is performed.
 		// Note that when calling one of the getX() methods, you don't need to call connect() or disconnect(), since
 		//	it's automatically called for you.</jc>
-		String output = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponseAsString();
+		String output = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().asString();
 				
 		<jc>// GET request, getting output as a Reader</jc>
-		Reader r = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getReader();
+		Reader r = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().asReader();
 				
 		<jc>// GET request, getting output as an untyped map</jc>
 		<jc>// Input must be an object (e.g. "{...}")</jc>
-		ObjectMap m = client.doGet(<js>"http://localhost:10000/addressBook/0"</js>)
-			.getResponse(ObjectMap.<jk>class</jk>);
+		ObjectMap m = client
+			.get(<js>"http://localhost:10000/addressBook/0"</js>)
+			.run()
+			.getBody().as(ObjectMap.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as an untyped list</jc>
 		<jc>// Input must be an array (e.g. "[...]")</jc>
-		ObjectList l = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(ObjectList.<jk>class</jk>);
+		ObjectList l = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(ObjectList.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed bean</jc>
 		<jc>// Input must be an object (e.g. "{...}")</jc>
 		<jc>// Note that you don't have to do any casting!</jc>
-		Person p = client.doGet(<js>"http://localhost:10000/addressBook/0"</js>)
-			.getResponse(Person.<jk>class</jk>);
+		Person p = client
+			.get(<js>"http://localhost:10000/addressBook/0"</js>)
+			.run()
+			.getBody().as(Person.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed bean</jc>
 		<jc>// Input must be an array of objects (e.g. "[{...},{...}]")</jc>
-		Person[] pa = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(Person[].<jk>class</jk>);
+		Person[] pa = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(Person[].<jk>class</jk>);
 				
 		<jc>// Same as above, except as a List&lt;Person&gt;</jc>
-		List&lt;Person&gt; pl = client.doGet(<js>"http://localhost:10000/addressBook"</js>)
-			.getResponse(List.<jk>class</jk>, Person.<jk>class</jk>);
+		List&lt;Person&gt; pl = client
+			.get(<js>"http://localhost:10000/addressBook"</js>)
+			.run()
+			.getBody().as(List.<jk>class</jk>, Person.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed string</jc>
 		<jc>// Input must be a string (e.g. "&lt;string&gt;foo&lt;/string&gt;" or "'foo'")</jc>
-		String name = client.doGet(<js>"http://localhost:10000/addressBook/0/name"</js>)
-			.getResponse(String.<jk>class</jk>);
+		String name = client
+			.get(<js>"http://localhost:10000/addressBook/0/name"</js>)
+			.run()
+			.getBody().as(String.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed number</jc>
 		<jc>// Input must be a number (e.g. "&lt;number&gt;123&lt;/number&gt;" or "123")</jc>
-		<jk>int</jk> age = client.doGet(<js>"http://localhost:10000/addressBook/0/age"</js>)
-			.getResponse(Integer.<jk>class</jk>);
+		<jk>int</jk> age = client
+			.get(<js>"http://localhost:10000/addressBook/0/age"</js>)
+			.run()
+			.getBody().as(Integer.<jk>class</jk>);
 				
 		<jc>// GET request, getting output as a parsed boolean</jc>
 		<jc>// Input must be a boolean (e.g. "&lt;boolean&gt;true&lt;/boolean&gt;" or "true")</jc>
-		<jk>boolean</jk> isCurrent = client.doGet(<js>"http://localhost:10000/addressBook/0/addresses/0/isCurrent"</js>)
-			.getResponse(Boolean.<jk>class</jk>);
+		<jk>boolean</jk> isCurrent = client
+			.get(<js>"http://localhost:10000/addressBook/0/addresses/0/isCurrent"</js>)
+			.run()
+			.getBody().as(Boolean.<jk>class</jk>);
 	}
 				
 	<jc>// GET request, getting a filtered object</jc>
 	<jk>try</jk> (RestClient client = RestClient.<jsm>create</jsm>().pojoSwaps(TemporalCalendarSwap.IsoInstant.<jk>class</jk>).build()) {
-		Calendar birthDate = client.doGet(<js>"http://localhost:10000/addressBook/0/birthDate"</js>)
-			.getResponse(GregorianCalendar.<jk>class</jk>);
+		Calendar birthDate = client
+			.get(<js>"http://localhost:10000/addressBook/0/birthDate"</js>)
+			.run()
+			.getBody().as(GregorianCalendar.<jk>class</jk>);
 	
 		<jc>// PUT request on regular field</jc>
 		String newName = <js>"John Smith"</js>;
-		<jk>int</jk> rc = client.doPut(<js>"http://localhost:10000/addressBook/0/name"</js>, newName).run();
+		<jk>int</jk> rc = client.put(<js>"http://localhost:10000/addressBook/0/name"</js>, newName).execute().getStatusCode();
 		
 		<jc>// PUT request on filtered field</jc>
 		Calendar newBirthDate = <jk>new</jk> GregorianCalendar(1, 2, 3, 4, 5, 6);
-		rc = client.doPut(<js>"http://localhost:10000/addressBook/0/birthDate"</js>, newBirthDate).run();
+		rc = client.put(<js>"http://localhost:10000/addressBook/0/birthDate"</js>, newBirthDate).execute().getStatusCode();
 		
 		<jc>// POST of a new entry to a list</jc>
 		Address newAddress = <jk>new</jk> Address(<js>"101 Main St"</js>, <js>"Anywhere"</js>, <js>"NY"</js>, 12121, <jk>false</jk>);
-		rc = client.doPost(<js>"http://localhost:10000/addressBook/0/addresses"</js>, newAddress).run();	
+		rc = client.post(<js>"http://localhost:10000/addressBook/0/addresses"</js>, newAddress).execute().getStatusCode();	
 	}
 </p>
 
@@ -22687,11 +22694,11 @@
 	Remote resources are instantiated using one of the following methods:
 </p>
 <ul class='javatree'>
-	<li class='jc'>{@link org.apache.juneau.rest.client.RestClient}
+	<li class='jc'>{@link org.apache.juneau.rest.client2.RestClient}
 	<ul>
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRemote(Class) getRemote(Class)}
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
-		<li class='jm'>{@link org.apache.juneau.rest.client.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class) getRemote(Class)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object) getRemote(Class,Object)}
+		<li class='jm'>{@link org.apache.juneau.rest.client2.RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class,Object,Serializer,Parser)}
 	</ul>
 </ul>
 <p>
@@ -23753,47 +23760,8 @@
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.SSL' id='juneau-rest-client.SSL'>9.2 - SSL Support</a></h3>
-<div class='topic'><!-- START: 9.2 - juneau-rest-client.SSL -->
-<p>
-	The simplest way to enable SSL support in the client is to use the 
-	{@link org.apache.juneau.rest.client.RestClientBuilder#enableLaxSSL()} method.
-</p>
-
-<h5 class='figure'>Example:</h5>
-<p class='bpcode w800'>
-	<jc>// Create a client that ignores self-signed or otherwise invalid certificates.</jc>
-	RestClient rc = RestClient.<jsm>create</jsm>().enableLaxSSL().build();
-</p>
-<p>
-	A more typical scenario using default cert and hostname verification is shown here:
-</p>
-<p class='bpcode w800'>
-	RestClient rc = RestClient.create().enableSSL().sslProtocols(<js>"TLSv1.2"</js>).build();
-</p>
-<p>
-	The following convenience methods are provided in the builder class for specifying SSL parameters:
-</p>
-<ul class='javatree'>
-	<li class='jc'>{@link org.apache.juneau.rest.client.RestClientBuilder}
-	<ul>
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#sslProtocols(String...) sslProtocols(String...)}
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#cipherSuites(String...) cipherSuites(String...)}
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#hostnameVerifier(HostnameVerifier) hostnameVerifier(HostnameVerifier)}
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#keyManagers(KeyManager...) keyManagers(KeyManager...)}
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#trustManagers(TrustManager...)}
-		<li class='jf'>{@link org.apache.juneau.rest.client.RestClientBuilder#secureRandom(SecureRandom)}
-	</ul>
-</ul>
-<p>
-	SSL support can also be enabled by passing in your own connection manager using {@link org.apache.juneau.rest.client.RestClientBuilder#httpClientConnectionManager(HttpClientConnectionManager)}.
-</p>
-</div><!-- END: 9.2 - juneau-rest-client.SSL -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication' id='juneau-rest-client.Authentication'>9.3 - Authentication</a></h3>
-<div class='topic'><!-- START: 9.3 - juneau-rest-client.Authentication -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication' id='juneau-rest-client.Authentication'>9.2 - Authentication</a></h3>
+<div class='topic'><!-- START: 9.2 - juneau-rest-client.Authentication -->
 <p>
 	The Juneau REST client itself does not implement any support for authentication.  
 	Instead, it delegates it to the underlying Apache HTTP Client interface.
@@ -23804,10 +23772,10 @@
 
 <!-- ==================================================================================================== -->
 
-<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.BASIC' id='juneau-rest-client.Authentication.BASIC'>9.3.1 - BASIC Authentication</a></h4>
-<div class='topic'><!-- START: 9.3.1 - juneau-rest-client.Authentication.BASIC -->
+<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.BASIC' id='juneau-rest-client.Authentication.BASIC'>9.2.1 - BASIC Authentication</a></h4>
+<div class='topic'><!-- START: 9.2.1 - juneau-rest-client.Authentication.BASIC -->
 <p>
-	The {@link org.apache.juneau.rest.client.RestClientBuilder#basicAuth(String,int,String,String)} method 
+	The {@link org.apache.juneau.rest.client2.RestClientBuilder#basicAuth(String,int,String,String)} method 
 	can be used to quickly enable BASIC authentication support.
 </p>
 
@@ -23829,18 +23797,18 @@
 	p.setCredentials(scope, up);
 	builder.setDefaultCredentialsProvider(p);
 </p>
-</div><!-- END: 9.3.1 - juneau-rest-client.Authentication.BASIC -->
+</div><!-- END: 9.2.1 - juneau-rest-client.Authentication.BASIC -->
 
 <!-- ==================================================================================================== -->
 
-<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.FORM' id='juneau-rest-client.Authentication.FORM'>9.3.2 - FORM-based Authentication</a></h4>
-<div class='topic'><!-- START: 9.3.2 - juneau-rest-client.Authentication.FORM -->
+<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.FORM' id='juneau-rest-client.Authentication.FORM'>9.2.2 - FORM-based Authentication</a></h4>
+<div class='topic'><!-- START: 9.2.2 - juneau-rest-client.Authentication.FORM -->
 <p>
-	The {@link org.apache.juneau.rest.client.RestClientBuilder} class does not itself provide FORM-based 
+	The {@link org.apache.juneau.rest.client2.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.RestClientBuilder} and override the 
-	{@link org.apache.juneau.rest.client.RestClientBuilder#createHttpClient()} method to provide an 
+	subclass of {@link org.apache.juneau.rest.client2.RestClientBuilder} and override the 
+	{@link org.apache.juneau.rest.client2.RestClientBuilder#createHttpClient()} method to provide an 
 	authenticated client.
 </p>
 <p>
@@ -23918,12 +23886,12 @@
 		}
 	}
 </p>
-</div><!-- END: 9.3.2 - juneau-rest-client.Authentication.FORM -->
+</div><!-- END: 9.2.2 - juneau-rest-client.Authentication.FORM -->
 
 <!-- ==================================================================================================== -->
 
-<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.OIDC' id='juneau-rest-client.Authentication.OIDC'>9.3.3 - OIDC Authentication</a></h4>
-<div class='topic'><!-- START: 9.3.3 - juneau-rest-client.Authentication.OIDC -->
+<h4 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Authentication.OIDC' id='juneau-rest-client.Authentication.OIDC'>9.2.3 - OIDC Authentication</a></h4>
+<div class='topic'><!-- START: 9.2.3 - juneau-rest-client.Authentication.OIDC -->
 <p>
 	The following example shows how the <c>JazzRestClient</c> class provides OIDC authentication 
 	support.
@@ -24046,13 +24014,13 @@
 		}
 	}
 </p>
-</div><!-- END: 9.3.3 - juneau-rest-client.Authentication.OIDC -->
-</div><!-- END: 9.3 - juneau-rest-client.Authentication -->
+</div><!-- END: 9.2.3 - juneau-rest-client.Authentication.OIDC -->
+</div><!-- END: 9.2 - juneau-rest-client.Authentication -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.ResponsePatterns' id='juneau-rest-client.ResponsePatterns'>9.4 - Using Response Patterns</a></h3>
-<div class='topic'><!-- START: 9.4 - juneau-rest-client.ResponsePatterns -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.ResponsePatterns' id='juneau-rest-client.ResponsePatterns'>9.3 - </a><span class='update'>todo</span></h3>
+<div class='topic'><!-- START: 9.3 - juneau-rest-client.ResponsePatterns -->
 <p>
 	One issue with REST (and HTTP in general) is that the HTTP response code must be set as a header before the 
 	body of the request is sent.  
@@ -24142,12 +24110,12 @@
 	use {@link org.apache.juneau.rest.client.RestCall#getCapturedResponse()} since this method will not absorb 
 	the response for those other methods.
 </p>
-</div><!-- END: 9.4 - juneau-rest-client.ResponsePatterns -->
+</div><!-- END: 9.3 - juneau-rest-client.ResponsePatterns -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.PipingOutput' id='juneau-rest-client.PipingOutput'>9.5 - Piping Response Output</a></h3>
-<div class='topic'><!-- START: 9.5 - juneau-rest-client.PipingOutput -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.PipingOutput' id='juneau-rest-client.PipingOutput'>9.4 - Piping Response Output</a></h3>
+<div class='topic'><!-- START: 9.4 - juneau-rest-client.PipingOutput -->
 <p>
 	The {@link org.apache.juneau.rest.client.RestCall} class provides various convenience <c>pipeTo()</c> 
 	methods to pipe output to output streams and writers.
@@ -24165,14 +24133,14 @@
 	<jc>// Pipe output from REST call to System.out in real-time.</jc>
 	restClient.doPost(<jsf>URL</jsf>).byLines().pipeTo(<jk>new</jk> PrintWriter(System.<jk>out</jk>)).run();
 </p>
-</div><!-- END: 9.5 - juneau-rest-client.PipingOutput -->
+</div><!-- END: 9.4 - juneau-rest-client.PipingOutput -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Debugging' id='juneau-rest-client.Debugging'>9.6 - Debugging</a></h3>
-<div class='topic'><!-- START: 9.6 - juneau-rest-client.Debugging -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Debugging' id='juneau-rest-client.Debugging'>9.5 - Debugging</a></h3>
+<div class='topic'><!-- START: 9.5 - juneau-rest-client.Debugging -->
 <p>
-	Use the {@link org.apache.juneau.rest.client.RestClientBuilder#debug()} method to enable logging for HTTP requests
+	Use the {@link org.apache.juneau.rest.client2.RestClientBuilder#debug()} method to enable logging for HTTP requests
 	made from the client.
 </p>
 <p>
@@ -24224,22 +24192,22 @@
 	{"foo":"bar","baz":123}
 	=== END ========================================================================
 </p>
-</div><!-- END: 9.6 - juneau-rest-client.Debugging -->
+</div><!-- END: 9.5 - juneau-rest-client.Debugging -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Logging' id='juneau-rest-client.Logging'>9.7 - Logging</a></h3>
-<div class='topic'><!-- START: 9.7 - juneau-rest-client.Logging -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Logging' id='juneau-rest-client.Logging'>9.6 - Logging</a></h3>
+<div class='topic'><!-- START: 9.6 - juneau-rest-client.Logging -->
 <p>
-	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.
+	Use the {@link org.apache.juneau.rest.client2.RestClientBuilder#logTo(Level,Logger)} and 
+	{@link org.apache.juneau.rest.client2.RestRequest#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>
 
 <h5 class='figure'>Example:</h5>
 <p class='bpcode w800'>
 	<jc>// Log the HTTP request/response to the specified logger.</jc>
-	<jk>int</jk> rc = restClient.doGet(<jsf>URL</jsf>).logTo(<jsf>INFO</jsf>, getLogger()).run();
+	<jk>int</jk> rc = restClient.get(<jsf>URL</jsf>).logTo(<jsf>INFO</jsf>, getLogger()).run().getStatusCode();
 </p>
 <p>
 	The method call is ignored if the logger level is below the specified level.
@@ -24248,15 +24216,14 @@
 	Customized logging can be handled by sub-classing the {@link org.apache.juneau.rest.client.RestCallLogger} 
 	class and using the  {@link org.apache.juneau.rest.client.RestCall#interceptor(RestCallInterceptor)} method.
 </p>
-</div><!-- END: 9.7 - juneau-rest-client.Logging -->
+</div><!-- END: 9.6 - juneau-rest-client.Logging -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Interceptors' id='juneau-rest-client.Interceptors'>9.8 - Interceptors</a></h3>
-<div class='topic'><!-- START: 9.8 - juneau-rest-client.Interceptors -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Interceptors' id='juneau-rest-client.Interceptors'>9.7 - Interceptors</a></h3>
+<div class='topic'><!-- START: 9.7 - juneau-rest-client.Interceptors -->
 <p>
-	The {@link org.apache.juneau.rest.client.RestClientBuilder#interceptors(RestCallInterceptor...)} and 
-	{@link org.apache.juneau.rest.client.RestCall#interceptor(RestCallInterceptor)} methods can be used to 
+	The {@link org.apache.juneau.rest.client2.RestClientBuilder#interceptors(RestCallInterceptor...)} method can be used to 
 	intercept responses during specific connection lifecycle events.
 </p>
 <p>
@@ -24352,23 +24319,23 @@
 		}
 	}
 </p>
-</div><!-- END: 9.8 - juneau-rest-client.Interceptors -->
+</div><!-- END: 9.7 - juneau-rest-client.Interceptors -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Other' id='juneau-rest-client.Other'>9.9 - Other Useful Methods</a></h3>
-<div class='topic'><!-- START: 9.9 - juneau-rest-client.Other -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-rest-client.Other' id='juneau-rest-client.Other'>9.8 - </a><span class='update'><b>8.1.4-updated</b></span></h3>
+<div class='topic'><!-- START: 9.8 - juneau-rest-client.Other -->
 <p>
-	The {@link org.apache.juneau.rest.client.RestClientBuilder#rootUrl(Object)} method can be used to specify a 
+	The {@link org.apache.juneau.rest.client2.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='bpcode w800'>
 	<jc>// Create a rest client with a root URL</jc>
 	RestClient rc = RestClient.<jsm>create</jsm>().rootUrl(<js>"http://localhost:9080/foobar"</js>).build();
-	String r = rc.doGet(<js>"/baz"</js>).getResponseAsString();  <jc>// Gets "http://localhost:9080/foobar/baz"</jc>
+	String r = rc.get(<js>"/baz"</js>).run().getBody().asString();  <jc>// Gets "http://localhost:9080/foobar/baz"</jc>
 </p>
 <p>
-	The {@link org.apache.juneau.rest.client.RestClientBuilder#set(String,Object)} method can be used to 
+	The {@link org.apache.juneau.rest.client2.RestClientBuilder#set(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.
@@ -24379,22 +24346,9 @@
 		.set(<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#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.
-</p>
-<p class='bpcode w800'>
-	<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>)
-		.retryable(180, 10000, RetryOn.<jsf>DEFAULT</jsf>)
-		.run();
+	MyPojo myPojo = rc.get(<jsf>URL</jsf>).run().getBody().as(MyPojo.<jk>class</jk>);
 </p>
-</div><!-- END: 9.9 - juneau-rest-client.Other -->
+</div><!-- END: 9.8 - juneau-rest-client.Other -->
 </div><!-- END: 9 - juneau-rest-client -->
 
 <!-- ==================================================================================================== -->
@@ -24742,8 +24696,8 @@
 	It looks simple, but there's a lot going on here.   
 </p>
 <p>
-	Remote resource interfaces are normally created through the {@link org.apache.juneau.rest.client.RestClient#getRemote(Class)} method.
-	The {@link org.apache.juneau.rest.mock2.MockRemote} will create a {@link org.apache.juneau.rest.client.RestClient} using a specialized <c>HttpClientConnectionManager</c>
+	Remote resource interfaces are normally created through the {@link org.apache.juneau.rest.client2.RestClient#getRemote(Class)} method.
+	The {@link org.apache.juneau.rest.mock2.MockRemote} will create a {@link org.apache.juneau.rest.client2.RestClient} using a specialized <c>HttpClientConnectionManager</c>
 	designed to transform client-side <c>HttpRequest</c>/<c>HttpResponse</c> objects into server-side 
 	{@link org.apache.juneau.rest.mock2.MockServletRequest}/{@link org.apache.juneau.rest.mock2.MockServletResponse} objects and then pass those to the {@link org.apache.juneau.rest.mock2.MockRest} 
 	object described in the previous section.
@@ -28539,15 +28493,79 @@
 
 <!-- ==================================================================================================== -->
 
-<h2 class='topic' onclick='toggle(this)'><a href='#Glossaries' id='Glossaries'>19 - Glossaries</a><span class='update'>8.1.3-new</span></h2>
-<div class='topic'><!-- START: 19 - Glossaries -->
+<h2 class='topic' onclick='toggle(this)'><a href='#juneau-petstore' id='juneau-petstore'>19 - juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></h2>
+<div class='topic'><!-- START: 19 - juneau-petstore -->
 <p>
+	TODO
 </p>
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.LanguageSupport' id='Glossaries.LanguageSupport'>19.1 - Language Support</a><span class='update'>8.1.3-new</span></h3>
-<div class='topic'><!-- START: 19.1 - Glossaries.LanguageSupport -->
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Installing' id='juneau-petstore.Installing'>19.1 - Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></h3>
+<div class='topic'><!-- START: 19.1 - juneau-petstore.Installing -->
+<p>
+	How to import Petstore to Eclipse or Spring Tool Suite: <br><br>
+<ol>
+<li>File --> </li>
+<li>Import --> </li>
+<li>Existing Maven Projects--></li>
+<li>Browse existing projects--> juneau-petstore</li>
+</ol>
+</p>
+</div><!-- END: 19.1 - juneau-petstore.Installing -->
+
+<!-- ==================================================================================================== -->
+
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Running' id='juneau-petstore.Running'>19.2 - Running Petstore manually</a><span class='update'><b>8.1.4-new</b></span></h3>
+<div class='topic'><!-- START: 19.2 - juneau-petstore.Running -->
+<p>
+		How to run Petstore --Java Backend-- in Eclipse or Spring Tool Suite: <br><br>
+	<ol>
+	<li>App.java --> Run as Spring Boot App </li>
+	<li>Main.java --> Run as Spring Boot App </li>
+	</ol>
+</p>
+<p>
+		How to run Petstore --React Frontend-- with npm: <br><br>
+	<ol>
+	<li>Install latest node.js </li>
+	<li>Inside folder "Pets" run command: npm install </li>
+	<li>Inside folder "Pets" run command: npm start  </li>
+	</ol>
+</p>
+</div><!-- END: 19.2 - juneau-petstore.Running -->
+
+<!-- ==================================================================================================== -->
+
+<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Building' id='juneau-petstore.Building'>19.3 - Building and Running from Command-Line (Using Dockerfiles)</a><span class='update'><b>8.1.4-new</b></span></h3>
+<div class='topic'><!-- START: 19.3 - juneau-petstore.Building -->
+<p>
+		How to build and run Petstore using Docker: <br>
+	<ol>
+	<li>Go to the folder "juneau-petstore" and run this command: 
+			<br> 
+		docker build . -t petstore && docker run -p 5000:5000 petstore</li>
+	<br>
+	<li>Go to the folder "pets" and run this command:  
+			<br>
+		docker run --rm -it -p 3000:3000 -v $(pwd):/usr/src/app pets </li>
+	
+	</ol>
+	</p>
+</div><!-- END: 19.3 - juneau-petstore.Building -->
+</div><!-- END: 19 - juneau-petstore -->
+
+<!-- ==================================================================================================== -->
+
+<h2 class='topic' onclick='toggle(this)'><a href='#Glossaries' id='Glossaries'>20 - Glossaries</a><span class='update'>8.1.3-new</span></h2>
+<div class='topic'><!-- START: 20 - Glossaries -->
+<p>
+</p>
+
+<!-- ==================================================================================================== -->
+
+<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.LanguageSupport' id='Glossaries.LanguageSupport'>20.1 - Language Support</a><span class='update'>8.1.3-new</span></h3>
+<div class='topic'><!-- START: 20.1 - Glossaries.LanguageSupport -->
 <h5 class='figure'>All serializers/parsers defined in Juneau</h5>
 <table class='styled w1000'>
 	<tr>
@@ -28694,12 +28712,12 @@
 		<td>{@doc juneau-marshall.XmlDetails.XmlSchema XML-Schema Support}</td>
 	</tr>
 </table>
-</div><!-- END: 19.1 - Glossaries.LanguageSupport -->
+</div><!-- END: 20.1 - Glossaries.LanguageSupport -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.Annotations' id='Glossaries.Annotations'>19.2 - Annotations</a><span class='update'>8.1.3-new</span></h3>
-<div class='topic'><!-- START: 19.2 - Glossaries.Annotations -->
+<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.Annotations' id='Glossaries.Annotations'>20.2 - Annotations</a><span class='update'>8.1.3-new</span></h3>
+<div class='topic'><!-- START: 20.2 - Glossaries.Annotations -->
 <h5 class='figure'>Serialization Annotations (used to modify how artifacts are marshalled)</h5>
 <table class='styled w1000'>
 	<tr>
@@ -29041,12 +29059,12 @@
 	</tr>
 </table>
 <br><br>
-</div><!-- END: 19.2 - Glossaries.Annotations -->
+</div><!-- END: 20.2 - Glossaries.Annotations -->
 
 <!-- ==================================================================================================== -->
 
-<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.ConfigurableProperties' id='Glossaries.ConfigurableProperties'>19.3 - Configurable Properties</a><span class='update'>8.1.3-new</span></h3>
-<div class='topic'><!-- START: 19.3 - Glossaries.ConfigurableProperties -->
+<h3 class='topic' onclick='toggle(this)'><a href='#Glossaries.ConfigurableProperties' id='Glossaries.ConfigurableProperties'>20.3 - Configurable Properties</a><span class='update'>8.1.3-new</span></h3>
+<div class='topic'><!-- START: 20.3 - Glossaries.ConfigurableProperties -->
 <h5 class='figure'>All properties defined in Juneau</h5>
 <table class='styled w1000'>
 	<tr>
@@ -29882,6 +29900,12 @@
 	</tr>
 	<tr>
 		<td></td>
+		<td>{@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_errorCodes RESTCLIENT_errorCodes}</td>
+		<td>Error codes predicate.</td>
+		<td style='max-width:250px;overflow:hidden'>{@link java.util.function.Predicate}&lt;{@link java.lang.Integer}&gt;</td>
+	</tr>
+	<tr>
+		<td></td>
 		<td>{@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_executorService RESTCLIENT_executorService}</td>
 		<td>Executor service.</td>
 		<td style='max-width:250px;overflow:hidden'><ul><li><c>Class&lt;{@link java.util.concurrent.ExecutorService}&gt;</c><li>{@link java.util.concurrent.ExecutorService}</ul></td>
@@ -29894,6 +29918,18 @@
 	</tr>
 	<tr>
 		<td></td>
+		<td>{@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_formData RESTCLIENT_formData}</td>
+		<td>Request form-data parameters.</td>
+		<td style='max-width:250px;overflow:hidden'><c>List&lt;{@link org.apache.http.NameValuePair}&gt;</c></td>
+	</tr>
+	<tr>
+		<td></td>
+		<td>{@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_headers RESTCLIENT_headers}</td>
+		<td>Request headers.</td>
+		<td style='max-width:250px;overflow:hidden'><c>List&lt;{@link org.apache.http.Header} | {@link org.apache.juneau.http.HttpHeader} | {@link org.apache.http.NameValuePair}&gt;</c></td>
+	</tr>
+	<tr>
+		<td></td>
 		<td>{@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_interceptors RESTCLIENT_interceptors}</td>
 		<td>Call interceptors.</td>
 		<td style='max-width:250px;overflow:hidden'><c>List&lt;Class&lt;{@link org.apache.juneau.rest.client.RestCallInterceptor}&gt;|{@link org.apache.juneau.rest.client.RestCallInterceptor}&gt;</c></td>
@@ -29906,6 +29942,12 @@
 	</tr>
 	<tr>
 		<td></td>
+		<td>{@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_leakDetection RESTCLIENT_leakDetection}</td>
+		<td>Enable leak detection.</td>
+		<td style='max-width:250px;overflow:hidden'><jk>boolean</jk></td>
+	</tr>
+	<tr>
+		<td></td>
 		<td>{@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_parser RESTCLIENT_parser}</td>
 		<td>Parser.</td>
 		<td style='max-width:250px;overflow:hidden'><ul><li><c>Class&lt;{@link org.apache.juneau.parser.Parser}&gt;</c><li>{@link org.apache.juneau.parser.Parser}</ul></td>
@@ -29924,6 +29966,12 @@
 	</tr>
 	<tr>
 		<td></td>
+		<td>{@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_query RESTCLIENT_query}</td>
+		<td>Request query parameters.</td>
+		<td style='max-width:250px;overflow:hidden'><c>List&lt;{@link org.apache.http.NameValuePair}&gt;</c></td>
+	</tr>
+	<tr>
+		<td></td>
 		<td>{@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_query RESTCLIENT_query}</td>
 		<td>Request query parameters.</td>
 		<td style='max-width:250px;overflow:hidden'><c>Map&lt;String,String&gt;</c></td>
@@ -30518,44 +30566,8 @@
 	</tr>
 </table>
 
-</div><!-- END: 19.3 - Glossaries.ConfigurableProperties -->
-</div><!-- END: 19 - Glossaries -->
-
-<!-- ==================================================================================================== -->
-
-<h2 class='topic' onclick='toggle(this)'><a href='#juneau-petstore' id='juneau-petstore'>20 - juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></h2>
-<div class='topic'><!-- START: 20 - juneau-petstore -->
-<p>
-	TODO
-</p>
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Installing' id='juneau-petstore.Installing'>20.1 - Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></h3>
-<div class='topic'><!-- START: 20.1 - juneau-petstore.Installing -->
-<p>
-	TODO
-</p>
-</div><!-- END: 20.1 - juneau-petstore.Installing -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Running' id='juneau-petstore.Running'>20.2 - Running in Eclipse</a><span class='update'><b>8.1.4-new</b></span></h3>
-<div class='topic'><!-- START: 20.2 - juneau-petstore.Running -->
-<p>
-	TODO
-</p>
-</div><!-- END: 20.2 - juneau-petstore.Running -->
-
-<!-- ==================================================================================================== -->
-
-<h3 class='topic' onclick='toggle(this)'><a href='#juneau-petstore.Building' id='juneau-petstore.Building'>20.3 - Building and Running from Command-Line</a><span class='update'><b>8.1.4-new</b></span></h3>
-<div class='topic'><!-- START: 20.3 - juneau-petstore.Building -->
-<p>
-	TODO
-</p>
-</div><!-- END: 20.3 - juneau-petstore.Building -->
-</div><!-- END: 20 - juneau-petstore -->
+</div><!-- END: 20.3 - Glossaries.ConfigurableProperties -->
+</div><!-- END: 20 - Glossaries -->
 
 <!-- ==================================================================================================== -->
 
diff --git a/juneau-doc/src/main/javadoc/resources/docs.txt b/juneau-doc/src/main/javadoc/resources/docs.txt
index 0519c19..7baa1eb 100644
--- a/juneau-doc/src/main/javadoc/resources/docs.txt
+++ b/juneau-doc/src/main/javadoc/resources/docs.txt
@@ -239,9 +239,9 @@ juneau-microservice-jetty.PredefinedResourceClasses = #juneau-microservice-jetty
 juneau-microservice-jetty.ResourceClasses = #juneau-microservice-jetty.ResourceClasses, Overview > juneau-microservice-jetty > Resource Classes
 juneau-microservice-jetty.UiCustomization = #juneau-microservice-jetty.UiCustomization, Overview > juneau-microservice-jetty > UI Customization
 juneau-petstore = #juneau-petstore, Overview > juneau-pestore
-juneau-petstore.Building = #juneau-petstore.Building, Overview > juneau-pestore > Building and Running from Command-Line
+juneau-petstore.Building = #juneau-petstore.Building, Overview > juneau-pestore > Building and Running from Command-Line (Using Dockerfiles)
 juneau-petstore.Installing = #juneau-petstore.Installing, Overview > juneau-pestore > Installing in Eclipse
-juneau-petstore.Running = #juneau-petstore.Running, Overview > juneau-pestore > Running in Eclipse
+juneau-petstore.Running = #juneau-petstore.Running, Overview > juneau-pestore > Running Petstore manually
 juneau-rest-client = #juneau-rest-client, Overview > juneau-rest-client
 juneau-rest-client.Authentication = #juneau-rest-client.Authentication, Overview > juneau-rest-client > Authentication
 juneau-rest-client.Authentication.BASIC = #juneau-rest-client.Authentication.BASIC, Overview > juneau-rest-client > Authentication > BASIC Authentication
@@ -250,9 +250,9 @@ juneau-rest-client.Authentication.OIDC = #juneau-rest-client.Authentication.OIDC
 juneau-rest-client.Debugging = #juneau-rest-client.Debugging, Overview > juneau-rest-client > Debugging
 juneau-rest-client.Interceptors = #juneau-rest-client.Interceptors, Overview > juneau-rest-client > Interceptors
 juneau-rest-client.Logging = #juneau-rest-client.Logging, Overview > juneau-rest-client > Logging
-juneau-rest-client.Other = #juneau-rest-client.Other, Overview > juneau-rest-client > Other Useful Methods
+juneau-rest-client.Other = #juneau-rest-client.Other, Overview > juneau-rest-client > 
 juneau-rest-client.PipingOutput = #juneau-rest-client.PipingOutput, Overview > juneau-rest-client > Piping Response Output
-juneau-rest-client.ResponsePatterns = #juneau-rest-client.ResponsePatterns, Overview > juneau-rest-client > Using Response Patterns
+juneau-rest-client.ResponsePatterns = #juneau-rest-client.ResponsePatterns, Overview > juneau-rest-client > 
 juneau-rest-client.RestProxies = #juneau-rest-client.RestProxies, Overview > juneau-rest-client > REST Proxies
 juneau-rest-client.RestProxies.Body = #juneau-rest-client.RestProxies.Body, Overview > juneau-rest-client > REST Proxies > @Body
 juneau-rest-client.RestProxies.DualPurposeInterfaces = #juneau-rest-client.RestProxies.DualPurposeInterfaces, Overview > juneau-rest-client > REST Proxies > Dual-purpose (end-to-end) interfaces
@@ -264,7 +264,6 @@ juneau-rest-client.RestProxies.Remote = #juneau-rest-client.RestProxies.Remote,
 juneau-rest-client.RestProxies.RemoteMethod = #juneau-rest-client.RestProxies.RemoteMethod, Overview > juneau-rest-client > REST Proxies > @RemoteMethod
 juneau-rest-client.RestProxies.Request = #juneau-rest-client.RestProxies.Request, Overview > juneau-rest-client > REST Proxies > @Request
 juneau-rest-client.RestProxies.Response = #juneau-rest-client.RestProxies.Response, Overview > juneau-rest-client > REST Proxies > @Response
-juneau-rest-client.SSL = #juneau-rest-client.SSL, Overview > juneau-rest-client > SSL Support
 juneau-rest-mock = #juneau-rest-mock, Overview > juneau-rest-mock
 juneau-rest-mock.MockRemote = #juneau-rest-mock.MockRemote, Overview > juneau-rest-mock > MockRemote
 juneau-rest-mock.MockRest = #juneau-rest-mock.MockRest, Overview > juneau-rest-mock > MockRest
@@ -368,7 +367,7 @@ juneau-rest-server.Swagger.Tags = #juneau-rest-server.Swagger.Tags, Overview > j
 juneau-rest-server.Transforms = #juneau-rest-server.Transforms, Overview > juneau-rest-server > Transforms
 juneau-rest-server.URIs = #juneau-rest-server.URIs, Overview > juneau-rest-server > URIs
 juneau-rest-server.UsingWithOsgi = #juneau-rest-server.UsingWithOsgi, Overview > juneau-rest-server > Using with OSGi
-juneau-rest-server.restRPC = #juneau-rest-server.restRPC, Overview > juneau-rest-server > restRPC
+juneau-rest-server.restRPC = #juneau-rest-server.restRPC, Overview > juneau-rest-server > REST/RPC
 my-jetty-microservice = #my-jetty-microservice, Overview > my-jetty-microservice
 my-jetty-microservice.Building = #my-jetty-microservice.Building, Overview > my-jetty-microservice > Building and Running from Command-Line
 my-jetty-microservice.Installing = #my-jetty-microservice.Installing, Overview > my-jetty-microservice > Installing in Eclipse
diff --git a/juneau-doc/src/main/javadoc/resources/fragments/toc.html b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
index 59882ea..1020149 100644
--- a/juneau-doc/src/main/javadoc/resources/fragments/toc.html
+++ b/juneau-doc/src/main/javadoc/resources/fragments/toc.html
@@ -232,7 +232,7 @@
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.RestMethod.PredefinedExceptions'>Predefined Exceptions</a></p>
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.RestMethod.PredefinedHelperBeans'>Predefined Helper Beans</a></p>
 		</ol>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.restRPC'>restRPC</a><span class='update'>8.0.0-updated</span></p>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.restRPC'>REST/RPC</a><span class='update'>8.0.0-updated</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.OpenApiSchemaPartParsing'>OpenAPI Schema Part Parsing</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.OpenApiSchemaPartSerializing'>OpenAPI Schema Part Serializing</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server.HttpPartAnnotations'>HTTP-Part Annotations</a></p>
@@ -312,7 +312,7 @@
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server-springboot.Overview'>Overview</a><span class='update'>8.0.0-new</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-server-springboot.ChildResources'>Child Resources</a><span class='update'>8.1.0-new</span></p>
 	</ol>
-	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client'>juneau-rest-client</a></p>
+	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client'>juneau-rest-client</a><span class='update'><b>8.1.4-updated</b></span></p>
 	<ol>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies'>REST Proxies</a></p>
 		<ol>
@@ -327,19 +327,18 @@
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.Response'>@Response</a></p>
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.RestProxies.DualPurposeInterfaces'>Dual-purpose (end-to-end) interfaces</a><span class='update'>8.0.0-new</span></p>
 		</ol>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.SSL'>SSL Support</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Authentication'>Authentication</a></p>
 		<ol>
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Authentication.BASIC'>BASIC Authentication</a></p>
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Authentication.FORM'>FORM-based Authentication</a></p>
 			<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Authentication.OIDC'>OIDC Authentication</a></p>
 		</ol>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.ResponsePatterns'>Using Response Patterns</a></p>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.ResponsePatterns'></a><span class='update'>todo</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.PipingOutput'>Piping Response Output</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Debugging'>Debugging</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Logging'>Logging</a></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Interceptors'>Interceptors</a></p>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Other'>Other Useful Methods</a></p>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-client.Other'></a><span class='update'><b>8.1.4-updated</b></span></p>
 	</ol>
 	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-rest-mock'>juneau-rest-mock</a><span class='update'>8.1.0-new</span></p>
 	<ol>
@@ -408,18 +407,18 @@
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-examples-rest-springboot.Building'>Building and Running from Command-Line</a><span class='update'>8.0.0-new</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-examples-rest-springboot.DeployingToHeroku'>Deploying to Heroku</a><span class='update'>8.0.0-new</span></p>
 	</ol>
+	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore'>juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></p>
+	<ol>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Installing'>Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Running'>Running Petstore manually</a><span class='update'><b>8.1.4-new</b></span></p>
+		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Building'>Building and Running from Command-Line (Using Dockerfiles)</a><span class='update'><b>8.1.4-new</b></span></p>
+	</ol>
 	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#Glossaries'>Glossaries</a><span class='update'>8.1.3-new</span></p>
 	<ol>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#Glossaries.LanguageSupport'>Language Support</a><span class='update'>8.1.3-new</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#Glossaries.Annotations'>Annotations</a><span class='update'>8.1.3-new</span></p>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#Glossaries.ConfigurableProperties'>Configurable Properties</a><span class='update'>8.1.3-new</span></p>
 	</ol>
-	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore'>juneau-pestore</a><span class='update'><b>8.1.4-new</b></span></p>
-	<ol>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Installing'>Installing in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Running'>Running in Eclipse</a><span class='update'><b>8.1.4-new</b></span></p>
-		<li><p><a class='doclink' href='{OVERVIEW_URL}#juneau-petstore.Building'>Building and Running from Command-Line</a><span class='update'><b>8.1.4-new</b></span></p>
-	</ol>
 	<li><p class='toc2'><a class='doclink' href='{OVERVIEW_URL}#Security'>Security Best-Practices</a></p>
 	<ol>
 		<li><p><a class='doclink' href='{OVERVIEW_URL}#Security.juneau-marshall'>juneau-marshall</a></p>
diff --git a/juneau-doc/src/main/javadoc/resources/juneau-code.css b/juneau-doc/src/main/javadoc/resources/juneau-code.css
index f7cf4dd..c8adc04 100644
--- a/juneau-doc/src/main/javadoc/resources/juneau-code.css
+++ b/juneau-doc/src/main/javadoc/resources/juneau-code.css
@@ -84,7 +84,9 @@ bc {
 
 /*--- Bordered code ---*/
 p.bcode,
-p.bpcode {
+p.bpcode,
+div.bcode,
+div.bpcode {
 	border: 1px solid black;
 	margin: 0px 20px;
 	border-radius: 10px;
@@ -94,23 +96,24 @@ p.bpcode {
 	box-shadow: 1px 1px 1px 0px rgba(0, 0, 0, 0.5);
 }
 
-p.bpcode {
+p.bpcode,
+div.bpcode {
 	padding-bottom: 15px;
 }
 
 /*--- Bordered code in a section of a method doc ---*/
-dd p.bcode {
+dd p.bcode, dd div.bcode {
 	margin-left:0px;
 	margin-right:20px;
 }
 
 /* Override padding bottom in javadoc comments. */
-.blockList p.bcode {
+.blockList p.bcode, .blocklist div.bcode {
 	padding-bottom: 0px !important;
 }
 
 /*--- Unbordered code ---*/
-p.code {
+p.code, div.code {
 	padding-bottom: 15px;
 	margin: -15px;
 }
diff --git a/juneau-doc/src/main/javadoc/resources/juneau-doc.css b/juneau-doc/src/main/javadoc/resources/juneau-doc.css
index 8d2cfb2..fdc1a9b 100755
--- a/juneau-doc/src/main/javadoc/resources/juneau-doc.css
+++ b/juneau-doc/src/main/javadoc/resources/juneau-doc.css
@@ -376,14 +376,25 @@ ul.seealso:before {
 ul.notes:before {
 	content: 'Notes:';
 }
-ul.seealso:before, ul.notes:before {
+div.description ul.seealso:before, 
+div.description ul.notes:before {
 	white-space: pre;
 	font-size: 1.1em;
 	font-weight: bold;
 	color: #4e4e4e;
 	margin-left: -40px;
 	padding-bottom: 20px;
-    line-height: 30px;
+	line-height: 30px;
+}
+div.details ul.seealso:before, 
+div.details ul.notes:before {
+	white-space: pre;
+	font-size: 1.1em;
+	font-weight: bold;
+	color: #4e4e4e;
+	margin-left: -40px;
+	padding-bottom: 20px;
+	line-height: 30px;
 }
 ul.seealso, ul.notes {
 	margin-top:20px;
diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/ContentComboTestBase.java b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/ContentComboTestBase.java
index 50e5bd4..d1baac2 100644
--- a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/ContentComboTestBase.java
+++ b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/ContentComboTestBase.java
@@ -26,7 +26,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.plaintext.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
@@ -95,11 +95,10 @@ public class ContentComboTestBase extends RestTestcase {
 		this.comboInput = comboInput;
 	}
 
-	@SuppressWarnings("resource")
 	@Test
 	public void doTest() throws Exception {
 		RestClient rc = getClient(comboInput.mediaType);
-		String s = rc.doGet(comboInput.url).getResponseAsString();
+		String s = rc.get(comboInput.url).run().getBody().asString();
 		assertContains(s, comboInput.expectedResults);
 	}
 }
diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
index 9ba69f6..0320fb4 100644
--- a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
+++ b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootContentTest.java
@@ -91,58 +91,49 @@ public class RootContentTest extends ContentComboTestBase {
 					"'description':'Hello World'"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 10 */
 				new ComboInput("HTML-content-octal/msgpack", "/", MediaType.MSGPACK,
-					"",
-					""
+					"95 82 A4"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 11 */
 				new ComboInput("HTML-content-text/plain", "/", MediaType.PLAIN,
-					"",
-					""
+					"Hello World"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 12 */
 				new ComboInput("HTML-content-text/uon", "/", MediaType.UON,
-					"",
-					""
+					"(name=helloWorld,description='Hello World')"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 13 */
 				new ComboInput("HTML-content-application/x-www-form-urlencoded", "/", MediaType.URLENCODING,
-					"",
-					""
+					"0=(name=helloWorld,description='Hello+World')"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 14 */
 				new ComboInput("HTML-content-text/xml", "/", MediaType.XML,
-					"",
-					""
+					"<name>helloWorld</name><description>Hello World</description>"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 15 */
 				new ComboInput("HTML-content-text/xml+rdf", "/", MediaType.RDF,
-					"",
-					""
+					"<jp:name>helloWorld</jp:name>"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 16 */
 				new ComboInput("HTML-content-text/n-triple", "/", MediaType.NTRIPLE,
-					"",
-					""
+					"\"helloWorld\"^^<"
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 17 */
 				new ComboInput("HTML-content-text/turtle", "/", MediaType.TURTLE,
-					"",
-					""
+					"jp:description \"Hello World\""
 				)
 			},
-			{ 	/* 9 */
+			{ 	/* 18 */
 				new ComboInput("HTML-content-text/n3", "/", MediaType.N3,
-					"",
-					""
+					"jp:description \"Hello World\""
 				)
 			}
 
diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
index 3d89365..a0170bc 100644
--- a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
+++ b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/RootResourcesTest.java
@@ -18,7 +18,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.dto.swagger.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.json.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.rest.helper.*;
 import org.junit.*;
 
@@ -36,18 +36,14 @@ public class RootResourcesTest extends RestTestcase {
 	public void testJson() throws Exception {
 		RestClient client = SamplesMicroservice.DEFAULT_CLIENT;
 
-		try (RestCall r = client.doGet("")) {
-			ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
-			assertEquals("helloWorld", x[0].getName());
-			assertEquals("Hello World", x[0].getDescription());
-		}
+		ResourceDescription[] x = client.get("").run().getBody().as(ResourceDescription[].class);
+		assertEquals("helloWorld", x[0].getName());
+		assertEquals("Hello World", x[0].getDescription());
 
-		try (RestCall r = jsonClient.doOptions("")) {
-			ObjectMap x2 = r.getResponse(ObjectMap.class);
-			String s = x2.getObjectMap("info").getString("description");
-			if (debug) System.err.println(s);
-			assertTrue(s, s.startsWith("Example of a router resource page"));
-		}
+		ObjectMap x2 = jsonClient.options("").run().getBody().as(ObjectMap.class);
+		String s = x2.getObjectMap("info").getString("description");
+		if (debug) System.err.println(s);
+		assertTrue(s, s.startsWith("Example of a router resource page"));
 	}
 
 	//====================================================================================================
@@ -57,18 +53,14 @@ public class RootResourcesTest extends RestTestcase {
 	public void testXml() throws Exception {
 		try (RestClient client = SamplesMicroservice.client().xml().build()) {
 
-			try (RestCall r = client.doGet("")) {
-				ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
-				assertEquals("helloWorld", x[0].getName());
-				assertEquals("Hello World", x[0].getDescription());
-			}
-
-			try (RestCall r = jsonClient.doOptions("")) {
-				ObjectMap x2 = r.getResponse(ObjectMap.class);
-				String s = x2.getObjectMap("info").getString("description");
-				if (debug) System.err.println(s);
-				assertTrue(s, s.startsWith("Example of a router resource page"));
-			}
+			ResourceDescription[] x = client.get("").run().getBody().as(ResourceDescription[].class);
+			assertEquals("helloWorld", x[0].getName());
+			assertEquals("Hello World", x[0].getDescription());
+
+			ObjectMap x2 = jsonClient.options("").run().getBody().as(ObjectMap.class);
+			String s = x2.getObjectMap("info").getString("description");
+			if (debug) System.err.println(s);
+			assertTrue(s, s.startsWith("Example of a router resource page"));
 		}
 	}
 
@@ -79,18 +71,14 @@ public class RootResourcesTest extends RestTestcase {
 	public void testHtmlStripped() throws Exception {
 		try (RestClient client = SamplesMicroservice.client().parser(HtmlParser.DEFAULT).accept("text/html+stripped").build()) {
 
-			try (RestCall r = client.doGet("")) {
-				ResourceDescription[] x = r.getResponse(ResourceDescription[].class);
-				assertEquals("helloWorld", x[0].getName());
-				assertEquals("Hello World", x[0].getDescription());
-			}
-
-			try (RestCall 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("Example of a router resource page"));
-			}
+			ResourceDescription[] x = client.get("").run().getBody().as(ResourceDescription[].class);
+			assertEquals("helloWorld", x[0].getName());
+			assertEquals("Hello World", x[0].getDescription());
+
+			ObjectMap x2 = jsonClient.options("").run().getBody().as(ObjectMap.class);
+			String s = x2.getObjectMap("info").getString("description");
+			if (debug) System.err.println(s);
+			assertTrue(s, s.startsWith("Example of a router resource page"));
 		}
 	}
 
@@ -100,11 +88,9 @@ public class RootResourcesTest extends RestTestcase {
 	@Test
 	public void testJsonSchema() throws Exception {
 		try (RestClient client = SamplesMicroservice.client().parser(JsonParser.DEFAULT).accept("text/json+schema").build()) {
-			try (RestCall r = client.doGet("")) {
-				ObjectMap m = r.getResponse(ObjectMap.class);
-				if (debug) System.err.println(m);
-				client.closeQuietly();
-			}
+			ObjectMap m = client.get("").run().getBody().as(ObjectMap.class);
+			if (debug) System.err.println(m);
+			client.closeQuietly();
 		}
 	}
 
@@ -113,10 +99,8 @@ public class RootResourcesTest extends RestTestcase {
 	//====================================================================================================
 	@Test
 	public void testOptionsPage() throws Exception {
-		try (RestCall r = jsonClient.doOptions("")) {
-			Swagger o = r.getResponse(Swagger.class);
-			if (debug) System.err.println(o);
-			assertEquals("Example of a router resource page.", o.getInfo().getDescription());
-		}
+		Swagger o = jsonClient.options("").run().getBody().as(Swagger.class);
+		if (debug) System.err.println(o);
+		assertEquals("Example of a router resource page.", o.getInfo().getDescription());
 	}
 }
diff --git a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
index ecd2eb3..e89321c 100644
--- a/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
+++ b/juneau-examples/juneau-examples-rest-jetty-ftest/src/test/java/org/apache/juneau/examples/rest/SamplesMicroservice.java
@@ -17,7 +17,7 @@ import java.util.*;
 
 import org.apache.juneau.microservice.jetty.*;
 import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.serializer.*;
 
 /**
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/microservice/testutils/TestUtils.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/microservice/testutils/TestUtils.java
index ba492f2..890028b 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/microservice/testutils/TestUtils.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/microservice/testutils/TestUtils.java
@@ -14,7 +14,7 @@ package org.apache.juneau.microservice.testutils;
 
 import static org.apache.juneau.internal.StringUtils.*;
 
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 
 import junit.framework.*;
 
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
index 8706da2..0255043 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/ConfigTest.java
@@ -20,7 +20,7 @@ import java.util.*;
 
 import org.apache.juneau.*;
 import org.apache.juneau.config.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.junit.*;
 
 public class ConfigTest extends RestTestcase {
@@ -34,23 +34,23 @@ public class ConfigTest extends RestTestcase {
 	public void test() throws Exception {
 		RestClient c = TestMicroservice.client().accept("text/json+simple").build();
 
-		Map<String,Map<String,Object>> m = c.doGet(URL).getResponse(Map.class, String.class, ObjectMap.class);
+		Map<String,Map<String,Object>> m = c.get(URL).run().getBody().as(Map.class, String.class, ObjectMap.class);
 
 		Config cf = Config.create().memStore().build().load(m);
 
 		assertObjectEquals("{int1:'1',int2:'[1,2,3]',int3:'1',int4:'1',int5:'-1',boolean1:'true',boolean2:'[true,true]',testManifestEntry:'test-value'}", cf.getSectionAsMap("Test"));
 
-		assertEquals("'1'", c.doGet(URL + "/Test%2Fint1/" + getName(String.class)).getResponseAsString());
-		assertEquals("'[1,2,3]'", c.doGet(URL + "/Test%2Fint2/" + getName(String.class)).getResponseAsString());
-		assertEquals("['1','2','3']", c.doGet(URL + "/Test%2Fint2/" + getName(String[].class)).getResponseAsString());
-		assertEquals("[1,2,3]", c.doGet(URL + "/Test%2Fint2/" + getName(int[].class)).getResponseAsString());
-		assertEquals("[1,2,3]", c.doGet(URL + "/Test%2Fint2/" + getName(Integer[].class)).getResponseAsString());
-		assertEquals("1", c.doGet(URL + "/Test%2Fint3/" + getName(Integer.class)).getResponseAsString());
-		assertEquals("1", c.doGet(URL + "/Test%2Fint4/" + getName(Integer.class)).getResponseAsString());
-		assertEquals("-1", c.doGet(URL + "/Test%2Fint5/" + getName(Integer.class)).getResponseAsString());
-		assertEquals("true", c.doGet(URL + "/Test%2Fboolean1/" + getName(Boolean.class)).getResponseAsString());
-		assertEquals("[true,true]", c.doGet(URL + "/Test%2Fboolean2/" + getName(Boolean[].class)).getResponseAsString());
-		assertEquals("'test-value'", c.doGet(URL + "/Test%2FtestManifestEntry/" + getName(String.class)).getResponseAsString());
+		assertEquals("'1'", c.get(URL + "/Test%2Fint1/" + getName(String.class)).run().getBody().asString());
+		assertEquals("'[1,2,3]'", c.get(URL + "/Test%2Fint2/" + getName(String.class)).run().getBody().asString());
+		assertEquals("['1','2','3']", c.get(URL + "/Test%2Fint2/" + getName(String[].class)).run().getBody().asString());
+		assertEquals("[1,2,3]", c.get(URL + "/Test%2Fint2/" + getName(int[].class)).run().getBody().asString());
+		assertEquals("[1,2,3]", c.get(URL + "/Test%2Fint2/" + getName(Integer[].class)).run().getBody().asString());
+		assertEquals("1", c.get(URL + "/Test%2Fint3/" + getName(Integer.class)).run().getBody().asString());
+		assertEquals("1", c.get(URL + "/Test%2Fint4/" + getName(Integer.class)).run().getBody().asString());
+		assertEquals("-1", c.get(URL + "/Test%2Fint5/" + getName(Integer.class)).run().getBody().asString());
+		assertEquals("true", c.get(URL + "/Test%2Fboolean1/" + getName(Boolean.class)).run().getBody().asString());
+		assertEquals("[true,true]", c.get(URL + "/Test%2Fboolean2/" + getName(Boolean[].class)).run().getBody().asString());
+		assertEquals("'test-value'", c.get(URL + "/Test%2FtestManifestEntry/" + getName(String.class)).run().getBody().asString());
 
 		cf.close();
 		c.closeQuietly();
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java
index ed7cb83..f3c5131 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/MockRestTest.java
@@ -19,7 +19,7 @@ import org.apache.juneau.http.annotation.Body;
 import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 import org.junit.runners.*;
@@ -47,13 +47,13 @@ public class MockRestTest {
 	@Test
 	public void a01() throws Exception {
 		RestClient rc = MockRestClient.build(A.class, null);
-		assertEquals("OK", rc.doPut("/a01", "OK").getResponseAsString());
+		assertEquals("OK", rc.put("/a01", "OK").run().getBody().asString());
 	}
 
 	@Test
 	public void a02() throws Exception {
 		RestClient rc = MockRestClient.build(A.class, Json.DEFAULT);
-		assertEquals("OK", rc.doPut("/a02", "OK").getResponse(String.class));
+		assertEquals("OK", rc.put("/a02", "OK").run().getBody().as(String.class));
 	}
 }
 
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/RestTestcase.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
index ee1faa2..8a230be 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/RestTestcase.java
@@ -16,7 +16,7 @@ import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.serializer.*;
 import org.junit.*;
 
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
index 8c77e5f..d678578 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/TestMicroservice.java
@@ -14,20 +14,16 @@ package org.apache.juneau.rest.test;
 
 import java.io.*;
 import java.net.*;
-import java.security.*;
 import java.util.*;
 
-import javax.net.ssl.*;
-
 import org.apache.http.*;
 import org.apache.http.client.*;
-import org.apache.http.conn.ssl.*;
 import org.apache.http.impl.client.*;
 import org.apache.http.protocol.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.microservice.jetty.*;
 import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.serializer.*;
 
 /**
@@ -152,17 +148,9 @@ public class TestMicroservice {
 		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();
+			return HttpClients.custom().setRedirectStrategy(new LaxRedirectStrategy()).build();
 		} catch (Exception e) {
 			throw new RuntimeException(e);
 		}
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/CallbackStringsTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/CallbackStringsTest.java
index 24c02ba..c495bd6 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/CallbackStringsTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/CallbackStringsTest.java
@@ -18,9 +18,9 @@ import static org.junit.Assert.*;
 import java.util.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.RestRequest;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 import org.junit.runners.*;
@@ -56,22 +56,22 @@ public class CallbackStringsTest {
 	public void a01() throws Exception {
 		String r;
 
-		r = a.doCallback("GET /testCallback").getResponseAsString();
+		r = a.callback("GET /testCallback").run().getBody().asString();
 		assertEquals("{method:'GET',headers:{},content:''}", r);
 
-		r = a.doCallback("GET /testCallback some sample content").getResponseAsString();
+		r = a.callback("GET /testCallback some sample content").run().getBody().asString();
 		assertEquals("{method:'GET',headers:{},content:'some sample content'}", r);
 
-		r = a.doCallback("GET {Foo-X:123,Foo-Y:'abc'} /testCallback").getResponseAsString();
+		r = a.callback("GET {Foo-X:123,Foo-Y:'abc'} /testCallback").run().getBody().asString();
 		assertEquals("{method:'GET',headers:{'Foo-X':'123','Foo-Y':'abc'},content:''}", r);
 
-		r = a.doCallback("GET  { Foo-X : 123, Foo-Y : 'abc' } /testCallback").getResponseAsString();
+		r = a.callback("GET  { Foo-X : 123, Foo-Y : 'abc' } /testCallback").run().getBody().asString();
 		assertEquals("{method:'GET',headers:{'Foo-X':'123','Foo-Y':'abc'},content:''}", r);
 
-		r = a.doCallback("GET {Foo-X:123,Foo-Y:'abc'} /testCallback   some sample content  ").getResponseAsString();
+		r = a.callback("GET {Foo-X:123,Foo-Y:'abc'} /testCallback   some sample content  ").run().getBody().asString();
 		assertEquals("{method:'GET',headers:{'Foo-X':'123','Foo-Y':'abc'},content:'some sample content'}", r);
 
-		r = a.doCallback("PUT {Foo-X:123,Foo-Y:'abc'} /testCallback   some sample content  ").getResponseAsString();
+		r = a.callback("PUT {Foo-X:123,Foo-Y:'abc'} /testCallback   some sample content  ").run().getBody().asString();
 		assertEquals("{method:'PUT',headers:{'Foo-X':'123','Foo-Y':'abc'},content:'some sample content'}", r);
 	}
 }
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ClientFuturesTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ClientFuturesTest.java
index f64d12c..fb2044e 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ClientFuturesTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ClientFuturesTest.java
@@ -18,9 +18,10 @@ import static org.junit.Assert.*;
 import java.util.concurrent.*;
 
 import org.apache.juneau.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.RestRequest;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
+import org.apache.juneau.rest.client2.RestResponse;
 import org.apache.juneau.rest.mock2.*;
 import org.junit.*;
 import org.junit.runners.*;
@@ -43,13 +44,15 @@ public class ClientFuturesTest {
 
 	@Test
 	public void a01() throws Exception {
-		Future<Integer> f = a.doGet("").runFuture();
-		assertEquals(200, f.get().intValue());
+		Future<RestResponse> f = a.get("").runFuture();
+		assertEquals(200, f.get().getStatusCode());
 
-		Future<ObjectMap> f2 = a.doGet("").getResponseFuture(ObjectMap.class);
-		assertObjectEquals("{foo:'bar'}", f2.get());
+		Future<RestResponse> f2 = a.get("").runFuture();
+		Future<ObjectMap> m = f2.get().getBody().asFuture(ObjectMap.class);
+		assertObjectEquals("{foo:'bar'}", m.get());
 
-		Future<String> f3 = a.doGet("").getResponseAsStringFuture();
-		assertObjectEquals("'{foo:\\'bar\\'}'", f3.get());
+		Future<RestResponse> f3 = a.get("").runFuture();
+		Future<String> s = f3.get().getBody().asStringFuture();
+		assertObjectEquals("'{foo:\\'bar\\'}'", s.get());
 	}
 }
\ No newline at end of file
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/FormDataTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/FormDataTest.java
index 89e2b38..bb2787e 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/FormDataTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/FormDataTest.java
@@ -19,9 +19,10 @@ import java.io.*;
 import java.util.*;
 
 import org.apache.juneau.marshall.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.RestRequest;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.rest.test.*;
 import org.apache.juneau.utils.*;
@@ -46,17 +47,17 @@ public class FormDataTest extends RestTestcase {
 
 	@Test
 	public void a01_formDataMethod() throws Exception {
-		String r = a.doPost("")
+		String r = a.post("")
 			.formData("foo", 123)
 			.formData("bar", "baz")
-			.getResponseAsString();
+			.run()
+			.getBody().asString();
 		assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[foo=123&bar=baz]", r);
 	}
 
 	@Test
 	public void a02_nameValuePairs() throws Exception {
-		String r = a.doPost("", new NameValuePairs().append("foo",123).append("bar","baz"))
-			.getResponseAsString();
+		String r = a.post("", new NameValuePairs().append("foo",123).append("bar","baz")).run().getBody().asString();
 		assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[foo=123&bar=baz]", r);
 	}
 
@@ -72,11 +73,11 @@ public class FormDataTest extends RestTestcase {
 				.append("(foo)", "(foo)")
 				.append("@(foo)", "@(foo)");
 
-			r = c.doPost("", m).getResponseAsString();
+			r = c.post("", m).run().getBody().asString();
 			assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[foo=foo&'foo'='foo'&(foo)=(foo)&@(foo)=@(foo)]", r);
 
 			List<String> l = new AList<String>().appendAll("foo", "'foo'", "(foo)", "@(foo)");
-			r = c.doPost("", l).getResponseAsString();
+			r = c.post("", l).run().getBody().asString();
 			assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[0=foo&1='foo'&2=(foo)&3=@(foo)]", r);
 
 			NameValuePairs nvp = new NameValuePairs()
@@ -84,15 +85,16 @@ public class FormDataTest extends RestTestcase {
 				.append("'foo'", "'foo'")
 				.append("(foo)", "(foo)")
 				.append("@(foo)", "@(foo)");
-			r = c.doPost("", nvp).getResponseAsString();
+			r = c.post("", nvp).run().getBody().asString();
 			assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[foo=foo&%27foo%27=%27foo%27&%28foo%29=%28foo%29&%40%28foo%29=%40%28foo%29]", r);
 
-			r = c.doPost("")
+			r = c.post("")
 				.formData("foo", "foo")
 				.formData("'foo'", "'foo'")
 				.formData("(foo)", "(foo)")
 				.formData("@(foo)", "@(foo)")
-				.getResponseAsString();
+				.run()
+				.getBody().asString();
 			assertEquals("Content-Type=[application/x-www-form-urlencoded], contents=[foo=foo&%27foo%27=%27foo%27&%28foo%29=%28foo%29&%40%28foo%29=%40%28foo%29]", r);
 		} finally {
 			c.close();
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RequestBeanProxyTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RequestBeanProxyTest.java
index d65c071..03857b1 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RequestBeanProxyTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RequestBeanProxyTest.java
@@ -26,9 +26,9 @@ import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.http.annotation.Query;
 import org.apache.juneau.httppart.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.RestRequest;
 import org.apache.juneau.rest.annotation.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.serializer.*;
@@ -199,12 +199,12 @@ public class RequestBeanProxyTest {
 	@Test
 	public void a03b_query_nameValuePairs_on() throws Exception {
 		String r = a03b.normal(new A03_Bean());
-		assertEquals("{a1:'v1',a2:'\\'123\\'',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'\\'123\\'',c4:''}", r);
+		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
 	}
 	@Test
 	public void a03c_query_nameValuePairs_x() throws Exception {
 		String r = a03b.serialized(new A03_Bean());
-		assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
+		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
 	}
 
 	//=================================================================================================================
@@ -804,12 +804,12 @@ public class RequestBeanProxyTest {
 	@Test
 	public void e03b_header_nameValuePairs_uon() throws Exception {
 		String r = e03b.normal(new E03_Bean());
-		assertEquals("{a1:'v1',a2:'\\'123\\'',a4:'',b1:'\\'true\\'',b2:'\\'123\\'',b3:'\\'null\\'',c1:'v1',c2:'\\'123\\'',c4:''}", r);
+		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
 	}
 	@Test
 	public void e03c_header_nameValuePairs_x() throws Exception {
 		String r = e03b.serialized(new E03_Bean());
-		assertEquals("{a1:'xv1x',a2:'x123x',a4:'xx',b1:'xtruex',b2:'x123x',b3:'xnullx',c1:'xv1x',c2:'x123x',c4:'xx'}", r);
+		assertEquals("{a1:'v1',a2:'123',a4:'',b1:'true',b2:'123',b3:'null',c1:'v1',c2:'123',c4:''}", r);
 	}
 
 	//=================================================================================================================
@@ -1005,7 +1005,7 @@ public class RequestBeanProxyTest {
 	@Test
 	public void g02c_path_maps_x() throws Exception {
 		String r = g02b.serialized(new G02_Bean());
-		assertEquals("echoPath/xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
+		assertEquals("echoPath/xv1x/x123x/null/xx/xtruex/x123x/xnullx/xv1x/x123x/null/xx", r);
 	}
 
 	//=================================================================================================================
@@ -1052,12 +1052,12 @@ public class RequestBeanProxyTest {
 	@Test
 	public void g03b_path_nameValuePairs_uon() throws Exception {
 		String r = g03b.normal(new G03_Bean());
-		assertEquals("echoPath/v1/'123'/null//'true'/'123'/'null'/v1/'123'/null/", r);
+		assertEquals("echoPath/v1/123/null//true/123/null/v1/123/null/", r);
 	}
 	@Test
 	public void g03c_path_nameValuePairs_x() throws Exception {
 		String r = g03b.serialized(new G03_Bean());
-		assertEquals("echoPath/xv1x/x123x/NULL/xx/xtruex/x123x/xnullx/xv1x/x123x/NULL/xx", r);
+		assertEquals("echoPath/v1/123/null//true/123/null/v1/123/null/", r);
 	}
 
 	//=================================================================================================================
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RestClientTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RestClientTest.java
index 795d7c5..5bd68ff 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RestClientTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/RestClientTest.java
@@ -15,12 +15,12 @@ package org.apache.juneau.rest.test.client;
 import static org.apache.juneau.rest.testutils.TestUtils.*;
 import static org.junit.Assert.*;
 
-import java.util.*;
 import java.util.regex.*;
 
 import org.apache.http.entity.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.*;
 import org.apache.juneau.rest.test.*;
+import org.apache.juneau.utils.*;
 import org.junit.*;
 
 public class RestClientTest extends RestTestcase {
@@ -33,19 +33,18 @@ public class RestClientTest extends RestTestcase {
 	@Test
 	public void testSuccessPattern() throws Exception {
 		RestClient c = TestMicroservice.DEFAULT_CLIENT;
-		String r;
-		int rc;
 
-		r = c.doPost(URL, new StringEntity("xxxSUCCESSxxx")).successPattern("SUCCESS").getResponseAsString();
-		assertEquals("xxxSUCCESSxxx", r);
-		rc = c.doPost(URL, new StringEntity("xxxSUCCESSxxx")).successPattern("SUCCESS").run();
-		assertEquals(200, rc);
+		Mutable<Integer> rc = new Mutable<>();
+		Mutable<String> r = new Mutable<>();
+		c.post(URL, new StringEntity("xxxSUCCESSxxx")).run().getStatusCode(rc).getBody().cache().assertValueContains("SUCCESS").getBody().asString(r);
+		assertEquals("xxxSUCCESSxxx", r.get());
+		assertEquals(200, rc.get().intValue());
 
 		try {
-			r = c.doPost(URL, new StringEntity("xxxFAILURExxx")).successPattern("SUCCESS").getResponseAsString();
+			c.post(URL, new StringEntity("xxxFAILURExxx")).run().getBody().assertValueContains("SUCCESS");
 			fail();
 		} catch (RestCallException e) {
-			assertEquals("Success pattern not detected.", e.getLocalizedMessage());
+			assertTrue(e.getLocalizedMessage().contains("Response did not have the expected substring for body."));
 		}
 	}
 
@@ -55,26 +54,18 @@ public class RestClientTest extends RestTestcase {
 	@Test
 	public void testFailurePattern() throws Exception {
 		RestClient c = TestMicroservice.DEFAULT_CLIENT;
-		String r;
-		int rc;
 
-		r = c.doPost(URL, new StringEntity("xxxSUCCESSxxx")).failurePattern("FAILURE").getResponseAsString();
-		assertEquals("xxxSUCCESSxxx", r);
-		rc = c.doPost(URL, new StringEntity("xxxSUCCESSxxx")).failurePattern("FAILURE").run();
-		assertEquals(200, rc);
-
-		try {
-			r = c.doPost(URL, new StringEntity("xxxFAILURExxx")).failurePattern("FAILURE").getResponseAsString();
-			fail();
-		} catch (RestCallException e) {
-			assertEquals("Failure pattern detected.", e.getLocalizedMessage());
-		}
+		Mutable<Integer> rc = new Mutable<>();
+		Mutable<String> r = new Mutable<>();
+		c.post(URL, new StringEntity("xxxSUCCESSxxx")).run().getStatusCode(rc).getBody().cache().assertValue(x -> ! x.contains("FAILURE")).getBody().asString(r);
+		assertEquals("xxxSUCCESSxxx", r.get());
+		assertEquals(200, rc.get().intValue());
 
 		try {
-			r = c.doPost(URL, new StringEntity("xxxERRORxxx")).failurePattern("FAILURE|ERROR").getResponseAsString();
+			c.post(URL, new StringEntity("xxxFAILURExxx")).run().getBody().assertValue(x -> ! x.contains("FAILURE"));
 			fail();
 		} catch (RestCallException e) {
-			assertEquals("Failure pattern detected.", e.getLocalizedMessage());
+			assertTrue(e.getLocalizedMessage().contains("Response did not have the expected value for body."));
 		}
 	}
 
@@ -84,25 +75,16 @@ public class RestClientTest extends RestTestcase {
 	@Test
 	public void testCaptureResponse() throws Exception {
 		RestClient c = TestMicroservice.DEFAULT_CLIENT;
-		RestCall rc = c.doPost(URL, new StringEntity("xxx")).captureResponse();
+		RestResponse r = c.post(URL, new StringEntity("xxx")).run().getBody().cache().toResponse();
 
-		try {
-			rc.getCapturedResponse();
-			fail();
-		} catch (IllegalStateException e) {
-			assertEquals("This method cannot be called until the response has been consumed.", e.getLocalizedMessage());
-		}
-		rc.run();
-		assertEquals("xxx", rc.getCapturedResponse());
-		assertEquals("xxx", rc.getCapturedResponse());
+		assertEquals("xxx", r.getBody().asString());
+		assertEquals("xxx", r.getBody().asString());
 
-		rc = c.doPost(URL, new StringEntity("xxx")).captureResponse();
-		assertEquals("xxx", rc.getResponseAsString());
-		assertEquals("xxx", rc.getCapturedResponse());
-		assertEquals("xxx", rc.getCapturedResponse());
+		r = c.post(URL, new StringEntity("xxx")).run();
+		assertEquals("xxx", r.getBody().asString());
 
 		try {
-			rc.getResponseAsString();
+			r.getBody().asString();
 			fail();
 		} catch (IllegalStateException e) {
 			assertEquals("Method cannot be called.  Response has already been consumed.", e.getLocalizedMessage());
@@ -117,75 +99,27 @@ public class RestClientTest extends RestTestcase {
 		RestClient c = TestMicroservice.DEFAULT_CLIENT;
 		String r;
 
-		final List<String> l = new ArrayList<>();
-		ResponsePattern p = new ResponsePattern("x=(\\d+),y=(\\S+)") {
-			@Override
-			public void onMatch(RestCall restCall, Matcher m) throws RestCallException {
-				l.add(m.group(1)+'/'+m.group(2));
-			}
-			@Override
-			public void onNoMatch(RestCall restCall) throws RestCallException {
-				throw new RestCallException("Pattern not found!");
-			}
-		};
-
-		r = c.doPost(URL, new StringEntity("x=1,y=2")).responsePattern(p).getResponseAsString();
+		Mutable<Matcher> m = Mutable.create();
+		r = c.post(URL, new StringEntity("x=1,y=2")).run().getBody().cache().asMatcher(m, "x=(\\d+),y=(\\S+)").getBody().asString();
 		assertEquals("x=1,y=2", r);
-		assertObjectEquals("['1/2']", l);
+		assertTrue(m.get().matches());
+		assertObjectEquals("['x=1,y=2','1','2']", m.get().toMatchResult());
 
-		l.clear();
-
-		r = c.doPost(URL, new StringEntity("x=1,y=2\nx=3,y=4")).responsePattern(p).getResponseAsString();
+		r = c.post(URL, new StringEntity("x=1,y=2\nx=3,y=4")).run().getBody().cache().asMatcher(m, "x=(\\d+),y=(\\S+)").getBody().asString();
 		assertEquals("x=1,y=2\nx=3,y=4", r);
-		assertObjectEquals("['1/2','3/4']", l);
-
-		try {
-			c.doPost(URL, new StringEntity("x=1")).responsePattern(p).run();
-			fail();
-		} catch (RestCallException e) {
-			assertEquals("Pattern not found!", e.getLocalizedMessage());
-			assertEquals(0, e.getResponseCode());
-		}
-
-		// Two patterns!
-		ResponsePattern p1 = new ResponsePattern("x=(\\d+)") {
-			@Override
-			public void onMatch(RestCall restCall, Matcher m) throws RestCallException {
-				l.add("x="+m.group(1));
-			}
-			@Override
-			public void onNoMatch(RestCall restCall) throws RestCallException {
-				throw new RestCallException("Pattern x not found!");
-			}
-		};
-		ResponsePattern p2 = new ResponsePattern("y=(\\S+)") {
-			@Override
-			public void onMatch(RestCall restCall, Matcher m) throws RestCallException {
-				l.add("y="+m.group(1));
-			}
-			@Override
-			public void onNoMatch(RestCall restCall) throws RestCallException {
-				throw new RestCallException("Pattern y not found!");
-			}
-		};
-
-		l.clear();
-		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")).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")).responsePattern(p1).responsePattern(p2).getResponseAsString();
-		} catch (RestCallException e) {
-			assertEquals("Pattern x not found!", e.getLocalizedMessage());
-			assertEquals(0, e.getResponseCode());
-		}
+		assertTrue(m.get().find());
+		assertObjectEquals("['x=1,y=2','1','2']", m.get().toMatchResult());
+		assertTrue(m.get().find());
+		assertObjectEquals("['x=3,y=4','3','4']", m.get().toMatchResult());
+
+		c.post(URL, new StringEntity("x=1")).run().getBody().asMatcher("x=(\\d+),y=(\\S+)");
+		assertFalse(m.get().find());
+
+		Mutable<Matcher> m2 = Mutable.create();
+		c.post(URL, new StringEntity("x=1,y=2")).run().getBody().cache().asMatcher(m, "x=(\\d+),y=(\\S+)").getBody().asMatcher(m2, "x=(\\d+),y=(\\S+)");
+		assertTrue(m.get().matches());
+		assertTrue(m2.get().matches());
+		assertObjectEquals("['x=1,y=2','1','2']", m.get().toMatchResult());
+		assertObjectEquals("['x=1,y=2','1','2']", m2.get().toMatchResult());
 	}
 }
diff --git a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
index dce4c29..f8963b4 100644
--- a/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
+++ b/juneau-microservice/juneau-microservice-ftest/src/test/java/org/apache/juneau/rest/test/client/ThirdPartyProxyTest.java
@@ -28,7 +28,7 @@ import org.apache.juneau.jena.*;
 import org.apache.juneau.json.*;
 import org.apache.juneau.msgpack.*;
 import org.apache.juneau.parser.*;
-import org.apache.juneau.rest.client.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.test.*;
 import org.apache.juneau.rest.test.client.ThirdPartyProxyTest.ThirdPartyProxy.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BodyAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BodyAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
index afae550..d5ad18b 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/BodyAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/BodyAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 
@@ -26,6 +26,7 @@ import org.apache.juneau.json.*;
 import org.apache.juneau.marshall.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.utils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/EndToEndInterfaceTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/EndToEndInterfaceTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
index 6a0d510..f434331 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/EndToEndInterfaceTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/EndToEndInterfaceTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.apache.juneau.http.HttpMethodName.*;
 import static org.junit.Assert.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/FormDataAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/FormDataAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/FormDataAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/FormDataAnnotationTest.java
index c2daa81..90339da 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/FormDataAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/FormDataAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 import static org.apache.juneau.testutils.TestUtils.*;
@@ -26,6 +26,7 @@ import org.apache.juneau.http.annotation.FormData;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.rest.testutils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/HeaderAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/HeaderAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/HeaderAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/HeaderAnnotationTest.java
index bbbbcf8..7cc71da 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/HeaderAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/HeaderAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.apache.juneau.testutils.TestUtils.*;
 import static org.junit.Assert.*;
@@ -24,6 +24,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.Header;
 import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.rest.testutils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/PathAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/PathAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/PathAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/PathAnnotationTest.java
index 11eb3d2..435a345 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/PathAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/PathAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.apache.juneau.testutils.TestUtils.*;
 import static org.junit.Assert.*;
@@ -24,6 +24,7 @@ import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.Path;
 import org.apache.juneau.jsonschema.annotation.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.rest.testutils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/QueryAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/QueryAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
index e02c4d3..088b2df 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/QueryAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.apache.juneau.testutils.TestUtils.*;
 import static org.junit.Assert.*;
@@ -24,8 +24,9 @@ import java.util.concurrent.atomic.*;
 import org.apache.juneau.*;
 import org.apache.juneau.http.annotation.Query;
 import org.apache.juneau.jsonschema.annotation.*;
-import org.apache.juneau.rest.*;
 import org.apache.juneau.rest.annotation.*;
+import org.apache.juneau.rest.RestRequest;
+import org.apache.juneau.rest.client2.ext.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
 import org.apache.juneau.rest.testutils.*;
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteMethodAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteMethodAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
index 66522f4..8b590c5 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteMethodAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteMethodAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteResourceAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
similarity index 99%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteResourceAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
index 21c1c92..1f1e266 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RemoteResourceAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RemoteResourceAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RequestAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RequestAnnotationTest.java
similarity index 98%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RequestAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RequestAnnotationTest.java
index 7ae06ec..dc49c1b 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/RequestAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RequestAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 
@@ -77,7 +77,7 @@ public class RequestAnnotationTest {
 		@RemoteMethod(path="/{x}") String post(ARequest req);
 	}
 
-	private static AR ar = MockRemote.build(AR.class, A.class, null);
+	private static AR ar = MockRemote.create(AR.class, A.class, null).build();
 
 	@Test
 	public void a01_basic() throws Exception {
diff --git a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/ResponseAnnotationTest.java b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/ResponseAnnotationTest.java
similarity index 97%
rename from juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/ResponseAnnotationTest.java
rename to juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/ResponseAnnotationTest.java
index 28d8767..04d4992 100644
--- a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client/ResponseAnnotationTest.java
+++ b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/ResponseAnnotationTest.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static org.junit.Assert.*;
 
@@ -19,7 +19,7 @@ import java.io.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.http.annotation.Response;
 import org.apache.juneau.internal.*;
-import org.apache.juneau.rest.*;
+import org.apache.juneau.rest.RestResponse;
 import org.apache.juneau.rest.annotation.*;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.rest.mock2.*;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
index 41c026a..29c79b1 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/AllowAllRedirects.java
@@ -22,7 +22,10 @@ import org.apache.http.impl.client.*;
  * 		This class is similar to <c>org.apache.http.impl.client.LaxRedirectStrategy</c>
  * 		in Apache HttpClient 4.2, but also allows for redirects on <c>PUTs</c> and <c>DELETEs</c>.
  * </ul>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.ext.AllRedirectsStrategy}
  */
+@Deprecated
 public class AllowAllRedirects extends DefaultRedirectStrategy {
 
 	@Override /* DefaultRedirectStrategy */
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java
index a040588..3c86399 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/DateHeader.java
@@ -12,10 +12,11 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.rest.client;
 
-import java.util.*;
+import java.util.Date;
 
 import org.apache.http.client.utils.*;
-import org.apache.http.message.*;
+import org.apache.http.message.BasicHeader;
+import org.apache.juneau.http.*;
 
 /**
  * Convenience class for setting date headers in RFC2616 format.
@@ -25,7 +26,10 @@ import org.apache.http.message.*;
  * <p class='bcode w800'>
  * 	Header h = <jk>new</jk> Header(name, DateUtils.<jsm>formatDate</jsm>(value));
  * </p>
+ *
+ * @deprecated Use {@link HttpHeader HttpHeaders}
  */
+@Deprecated
 public final class DateHeader extends BasicHeader {
 
 	private static final long serialVersionUID = 1L;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/HttpMethod.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/HttpMethod.java
index 9dc0d67..659954c 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/HttpMethod.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/HttpMethod.java
@@ -14,7 +14,10 @@ package org.apache.juneau.rest.client;
 
 /**
  * Enumeration of HTTP methods.
+ *
+ * @deprecated Use {@link org.apache.juneau.http.HttpMethod}
  */
+@Deprecated
 public enum HttpMethod {
 
 	/** HTTP GET */
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/NameValuePairs.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/NameValuePairs.java
index bd77fbd..d649791 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/NameValuePairs.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/NameValuePairs.java
@@ -38,7 +38,10 @@ import org.apache.juneau.urlencoding.*;
  * 		.append(<js>"j_password"</js>, pw);
  * 	restClient.doPost(url, params).run();
  * </p>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.ext.NameValuePairs}
  */
+@Deprecated
 public final class NameValuePairs extends LinkedList<NameValuePair> {
 
 	private static final long serialVersionUID = 1L;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
index 84284ba..ca4d511 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponsePattern.java
@@ -72,7 +72,10 @@ import java.util.regex.*;
  * 	<li>
  * 		{@link ResponsePattern} objects are reusable and thread-safe.
  * </ul>
+ *
+ * @deprecated Use new methods provided on {@link org.apache.juneau.rest.client2.RestResponse} class.
  */
+@Deprecated
 public abstract class ResponsePattern {
 
 	private Pattern pattern;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
index 52b2e29..358fe1f 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCall.java
@@ -74,7 +74,10 @@ import org.apache.juneau.utils.*;
  * <ul class='seealso'>
  * 	<li class='link'>{@doc juneau-rest-client}
  * </ul>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestRequest} class.
  */
+@Deprecated
 @SuppressWarnings({ "unchecked" })
 public final class RestCall extends BeanSession implements Closeable {
 
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
index 3fe7203..12f4ac8 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
@@ -29,7 +29,10 @@ import org.apache.juneau.reflect.*;
 
 /**
  * Exception representing a <c>400+</c> HTTP response code against a remote resource.
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestCallException} class.
  */
+@Deprecated
 public final class RestCallException extends IOException {
 
 	private static final long serialVersionUID = 1L;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java
index 15cf54d..83241ab 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java
@@ -34,7 +34,10 @@ import org.apache.http.client.methods.*;
  * 	<li class='jf'>{@link RestClientBuilder#callHandler(Class)}
  * 	<li class='jf'>{@link RestClientBuilder#callHandler(RestCallHandler)}
  * </ul>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestCallHandler} class.
  */
+@Deprecated
 public interface RestCallHandler {
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java
index 3023a0d..3737ea1 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java
@@ -20,7 +20,10 @@ import org.apache.http.*;
  *
  * <p>
  * Useful if you want to prevent {@link RestCallException RestCallExceptions} from being thrown on error conditions.
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestCallInterceptor} class.
  */
+@Deprecated
 public abstract class RestCallInterceptor {
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
index c20065d..620c129 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallLogger.java
@@ -31,7 +31,10 @@ import org.apache.http.util.*;
  * <p>
  * Use the {@link RestClientBuilder#logTo(Level, Logger)} and {@link RestCall#logTo(Level, Logger)} methods to create
  * instances of this class.
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.logging.RestCallLogger}
  */
+@Deprecated
 public class RestCallLogger extends RestCallInterceptor {
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index 947d772..c523d24 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -69,9 +69,12 @@ import org.apache.juneau.utils.*;
  * <ul class='seealso'>
  * 	<li class='link'>{@doc juneau-rest-client}
  * </ul>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestClient}
  */
 @SuppressWarnings("rawtypes")
 @ConfigurableContext(nocache=true)
+@Deprecated
 public class RestClient extends BeanContext implements Closeable {
 
 	//-------------------------------------------------------------------------------------------------------------------
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
index 87529e0..bbb614c 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClientBuilder.java
@@ -81,7 +81,10 @@ import org.apache.juneau.xml.*;
  * <ul class='seealso'>
  * 	<li class='link'>{@doc juneau-rest-client}
  * </ul>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestClientBuilder}
  */
+@Deprecated
 public class RestClientBuilder extends BeanContextBuilder {
 
 	private HttpClientBuilder httpClientBuilder;
@@ -2586,12 +2589,15 @@ public class RestClientBuilder extends BeanContextBuilder {
 	@Override /* BeanContextBuilder */
 	public RestClientBuilder debug() {
 		super.debug();
+		interceptors(RestCallLogger.DEFAULT);
 		return this;
 	}
 
 	@Override /* BeanContextBuilder */
 	public RestClientBuilder debug(boolean value) {
 		super.debug(value);
+		if (value)
+			interceptors(RestCallLogger.DEFAULT);
 		return this;
 	}
 
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
index e14da15..97f23c6 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequestEntity.java
@@ -25,7 +25,10 @@ import org.apache.juneau.utils.*;
 
 /**
  * HttpEntity for serializing POJOs as the body of HTTP requests.
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.ext.SerializedHttpEntity}.
  */
+@Deprecated
 public final class RestRequestEntity extends BasicHttpEntity {
 	final Object output;
 	final Serializer serializer;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
index 7e457ed..b72fe50 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RetryOn.java
@@ -13,6 +13,7 @@
 package org.apache.juneau.rest.client;
 
 import org.apache.http.*;
+import org.apache.http.client.*;
 
 /**
  * Used to determine whether a request should be retried based on the HTTP response code.
@@ -20,7 +21,10 @@ import org.apache.http.*;
  * <p>
  * Subclasses should override either the {@link #onCode(int)} method (if you only care about the HTTP status code)
  * or {@link #onResponse(HttpResponse)} (if you want full access to the HTTP response object.
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.RestClientBuilder#retryHandler(HttpRequestRetryHandler)}.
  */
+@Deprecated
 public abstract class RetryOn {
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
index fd1573f..84a0fc9 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SerializedNameValuePair.java
@@ -30,7 +30,10 @@ import org.apache.juneau.urlencoding.*;
  * 		.append(<jk>new</jk> BasicNameValuePair(<js>"someOtherParam"</js>, <js>"foobar"</js>));
  * 	request.setEntity(<jk>new</jk> UrlEncodedFormEntity(params));
  * </p>
+ *
+ * @deprecated Use {@link org.apache.juneau.rest.client2.ext.SerializedNameValuePair}.
  */
+@Deprecated
 public final class SerializedNameValuePair implements NameValuePair {
 	private String name;
 	private Object value;
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SimpleX509TrustManager.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SimpleX509TrustManager.java
index c804651..2521ac8 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SimpleX509TrustManager.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/SimpleX509TrustManager.java
@@ -19,7 +19,10 @@ import javax.net.ssl.*;
 
 /**
  * A trust manager that optionally allows for self-signed certificates.
+ *
+ * @deprecated No replacement.
  */
+@Deprecated
 public final class SimpleX509TrustManager implements X509TrustManager {
 
 	private X509TrustManager baseTrustManager;  // The JRE-provided trust manager used to validate certificates presented by a server.
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
similarity index 84%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
copy to juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
index 3fe7203..6cff971 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallException.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallException.java
@@ -10,7 +10,7 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import static java.lang.String.*;
 import static org.apache.juneau.internal.StringUtils.*;
@@ -28,7 +28,7 @@ import org.apache.http.util.*;
 import org.apache.juneau.reflect.*;
 
 /**
- * Exception representing a <c>400+</c> HTTP response code against a remote resource.
+ * Exception representing a <c>400+</c> HTTP response code against a remote resource or other exception.
  */
 public final class RestCallException extends IOException {
 
@@ -37,12 +37,24 @@ public final class RestCallException extends IOException {
 	private int responseCode;
 	private String response, responseStatusMessage;
 	HttpResponseException e;
-	private HttpResponse httpResponse;
+	private RestResponse restResponse;
 
 	@SuppressWarnings("unused")
 	private String serverExceptionName, serverExceptionMessage, serverExceptionTrace;
 
 	/**
+	 * Converts the specified exception to a {@link RestCallException} by either casting or wrapping.
+	 *
+	 * @param e The exception to wrap.
+	 * @return The casted or wrapped exception.
+	 */
+	public static RestCallException create(Exception e) {
+		if (e instanceof RestCallException)
+			return (RestCallException)e;
+		return new RestCallException(e);
+	}
+
+	/**
 	 * Constructor.
 	 *
 	 * @param message The {@link MessageFormat}-style message.
@@ -87,10 +99,17 @@ public final class RestCallException extends IOException {
 	 *
 	 * @param msg The exception message.
 	 * @param response The HTTP response object.
-	 * @throws IOException Thrown by underlying stream.
 	 */
-	public RestCallException(String msg, HttpResponse response) throws IOException {
-		super(format("{0}\n{1}\nstatus=''{2}''\nResponse: \n{3}", msg, response.getStatusLine().getStatusCode(), EntityUtils.toString(response.getEntity(), UTF8)));
+	public RestCallException(String msg, HttpResponse response) {
+		super(format("{0}\n{1}\nstatus=''{2}''\nResponse: \n{3}", msg, response.getStatusLine().getStatusCode(), readEntity(response)));
+	}
+
+	private static String readEntity(HttpResponse response) {
+		try {
+			return EntityUtils.toString(response.getEntity(), UTF8);
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
 	}
 
 	/**
@@ -118,13 +137,13 @@ public final class RestCallException extends IOException {
 	 * @param exceptionTrace The stack trace of the exception returned by {@link Throwable#printStackTrace()}.
 	 * @return This object (for method chaining).
 	 */
-	protected RestCallException setServerException(Header exceptionName, Header exceptionMessage, Header exceptionTrace) {
+	protected RestCallException setServerException(String exceptionName, String exceptionMessage, String exceptionTrace) {
 		if (exceptionName != null)
-			serverExceptionName = exceptionName.getValue();
+			serverExceptionName = exceptionName;
 		if (exceptionMessage != null)
-			serverExceptionMessage = exceptionMessage.getValue();
+			serverExceptionMessage = exceptionMessage;
 		if (exceptionTrace != null)
-			serverExceptionTrace = exceptionTrace.getValue();
+			serverExceptionTrace = exceptionTrace;
 		return this;
 	}
 
@@ -182,11 +201,11 @@ public final class RestCallException extends IOException {
 	/**
 	 * Sets the HTTP response object that caused this exception.
 	 *
-	 * @param httpResponse The HTTP response object.
+	 * @param restResponse The REST response object.
 	 * @return This object (for method chaining).
 	 */
-	protected RestCallException setHttpResponse(HttpResponse httpResponse) {
-		this.httpResponse = httpResponse;
+	protected RestCallException setRestResponse(RestResponse restResponse) {
+		this.restResponse = restResponse;
 		return this;
 	}
 
@@ -197,8 +216,8 @@ public final class RestCallException extends IOException {
 	 * 	The HTTP response object that caused this exception, or <jk>null</jk> if no response was created yet when the
 	 * 	exception was thrown.
 	 */
-	public HttpResponse getHttpResponse() {
-		return this.httpResponse;
+	public RestResponse getRestResponse() {
+		return this.restResponse;
 	}
 
 	/**
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallHandler.java
similarity index 50%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java
copy to juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallHandler.java
index 15cf54d..52372a3 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallHandler.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallHandler.java
@@ -10,29 +10,30 @@
 // * "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;
+package org.apache.juneau.rest.client2;
 
 import java.io.*;
 
 import org.apache.http.*;
 import org.apache.http.client.*;
 import org.apache.http.client.methods.*;
+import org.apache.http.protocol.*;
 
 /**
  * Interface that allows you to override the handling of HTTP requests.
  *
  * <p>
- * Providing this implementation is the equivalent to overriding the {@link RestClient#execute(HttpEntityEnclosingRequestBase)}
- * and {@link RestClient#execute(HttpRequestBase)} methods.
+ * Providing this implementation is the equivalent to overriding the {@link RestClient#execute(HttpHost,HttpEntityEnclosingRequestBase,HttpContext)}
+ * and {@link RestClient#execute(HttpHost,HttpRequestBase,HttpContext)} methods.
  *
  * <p>
- * This can also be accomplished by providing your own {@link RestClientBuilder#connectionManager(org.apache.http.conn.HttpClientConnectionManager)},
- * but this provides a simpler way of handling the requests yourself.
+ * This can also be accomplished by providing your own {@link RestClientBuilder#connectionManager(org.apache.http.conn.HttpClientConnectionManager)}
+ * or subclassing {@link RestClient}, but this provides a simpler way of handling the requests yourself.
  *
  * <ul class='seealso'>
  * 	<li class='jf'>{@link RestClient#RESTCLIENT_callHandler}
- * 	<li class='jf'>{@link RestClientBuilder#callHandler(Class)}
- * 	<li class='jf'>{@link RestClientBuilder#callHandler(RestCallHandler)}
+ * 	<li class='jm'>{@link RestClientBuilder#callHandler(Class)}
+ * 	<li class='jm'>{@link RestClientBuilder#callHandler(RestCallHandler)}
  * </ul>
  */
 public interface RestCallHandler {
@@ -43,12 +44,20 @@ public interface RestCallHandler {
 	 * <p>
 	 * Subclasses can override this method to provide specialized handling.
 	 *
-	 * @param req The HTTP request.
-	 * @return The HTTP response.
-	 * @throws IOException Stream exception occurred.
-	 * @throws ClientProtocolException Signals an error in the HTTP protocol.
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
 	 */
-	HttpResponse execute(HttpEntityEnclosingRequestBase req) throws ClientProtocolException, IOException;
+	HttpResponse execute(HttpHost target, HttpEntityEnclosingRequestBase request, HttpContext context) throws ClientProtocolException, IOException;
 
 	/**
 	 * Execute the specified no-body request (e.g. GET/DELETE).
@@ -56,10 +65,18 @@ public interface RestCallHandler {
 	 * <p>
 	 * Subclasses can override this method to provide specialized handling.
 	 *
-	 * @param req The HTTP request.
-	 * @return The HTTP response.
-	 * @throws IOException Stream exception occurred.
-	 * @throws ClientProtocolException Signals an error in the HTTP protocol.
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
 	 */
-	HttpResponse execute(HttpRequestBase req) throws ClientProtocolException, IOException;
+	HttpResponse execute(HttpHost target, HttpRequestBase request, HttpContext context) throws ClientProtocolException, IOException;
 }
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
similarity index 66%
copy from juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java
copy to juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
index 3023a0d..5ce0d00 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestCallInterceptor.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestCallInterceptor.java
@@ -10,9 +10,7 @@
 // * "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 org.apache.http.*;
+package org.apache.juneau.rest.client2;
 
 /**
  * Used to intercept http connection responses to allow modification of that response before processing and for
@@ -20,42 +18,39 @@ import org.apache.http.*;
  *
  * <p>
  * Useful if you want to prevent {@link RestCallException RestCallExceptions} from being thrown on error conditions.
+ *
+ * <ul class='seealso'>
+ * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
+ * 	<li class='jm'>{@link RestClientBuilder#interceptors(Class...)}
+ * 	<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...)}
+ * </ul>
  */
-public abstract class RestCallInterceptor {
+public interface RestCallInterceptor {
 
 	/**
-	 * Called when {@link RestCall} object is created.
+	 * Called when {@link RestRequest} object is created.
 	 *
 	 * @param restCall The restCall object invoking this method.
+	 * @throws Exception Any exception can be thrown.
 	 */
-	public void onInit(RestCall restCall) {}
+	public void onInit(RestRequest restCall) throws Exception;
 
 	/**
 	 * Called immediately after an HTTP response has been received.
 	 *
-	 * @param statusCode The HTTP status code received.
-	 * @param restCall The restCall object invoking this method.
 	 * @param req The HTTP request object.
 	 * @param res The HTTP response object.
+	 * @throws Exception Any exception can be thrown.
 	 */
-	public void onConnect(RestCall restCall, int statusCode, HttpRequest req, HttpResponse res) {}
+	public void onConnect(RestRequest req, RestResponse res) throws Exception;
 
 	/**
-	 * Called if retry is going to be attempted.
+	 * Called when the response body is consumed.
 	 *
-	 * @param statusCode The HTTP status code received.
-	 * @param restCall The restCall object invoking this method.
-	 * @param req The HTTP request object.
-	 * @param res The HTTP response object.
-	 * @param ex The exception thrown from the client.
-	 */
-	public void onRetry(RestCall restCall, int statusCode, HttpRequest req, HttpResponse res, Exception ex) {}
-
-	/**
-	 * Called when {@link RestCall#close()} is called.
-	 *
-	 * @param restCall The restCall object invoking this method.
+	 * @param req The request object.
+	 * @param res The response object.
 	 * @throws RestCallException Error occurred during call.
+	 * @throws Exception Any exception can be thrown.
 	 */
-	public void onClose(RestCall restCall) throws RestCallException {}
+	public void onClose(RestRequest req, RestResponse res) throws Exception;
 }
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
new file mode 100644
index 0000000..e5462d2
--- /dev/null
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -0,0 +1,3095 @@
+// ***************************************************************************************************************************
+// * 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.client2;
+
+import static org.apache.juneau.internal.StringUtils.*;
+import static org.apache.juneau.httppart.HttpPartType.*;
+
+import java.io.*;
+import java.lang.reflect.*;
+import java.lang.reflect.Proxy;
+import java.net.*;
+import java.net.URI;
+import java.util.*;
+import java.util.concurrent.*;
+import java.util.function.*;
+import java.util.logging.*;
+import java.util.regex.*;
+import java.util.stream.*;
+
+import javax.net.ssl.*;
+
+import org.apache.http.*;
+import org.apache.http.client.*;
+import org.apache.http.client.config.*;
+import org.apache.http.client.entity.*;
+import org.apache.http.client.methods.*;
+import org.apache.http.client.utils.*;
+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.util.*;
+import org.apache.http.entity.*;
+import org.apache.http.impl.client.*;
+import org.apache.http.params.*;
+import org.apache.http.protocol.*;
+import org.apache.juneau.*;
+import org.apache.juneau.annotation.*;
+import org.apache.juneau.http.remote.RemoteReturn;
+import org.apache.juneau.http.*;
+import org.apache.juneau.http.remote.*;
+import org.apache.juneau.httppart.*;
+import org.apache.juneau.httppart.bean.*;
+import org.apache.juneau.internal.*;
+import org.apache.juneau.json.*;
+import org.apache.juneau.marshall.*;
+import org.apache.juneau.oapi.*;
+import org.apache.juneau.parser.*;
+import org.apache.juneau.reflect.*;
+import org.apache.juneau.remote.*;
+import org.apache.juneau.rest.client.remote.*;
+import org.apache.juneau.rest.client2.ext.*;
+import org.apache.juneau.rest.client2.logging.*;
+import org.apache.juneau.serializer.*;
+import org.apache.juneau.urlencoding.*;
+import org.apache.juneau.utils.*;
+import org.apache.http.client.CookieStore;
+
+/**
+ * Utility class for interfacing with remote REST interfaces.
+ *
+ * <p class='w900'>
+ * Built upon the feature-rich Apache HttpClient library, the Juneau RestClient API adds support for fluent-style
+ * REST calls and the ability to perform marshalling of POJOs to and from HTTP parts.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a basic REST client with JSON support and download a bean.</jc>
+ * 	<jk>try</jk> (RestClient c = RestClient.<jsm>create</jsm>().build()) {
+ * 		MyBean b = c.get(<jsf>URL</jsf>).run().assertStatusCode(200).getBody().as(MyBean.<jk>class</jk>);
+ * 	}
+ * </p>
+ *
+ * <p class='w900'>
+ * Breaking apart the fluent call, we can see the classes being used:
+ * <p class='bcode w800'>
+ * 	<jc>// Create a basic REST client with JSON support and download a bean.</jc>
+ * 	<jk>try</jk> (RestClient c = RestClient.<jsm>create</jsm>().build()) {
+ * 		RestRequest req = c.get(<jsf>URL</jsf>);
+ * 		RestResponse res = req.run();
+ * 		res.assertStatusCode(200);
+ * 		RestResponseBody body = res.getBody();
+ * 		MyBean b = body.as(MyBean.<jk>class</jk>);
+ * 	}
+ * </p>
+ *
+ * <p class='w900'>
+ * It additionally provides support for creating remote proxy interfaces using REST as the transport medium.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Define a Remote proxy for interacting with a REST interface.</jc>
+ * 	<ja>@Remote</ja>(path=<js>"/petstore"</js>)
+ * 	<jk>public interface</jk> PetStore {
+ * 		<ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
+ * 		Pet addPet(
+ * 			<ja>@Body</ja> CreatePet pet,
+ * 			<ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
+ * 			<ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ * 		);
+ * 	}
+ *
+ * 	<jc>// Use a RestClient with default Simple JSON support.</jc>
+ * 	<jk>try</jk> (RestClient c = RestClient.<jsm>create</jsm>().simpleJson().build()) {
+ * 		PetStore store = c.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+ * 		CreatePet cp = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ * 		Pet p = store.addPet(cp, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
+ * 	}
+ * </p>
+ *
+ * <p class='w900'>
+ * The classes are closely tied to Apache HttpClient, yet provide lots of additional functionality:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClient} <jk>extends</jk> {@link HttpClient}, creates {@link RestRequest} objects.
+ * 	<li class='jc'>{@link RestRequest} <jk>extends</jk> {@link HttpUriRequest}, creates {@link RestResponse} objects.
+ * 	<li class='jc'>{@link RestResponse} <jk>extends</jk> {@link HttpResponse}, creates {@link RestResponseBody} and {@link RestResponseHeader} objects.
+ * 	<li class='jc'>{@link RestResponseBody} <jk>extends</jk> {@link HttpEntity}
+ * 	<li class='jc'>{@link RestResponseHeader} <jk>extends</jk> {@link Header}
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Instantiation and Lifecycle</h4>
+ *
+ * <p class='w900'>
+ * Instances of this class are built using the {@link RestClientBuilder} class which can be constructed using
+ * the {@link #create() RestClient.create()} method as shown above.
+ *
+ * <p class='w900'>
+ * Clients are typically created with a root URL so that relative URLs can be used when making requests.
+ * This is done using the {@link RestClientBuilder#rootUrl(Object)} method.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a client where all URLs are relative to localhost.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().rootUrl(<js>"http://localhost:5000"</js>).build();
+ *
+ * 	<jc>// Use relative paths.</jc>
+ * 	String body = c.get(<js>"/subpath"</js>).run().getBody().asString();
+ * </p>
+ *
+ * <p class='w900'>
+ * The {@link RestClient} class creates {@link RestRequest} objects using the following methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClient}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClient#get(Object) get(Object url)}
+ * 		<li class='jm'>{@link RestClient#put(Object,Object) put(Object url, Object body)}
+ * 		<li class='jm'>{@link RestClient#put(Object) put(Object url)}
+ * 		<li class='jm'>{@link RestClient#post(Object) post(Object url, Object body)}
+ * 		<li class='jm'>{@link RestClient#post(Object) post(Object url)}
+ * 		<li class='jm'>{@link RestClient#patch(Object,Object) patch(Object url, Object body)}
+ * 		<li class='jm'>{@link RestClient#patch(Object) patch(Object url)}
+ * 		<li class='jm'>{@link RestClient#delete(Object) delete(Object url)}
+ * 		<li class='jm'>{@link RestClient#options(Object) options(Object url)}
+ * 		<li class='jm'>{@link RestClient#formPost(Object,Object) formPost(Object url, Object body)}
+ * 		<li class='jm'>{@link RestClient#formPost(Object) formPost(Object url)}
+ * 		<li class='jm'>{@link RestClient#formPost(Object,NameValuePairs) formPost(Object url, NameValuePairs parameters)}
+ * 		<li class='jm'>{@link RestClient#formPost(Object,NameValuePair...) formPost(Object url, NameValuePair...parameters)}
+ * 		<li class='jm'>{@link RestClient#formPost(Object,Object...) formPost(Object url, Object...parameters)}
+ * 		<li class='jm'>{@link RestClient#request(HttpMethod,Object,Object) request(HttpMethod method, Object url, Object body)}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The {@link RestRequest} class creates {@link RestResponse} objects using the following methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#run() run()}
+ * 		<li class='jm'>{@link RestRequest#execute() execute()}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The distinction between the two methods is that {@link RestRequest#execute() execute()} automatically consumes the response body and
+ * {@link RestRequest#run() run()} does not.  Note that you must consume response bodies in order for HTTP connections to be freed up
+ * for reuse!  The {@link InputStream InputStreams} returned by the {@link RestResponseBody} object are auto-closing once
+ * they are exhausted, so it is often not necessary to explicitly close them.
+ *
+ * <p class='w900'>
+ * The following examples show the distinction between the two calls:
+ *
+ * <p class='bcode w800'>
+ * 	<jc>// Consuming the response, so use run().</jc>
+ * 	String body = client.get(<jsf>URL</jsf>).run().getBody().asString();
+ *
+ * 	<jc>// Only interested in response status code, so use execute().</jc>
+ *   <jk>int</jk> status = client.get(<jsf>URL</jsf>).execute().getStatusCode();
+ * </p>
+ *
+ * <ul class='notes'>
+ * 	<li>Don't confuse the behavior on the {@link RestRequest#execute()} method with the various execute methods defined on
+ * 		the {@link RestClient} class.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>POJO Marshalling</h4>
+ *
+ * <p class='w900'>
+ * By default, JSON support is provided for HTTP request and response bodies.
+ * Other languages can be specified using any of the following builder methods:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#json() json()}
+ * 		<li class='jm'>{@link RestClientBuilder#simpleJson() simpleJson()}
+ * 		<li class='jm'>{@link RestClientBuilder#xml() xml()}
+ * 		<li class='jm'>{@link RestClientBuilder#html() html()}
+ * 		<li class='jm'>{@link RestClientBuilder#plainText() plainText()}
+ * 		<li class='jm'>{@link RestClientBuilder#msgpack() msgpack()}
+ * 		<li class='jm'>{@link RestClientBuilder#uon() uon()}
+ * 		<li class='jm'>{@link RestClientBuilder#urlEnc() urlEnc()}
+ * 		<li class='jm'>{@link RestClientBuilder#openapi() openapi()}
+ * 	</ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a basic REST client with Simplified-JSON support.</jc>
+ * 	<jc>// Typically easier to use when performing unit tests.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().simpleJson().build();
+ * </p>
+ *
+ * <p class='w900'>
+ * 	Other methods are also provided for specifying the serializers and parsers used for lower-level marshalling support:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#serializer(Serializer) serializer(Serializer)}
+ * 		<li class='jm'>{@link RestClientBuilder#serializer(Class) serializer(Class&lt;? extends Serializer>)}
+ * 		<li class='jm'>{@link RestClientBuilder#parser(Parser) parser(Parser)}
+ * 		<li class='jm'>{@link RestClientBuilder#parser(Class) parser(Class&lt;? extends Parser>)}
+ * 		<li class='jm'>{@link RestClientBuilder#marshall(Marshall) marshall(Marshall)}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * HTTP parts (headers, query parameters, form data...) are serialized and parsed using the {@link HttpPartSerializer}
+ * and {@link HttpPartParser} APIs.  By default, clients are configured to use {@link OpenApiSerializer} and
+ * {@link OpenApiParser}.  These can be overridden using the following methods:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#partSerializer(HttpPartSerializer) partSerializer(HttpPartSerializer)}
+ * 		<li class='jm'>{@link RestClientBuilder#partSerializer(Class) partSerializer(Class&lt;? extends HttpPartSerializer>)}
+ * 		<li class='jm'>{@link RestClientBuilder#partParser(HttpPartParser) partParser(HttpPartParser)}
+ * 		<li class='jm'>{@link RestClientBuilder#partParser(Class) partParser(Class&lt;? extends HttpPartParser>)}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The {@link RestClientBuilder} class also provides convenience methods for setting common serializer and parser
+ * settings.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a basic REST client with JSON support.</jc>
+ * 	<jc>// Use single-quotes and whitespace.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().json().sq().ws().build();
+ * </p>
+ *
+ *
+ * <h4 class='topic'>Request Headers</h4>
+ * <p class='w900'>
+ * Per-client or per-request headers can be specified using the following methods:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#header(Header) header(Header)}
+ * 		<li class='jm'>{@link RestClientBuilder#header(HttpHeader) header(HttpHeader)}
+ * 		<li class='jm'>{@link RestClientBuilder#header(NameValuePair) header(NameValuePair)}
+ * 		<li class='jm'>{@link RestClientBuilder#header(String,Object) header(String,Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#header(String,Object,HttpPartSerializer,HttpPartSchema) header(String,Object,HttpPartSerializer,HttpPartSchema)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(Header...) headers(Header...)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(HttpHeader...) headers(HttpHeader...)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(Map) headers(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(NameValuePair...) headers(NameValuePair...)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(NameValuePairs) headers(NameValuePairs)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(Object...) headers(Object...)}
+ * 		<li class='jm'>{@link RestClientBuilder#headers(ObjectMap) headers(ObjectMap)}
+ * 		<li class='jm'>{@link RestClientBuilder#accept(Object) accept(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#acceptCharset(Object) acceptCharset(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#acceptEncoding(Object) acceptEncoding(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#acceptLanguage(Object) acceptLanguage(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#authorization(Object) authorization(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#cacheControl(Object) cacheControl(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#clientVersion(Object) clientVersion(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#connection(Object) connection(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#contentLength(Object) contentLength(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#contentType(Object) contentType(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#date(Object) date(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#expect(Object) expect(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#forwarded(Object) forwarded(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#from(Object) from(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#host(Object) host(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#ifMatch(Object) ifMatch(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#ifModifiedSince(Object) ifModifiedSince(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#ifNoneMatch(Object) ifNoneMatch(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#ifRange(Object) ifRange(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#maxForwards(Object) maxForwards(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#origin(Object) origin(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#pragma(Object) pragma(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#proxyAuthorization(Object) proxyAuthorization(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#range(Object) proxyAuthorization(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#referer(Object) referer(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#te(Object) te(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#userAgent(Object) userAgent(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#upgrade(Object) upgrade(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#via(Object) via(Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#warning(Object) warning(Object)}
+ * 	</ul>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#header(Header) header(Header)}
+ * 		<li class='jm'>{@link RestRequest#header(Header,boolean) header(Header,boolean)}
+ * 		<li class='jm'>{@link RestRequest#header(HttpHeader) header(HttpHeader)}
+ * 		<li class='jm'>{@link RestRequest#header(NameValuePair) header(NameValuePair)}
+ * 		<li class='jm'>{@link RestRequest#header(NameValuePair,boolean) header(NameValuePair,boolean)}
+ * 		<li class='jm'>{@link RestRequest#header(String,Object) header(String,Object)}
+ * 		<li class='jm'>{@link RestRequest#header(String,Object,boolean,HttpPartSerializer,HttpPartSchema) header(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+ * 		<li class='jm'>{@link RestRequest#headers(Header...) headers(Header...)}
+ * 		<li class='jm'>{@link RestRequest#headers(HttpHeader...) headers(HttpHeader...)}
+ * 		<li class='jm'>{@link RestRequest#headers(Map) headers(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestRequest#headers(NameValuePair...) headers(NameValuePair...)}
+ * 		<li class='jm'>{@link RestRequest#headers(NameValuePairs) headers(NameValuePairs)}
+ * 		<li class='jm'>{@link RestRequest#headers(Object) headers(Object)}
+ * 		<li class='jm'>{@link RestRequest#headers(Object...) headers(Object...)}
+ * 		<li class='jm'>{@link RestRequest#headers(ObjectMap) headers(ObjectMap)}
+ *		<li class='jm'>{@link RestRequest#accept(Object) accept(Object)}
+ * 		<li class='jm'>{@link RestRequest#acceptCharset(Object) acceptCharset(Object)}
+ * 		<li class='jm'>{@link RestRequest#acceptEncoding(Object) acceptEncoding(Object)}
+ * 		<li class='jm'>{@link RestRequest#acceptLanguage(Object) acceptLanguage(Object)}
+ * 		<li class='jm'>{@link RestRequest#authorization(Object) authorization(Object)}
+ * 		<li class='jm'>{@link RestRequest#cacheControl(Object) cacheControl(Object)}
+ * 		<li class='jm'>{@link RestRequest#clientVersion(Object) clientVersion(Object)}
+ * 		<li class='jm'>{@link RestRequest#connection(Object) connection(Object)}
+ * 		<li class='jm'>{@link RestRequest#contentLength(Object) contentLength(Object)}
+ * 		<li class='jm'>{@link RestRequest#contentType(Object) contentType(Object)}
+ * 		<li class='jm'>{@link RestRequest#date(Object) date(Object)}
+ * 		<li class='jm'>{@link RestRequest#expect(Object) expect(Object)}
+ * 		<li class='jm'>{@link RestRequest#forwarded(Object) forwarded(Object)}
+ * 		<li class='jm'>{@link RestRequest#from(Object) from(Object)}
+ * 		<li class='jm'>{@link RestRequest#host(Object) host(Object)}
+ * 		<li class='jm'>{@link RestRequest#ifMatch(Object) ifMatch(Object)}
+ * 		<li class='jm'>{@link RestRequest#ifModifiedSince(Object) ifModifiedSince(Object)}
+ * 		<li class='jm'>{@link RestRequest#ifNoneMatch(Object) ifNoneMatch(Object)}
+ * 		<li class='jm'>{@link RestRequest#ifRange(Object) ifRange(Object)}
+ * 		<li class='jm'>{@link RestRequest#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
+ * 		<li class='jm'>{@link RestRequest#maxForwards(Object) maxForwards(Object)}
+ * 		<li class='jm'>{@link RestRequest#origin(Object) origin(Object)}
+ * 		<li class='jm'>{@link RestRequest#pragma(Object) pragma(Object)}
+ * 		<li class='jm'>{@link RestRequest#proxyAuthorization(Object) proxyAuthorization(Object)}
+ * 		<li class='jm'>{@link RestRequest#range(Object) proxyAuthorization(Object)}
+ * 		<li class='jm'>{@link RestRequest#referer(Object) referer(Object)}
+ * 		<li class='jm'>{@link RestRequest#te(Object) te(Object)}
+ * 		<li class='jm'>{@link RestRequest#userAgent(Object) userAgent(Object)}
+ * 		<li class='jm'>{@link RestRequest#upgrade(Object) upgrade(Object)}
+ * 		<li class='jm'>{@link RestRequest#via(Object) via(Object)}
+ * 		<li class='jm'>{@link RestRequest#warning(Object) warning(Object)}
+ * 	</ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a client that adds an Authorization header to every request.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, <js>"Foo"</js>).build();
+ *
+ * 	<jc>// Or do it on every request.</jc>
+ * 	String response = c.get(<jsf>URL</jsf>).authorization(<js>"Foo"</js>).run().getBody().asString();
+ *
+ * 	<jc>// Or use an HttpHeader.</jc>
+ * 	response = c.get(<jsf>URL</jsf>).headers(<jk>new</jk> Authorization(<js>"Foo"</js>)).run().getBody().asString();
+ * </p>
+ *
+ * <p class='w900'>
+ * Note that in the methods above, header values are specified as objects which are converted to strings at runtime.
+ * This allows you to pass in headers whose values may change over time (such as <c>Authorization</c> headers
+ * which may need to change every few minutes).
+ * </p>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jk>public class</jk> AuthGenerator {
+ * 		<jk>public</jk> String toString() {
+ * 			<jc>// Generate an updated auth token.</jc>
+ * 		}
+ * 	}
+ *
+ * 	<jc>// Create a client that adds an Authorization header to every request.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().authorization(<jk>new</jk> AuthGenerator()).build();
+ * </p>
+ *
+ * <ul class='notes'>
+ * 	<li>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>Header</c> or
+ * 		<c>NameValuePair</c> objects use the values returned by that bean directly.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Request Query Parameters</h4>
+ * <p>
+ * Per-client or per-request query parmameters can be specified using the following methods:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#query(Map) query(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(NameValuePair) query(NameValuePair)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(NameValuePair...) query(NameValuePair...)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(NameValuePairs) query(NameValuePairs)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(Object...) query(Object...)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(ObjectMap) query(ObjectMap)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(String,Object) query(String,Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#query(String,Object,HttpPartSerializer,HttpPartSchema) query(String,Object,HttpPartSerializer,HttpPartSchema)}
+ * 	</ul>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#query(Map) query(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestRequest#query(NameValuePair) query(NameValuePair)}
+ * 		<li class='jm'>{@link RestRequest#query(NameValuePair,boolean) query(NameValuePair,boolean)}
+ * 		<li class='jm'>{@link RestRequest#query(NameValuePair...) query(NameValuePair...)}
+ * 		<li class='jm'>{@link RestRequest#query(NameValuePairs) query(NameValuePairs)}
+ * 		<li class='jm'>{@link RestRequest#query(Object) query(Object)}
+ * 		<li class='jm'>{@link RestRequest#query(Object...) query(Object...)}
+ * 		<li class='jm'>{@link RestRequest#query(ObjectMap) query(ObjectMap)}
+ * 		<li class='jm'>{@link RestRequest#query(String) query(String)}
+ * 		<li class='jm'>{@link RestRequest#query(String,Object) query(String,Object)}
+ * 		<li class='jm'>{@link RestRequest#query(String,Object,boolean,HttpPartSerializer,HttpPartSchema) query(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+ * 	</ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Create a client that adds a ?foo=bar query parameter to every request.</jc>
+ * 	RestClient c = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
+ *
+ * 	<jc>// Or do it on every request.</jc>
+ * 	String response = c.get(<jsf>URL</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
+ * </p>
+ *
+ * <ul class='notes'>
+ * 	<li>Like header values, you can pass in objects that get converted to strings at runtime.
+ * 	<li>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
+ * 		objects use the values returned by that bean directly.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Request Form Data</h4>
+ *
+ * <p class='w900'>
+ * Per-client or per-request form-data parameters can be specified using the following methods:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#formData(Map) formData(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(NameValuePair) formData(NameValuePair)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(NameValuePair...) formData(NameValuePair...)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(NameValuePairs) formData(NameValuePairs)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(Object...) formData(Object...)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(ObjectMap) formData(ObjectMap)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(String,Object) formData(String,Object)}
+ * 		<li class='jm'>{@link RestClientBuilder#formData(String,Object,HttpPartSerializer,HttpPartSchema) formData(String,Object,HttpPartSerializer,HttpPartSchema)}
+ * 	</ul>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#formData(CharSequence) formData(CharSequence)}
+ * 		<li class='jm'>{@link RestRequest#formData(InputStream) formData(InputStream)}
+ * 		<li class='jm'>{@link RestRequest#formData(Map) formData(Map&lt;String,Object>)}
+ * 		<li class='jm'>{@link RestRequest#formData(NameValuePair) formData(NameValuePair)}
+ * 		<li class='jm'>{@link RestRequest#formData(NameValuePair,boolean) formData(NameValuePair,boolean)}
+ * 		<li class='jm'>{@link RestRequest#formData(NameValuePair...) formData(NameValuePair...)}
+ * 		<li class='jm'>{@link RestRequest#formData(NameValuePairs) formData(NameValuePairs)}
+ * 		<li class='jm'>{@link RestRequest#formData(Object) formData(Object)}
+ * 		<li class='jm'>{@link RestRequest#formData(Object...) formData(Object...)}
+ * 		<li class='jm'>{@link RestRequest#formData(ObjectMap) formData(ObjectMap)}
+ * 		<li class='jm'>{@link RestRequest#formData(Reader) formData(Reader)}
+ * 		<li class='jm'>{@link RestRequest#formData(String,Object) formData(String,Object)}
+ * 		<li class='jm'>{@link RestRequest#formData(String,Object,boolean,HttpPartSerializer,HttpPartSchema) formData(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+ * 	</ul>
+ * </ul>
+ *
+ * <ul class='notes'>
+ * 	<li>Like header values, you can pass in objects that get converted to strings at runtime.
+ * 	<li>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
+ * 		objects use the values returned by that bean directly.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Request Body</h4>
+ *
+ * <p class='w900'>
+ * The request body can either be passed in with the client creator method (e.g. {@link RestClient#post(Object,Object)}),
+ * or can be specified via the following methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#body(Object) body(Object)}
+ * 		<li class='jm'>{@link RestRequest#body(Object,HttpPartSchema) body(Object,HttpPartSchema)}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The request body can be any of the following types:
+ * <ul class='javatree'>
+ * 		<li class='jc'>
+ * 			{@link Object} - POJO to be converted to text using the {@link Serializer} defined on the client or request.
+ * 		<li class='jc'>
+ * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
+ * 		<li class='jc'>
+ * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
+ * 		<li class='jc'>
+ * 			{@link ReaderResource} - Raw contents of {@code Reader} will be serialized to remote resource.  Additional headers and media type will be set on request.
+ * 		<li class='jc'>
+ * 			{@link StreamResource} - Raw contents of {@code InputStream} will be serialized to remote resource.  Additional headers and media type will be set on request.
+ * 		<li class='jc'>
+ * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
+ * 		<li class='jc'>
+ * 			{@link NameValuePairs} - Converted to a URL-encoded FORM post.
+ * 	</ul>
+ *
+ * <ul class='notes'>
+ * 	<li>If the serializer on the client or request is explicitly set to <jk>null</jk>, POJOs will be converted to strings
+ * 		using the registered part serializer as content type <js>"text/plain</js>.  If the part serializer is also <jk>null</jk>,
+ * 		POJOs will be converted to strings using {@link ClassMeta#toString(Object)} which typically just calls {@link Object#toString()}.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Response Status</h4>
+ *
+ * <p class='w900'>
+ * After execution using {@link RestRequest#run()} or {@link RestRequest#execute()}, the following methods can be used
+ * to get the response status:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestResponse}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestResponse#getStatusLine() getStatusLine()} <jk>returns</jk> {@link StatusLine}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getStatusLine(Mutable) getStatusLine(Mutable&lt;StatusLine&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getStatusCode() getStatusCode()} <jk>returns</jk> <jk>int</jk></c>
+ * 		<li class='jm'><c>{@link RestResponse#getStatusCode(Mutable) getStatusCode(Mutable&lt;Integer&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getReasonPhrase() getReasonPhrase()} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponse#getReasonPhrase(Mutable) getReasonPhrase(Mutable&lt;String&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponse#assertStatusCode(int...) assertStatusCode(int...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponse#assertStatusCode(Predicate) assertStatusCode(Predicate&lt;Integer&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The methods with mutable parameters are provided to allow access to status values without breaking fluent call chains.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Only interested in status code.</jc>
+ * 	<jk>int</jk> statusCode = c.get(<jsf>URL</jsf>).execute().getStatusCode();
+ *
+ *   <jc>// Interested in multiple values.</jc>
+ * 	Mutable&lt;Integer&gt; statusCode;
+ * 	Mutable&lt;String&gt; reasonPhrase;
+ * 	c.get(<jsf>URL</jsf>).execute().getStatusCode(statusCode).getReasonPhrase(reasonPhrase);
+ * 	System.<jsf>err</jsf>.println(<js>"statusCode="</js>+statusCode.get()+<js>", reasonPhrase="</js>+reasonPhrase.get());
+ * </p>
+ *
+ * <ul class='notes'>
+ * 	<li>If you are only interested in the response status and not the response body, be sure to use {@link RestRequest#execute()} instead
+ * 		of {@link RestRequest#run()} to make sure the response body gets automatically cleaned up.  Otherwise you must
+ * 		consume the response yourself.
+ * </ul>
+ *
+ * <p class='w900'>
+ * The assertion methods are provided for quickly asserting status codes in fluent calls.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Status assertion using a static value.</jc>
+ * 	String body = c.get(<jsf>URL</jsf>).run().assertStatusCode(200).getBody().asString();
+ *
+ * 	<jc>// Status assertion using a predicate.</jc>
+ * 	String body = c.get(<jsf>URL</jsf>).run().assertStatusCode(x -&gt; x &lt; 400).getBody().asString();
+ * </p>
+ *
+ *
+ * <h4 class='topic'>Response Headers</h4>
+ *
+ * <p class='w900'>
+ * Response headers are accessed through the following methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestResponse}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestResponse#getHeader(String) getHeader(String)} <jk>returns</jk> {@link RestResponseHeader}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getHeaders(String) getHeaders(String)} <jk>returns</jk> {@link RestResponseHeader}[]</c>
+ * 		<li class='jm'><c>{@link RestResponse#getFirstHeader(String) getFirstHeader(String)} <jk>returns</jk> {@link RestResponseHeader}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getLastHeader(String) getLastHeader(String)} <jk>returns</jk> {@link RestResponseHeader}</c>
+ * 		<li class='jm'><c>{@link RestResponse#getAllHeaders() getAllHeaders()} <jk>returns</jk> {@link RestResponseHeader}[]</c>
+ * 		<li class='jm'><c>{@link RestResponse#getStringHeader(String) getStringHeader(String)} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponse#getStringHeader(String,String) getStringHeader(String,String)} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponse#containsHeader(String) containsHeader(String)} <jk>returns</jk> <jk>boolean</jk></c>
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Unlike {@link RestResponse#getFirstHeader(String)} and {@link RestResponse#getLastHeader(String)}, the {@link RestResponse#getHeader(String)}
+ * method returns an empty {@link RestResponseHeader} object instead of returning <jk>null</jk>.
+ * This allows it to be used more easily in fluent calls.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// See if response contains Location header.</jc>
+ * 	<jk>boolean</jk> hasLocationHeader = c.get(<jsf>URL</jsf>).execute().getHeader(<js>"Location"</js>).exists();
+ * </p>
+ *
+ * <p class='w900'>
+ * The {@link RestResponseHeader} class extends from the HttpClient {@link Header} class and provides several convenience
+ * methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestResponseHeader}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestResponseHeader#exists() exists()} <jk>returns</jk> <jk>boolean</jk></c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asString() asString()} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asString(Mutable) asString(Mutable&lt;String&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptionalString() asOptionalString()} <jk>returns</jk> Optional&lt;String&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asStringOrElse(String) asStringOrElse(String)} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asStringOrElse(Mutable,String) asStringOrElse(Mutable&lt;String&gt;,String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(Mutable,Type,Type...) as(Mutable&lt;T&gt;,Type,Type...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk>T</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(Mutable,Class) as(Mutable&lt;T&gt;,Class&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(ClassMeta) as(ClassMeta&lt;T&gt;)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#as(Mutable,ClassMeta) as(Mutable&lt;T&gt;,ClassMeta&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(Type,Type...) asOptional(Type,Type...)} <jk>returns</jk> Optional&lt;T&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(Mutable,Type,Type...) asOptional(Mutable&lt;Optional&lt;T&gt;&gt;,Type,Type...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(Class) asOptional(Class&lt;T&gt;)} <jk>returns</jk> Optional&lt;T&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(Mutable,Class) asOptional(Mutable&lt;Optional&lt;T&gt;&gt;,Class&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(ClassMeta) asOptional(ClassMeta&lt;T&gt;)} <jk>returns</jk> Optional&lt;T&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asOptional(Mutable,ClassMeta) asOptional(Mutable&lt;Optional&lt;T&gt;&gt;,ClassMeta&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(Mutable,Pattern) asMatcher(Mutable&lt;Matcher&gt;,Pattern)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(Mutable,String) asMatcher(Mutable&lt;Matcher&gt;,String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(String,int) asMatcher(String,int)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#asMatcher(Mutable,String,int) asMatcher(Mutable&lt;Matcher&gt;,String,int)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertExists() assertExists()} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValue(String) assertValue(String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValue(Predicate) assertValue(Predicate&lt;String&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValueContains(String...) assertValueContains(String...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValueMatches(String) assertValueMatches(String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValueMatches(String,int) assertValueMatches(String,int)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseHeader#assertValueMatches(Pattern) assertValueMatches(Pattern)} <jk>returns</jk> {@link RestResponse}</c>
+ * 	</ul>
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Response Body</h4>
+ *
+ * <p class='w900'>
+ * The response body is accessed through the following method:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestResponse}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestResponse#getBody() getBody()} <jk>returns</jk> {@link RestResponseBody}</c>
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * The {@link RestResponseBody} class extends from the HttpClient {@link HttpEntity} class and provides several convenience
+ * methods:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestResponseBody}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestResponseBody#asInputStream() asInputStream()} <jk>returns</jk> InputStream</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asReader() asReader()} <jk>returns</jk> Reader</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asReader(String) asReader(String)} <jk>returns</jk> Reader</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#pipeTo(OutputStream) pipeTo(OutputStream)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#pipeTo(Writer) pipeTo(Writer)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#pipeTo(Writer,String) pipeTo(Writer,String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#pipeTo(Writer,boolean) pipeTo(Writer,boolean)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#pipeTo(Writer,String,boolean) pipeTo(Writer,String,boolean)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(Mutable,Type,Type...) as(Mutable&lt;T&gt;,Type,Type...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(Mutable,Class) as(Mutable&lt;T&gt;,Class&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(ClassMeta) as(ClassMeta&lt;T&gt;)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#as(Mutable,ClassMeta) as(Mutable&lt;T&gt;,ClassMeta&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(Class) asFuture(Class&lt;T&gt;)} <jk>returns</jk> Future&lt;T&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(Mutable,Class) asFuture(Mutable&lt;Future&lt;T&gt;&gt;,Class&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(ClassMeta) asFuture(ClassMeta&lt;T&gt;)} <jk>returns</jk>Future&lt;T&gt; </c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(Mutable,ClassMeta) asFuture(Mutable&lt;Future&lt;T&gt;&gt;,ClassMeta&lt;T&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(Type,Type...) asFuture(Type,Type...)} <jk>returns</jk> Future&lt;T&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asFuture(Mutable,Type,Type...) asFuture(Mutable&lt;Future&lt;T&gt;&gt;,Type,Type...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asString() asString()} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asString(Mutable) asString(Mutable&lt;String&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asStringFuture() asStringFuture()} <jk>returns</jk> Future&lt;String&gt;</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asStringFuture(Mutable) asStringFuture(Mutable&lt;Future&lt;String&gt;&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asAbbreviatedString(int) asAbbreviatedString(int)} <jk>returns</jk> String</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asAbbreviatedString(Mutable,int) asAbbreviatedString(Mutable&lt;String&gt;,int)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asPojoRest(Class) asPojoRest(Class&lt;?&gt;)} <jk>returns</jk> {@link PojoRest}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asPojoRest(Mutable,Class) asPojoRest(Mutable&lt;PojoRest&gt;,Class&lt;?&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asPojoRest() asPojoRest()} <jk>returns</jk> {@link PojoRest}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asPojoRest(Mutable) asPojoRest(Mutable&lt;PojoRest&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(Mutable,Pattern) asMatcher(Mutable&lt;Matcher&gt;,Pattern)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(Mutable,String) asMatcher(Mutable&lt;Matcher&gt;,String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(String,int) asMatcher(String,int)} <jk>returns</jk> {@link Matcher}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#asMatcher(Mutable,String,int) asMatcher(Mutable&lt;Matcher&gt;,String,int)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValue(String) assertValue(String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValueContains(String...) assertValueContains(String...)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValue(Predicate) assertValue(Predicate&lt;String&gt;)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValueMatches(String) assertValueMatches(String)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValueMatches(String,int) assertValueMatches(String,int)} <jk>returns</jk> {@link RestResponse}</c>
+ * 		<li class='jm'><c>{@link RestResponseBody#assertValueMatches(Pattern) assertValueMatches(Pattern)} <jk>returns</jk> {@link RestResponse}</c>
+ * 	</ul>
+ * </ul>
+ *
+ * <h5 class='figure'>Examples:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Parse into a linked-list of strings.</jc>
+ * 	List&lt;String&gt; l = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().as(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * 	<jc>// Parse into a linked-list of beans.</jc>
+ * 	List&lt;MyBean&gt; l = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().as(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
+ *
+ * 	<jc>// Parse into a linked-list of linked-lists of strings.</jc>
+ * 	List&lt;List&lt;String&gt;&gt; l = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().as(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * 	<jc>// Parse into a map of string keys/values.</jc>
+ * 	Map&lt;String,String&gt; m = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
+ *
+ * 	<jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
+ * 	Map&lt;String,List&lt;MyBean&gt;&gt; m = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
+ * </p>
+ *
+ * <p class='w900'>
+ * The response body can only be consumed once.  However, the {@link RestResponseBody#cache()} method is provided
+ * to cache the response body in memory so that you can perform several operations against it.
+ *
+ * <h5 class='figure'>Examples:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Cache the response body so that you can perform multiple operations against it.</jc>
+ * 	String body = client.get(<jsf>URL</jsf>).run()
+ * 		.getBody().cache().assertValueContains(<js>"Success"</js>)
+ * 		.getBody().asString();
+ * </p>
+ *
+ *
+ * <h4 class='topic'>Customizing Apache HttpClient</h4>
+ *
+ * <p class='w900'>
+ * Several methods are provided for customizing the underlying HTTP client and client builder classes:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#getHttpClientBuilder() getHttpClientBuilder()}
+ * 		<li class='jm'>{@link RestClientBuilder#httpClientBuilder(HttpClientBuilder) httpClientBuilder(HttpClientBuilder)}
+ * 		<li class='jm'>{@link RestClientBuilder#createHttpClientBuilder() createHttpClientBuilder()}
+ * 		<li class='jm'>{@link RestClientBuilder#createHttpClient() createHttpClient()}
+ * 		<li class='jm'>{@link RestClientBuilder#createConnectionManager() createConnectionManager()}
+ * 		<li class='jm'>{@link RestClientBuilder#pooled() pooled()}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Additionally, all methods on the <c>HttpClientBuilder</c> class are also exposed with fluent setters:
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#disableRedirectHandling() disableRedirectHandling()}
+ * 		<li class='jm'>{@link RestClientBuilder#redirectStrategy(RedirectStrategy) redirectStrategy(RedirectStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultCookieSpecRegistry(Lookup) defaultCookieSpecRegistry(Lookup&lt;CookieSpecProvider>)}
+ * 		<li class='jm'>{@link RestClientBuilder#requestExecutor(HttpRequestExecutor) requestExecutor(HttpRequestExecutor)}
+ * 		<li class='jm'>{@link RestClientBuilder#sslHostnameVerifier(HostnameVerifier) sslHostnameVerifier(HostnameVerifier)}
+ * 		<li class='jm'>{@link RestClientBuilder#publicSuffixMatcher(PublicSuffixMatcher) publicSuffixMatcher(PublicSuffixMatcher)}
+ * 		<li class='jm'>{@link RestClientBuilder#sslContext(SSLContext) sslContext(SSLContext)}
+ * 		<li class='jm'>{@link RestClientBuilder#sslSocketFactory(LayeredConnectionSocketFactory) sslSocketFactory(LayeredConnectionSocketFactory)}
+ * 		<li class='jm'>{@link RestClientBuilder#maxConnTotal(int) maxConnTotal(int)}
+ * 		<li class='jm'>{@link RestClientBuilder#maxConnPerRoute(int) maxConnPerRoute(int)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultSocketConfig(SocketConfig) defaultSocketConfig(SocketConfig)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultConnectionConfig(ConnectionConfig) defaultConnectionConfig(ConnectionConfig)}
+ * 		<li class='jm'>{@link RestClientBuilder#connectionTimeToLive(long,TimeUnit) connectionTimeToLive(long,TimeUnit)}
+ * 		<li class='jm'>{@link RestClientBuilder#connectionManager(HttpClientConnectionManager) connectionManager(HttpClientConnectionManager)}
+ * 		<li class='jm'>{@link RestClientBuilder#connectionManagerShared(boolean) connectionManagerShared(boolean)}
+ * 		<li class='jm'>{@link RestClientBuilder#connectionReuseStrategy(ConnectionReuseStrategy) connectionReuseStrategy(ConnectionReuseStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#keepAliveStrategy(ConnectionKeepAliveStrategy) keepAliveStrategy(ConnectionKeepAliveStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#targetAuthenticationStrategy(AuthenticationStrategy) targetAuthenticationStrategy(AuthenticationStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#proxyAuthenticationStrategy(AuthenticationStrategy) proxyAuthenticationStrategy(AuthenticationStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#userTokenHandler(UserTokenHandler) userTokenHandler(UserTokenHandler)}
+ * 		<li class='jm'>{@link RestClientBuilder#disableConnectionState() disableConnectionState()}
+ * 		<li class='jm'>{@link RestClientBuilder#schemePortResolver(SchemePortResolver) schemePortResolver(SchemePortResolver)}
+ * 		<li class='jm'>{@link RestClientBuilder#userAgent(String) userAgent(String)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultHeaders(Collection) defaultHeaders(Collection&lt;? extends Header>)}
+ * 		<li class='jm'>{@link RestClientBuilder#addInterceptorFirst(HttpResponseInterceptor) addInterceptorFirst(HttpResponseInterceptor)}
+ * 		<li class='jm'>{@link RestClientBuilder#addInterceptorLast(HttpResponseInterceptor) addInterceptorLast(HttpResponseInterceptor)}
+ * 		<li class='jm'>{@link RestClientBuilder#addInterceptorFirst(HttpRequestInterceptor) addInterceptorFirst(HttpRequestInterceptor)}
+ * 		<li class='jm'>{@link RestClientBuilder#addInterceptorLast(HttpRequestInterceptor) addInterceptorLast(HttpRequestInterceptor)}
+ * 		<li class='jm'>{@link RestClientBuilder#disableCookieManagement() disableCookieManagement()}
+ * 		<li class='jm'>{@link RestClientBuilder#disableContentCompression() disableContentCompression()}
+ * 		<li class='jm'>{@link RestClientBuilder#disableAuthCaching() disableAuthCaching()}
+ * 		<li class='jm'>{@link RestClientBuilder#httpProcessor(HttpProcessor) httpProcessor(HttpProcessor)}
+ * 		<li class='jm'>{@link RestClientBuilder#retryHandler(HttpRequestRetryHandler) retryHandler(HttpRequestRetryHandler)}
+ * 		<li class='jm'>{@link RestClientBuilder#disableAutomaticRetries() disableAutomaticRetries()}
+ * 		<li class='jm'>{@link RestClientBuilder#proxy(HttpHost proxy) proxy(HttpHost proxy)}
+ * 		<li class='jm'>{@link RestClientBuilder#routePlanner(HttpRoutePlanner) routePlanner(HttpRoutePlanner)}
+ * 		<li class='jm'>{@link RestClientBuilder#connectionBackoffStrategy(ConnectionBackoffStrategy) connectionBackoffStrategy(ConnectionBackoffStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#backoffManager(BackoffManager) backoffManager(BackoffManager)}
+ * 		<li class='jm'>{@link RestClientBuilder#serviceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy) serviceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultCookieStore(CookieStore) defaultCookieStore(CookieStore)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultCredentialsProvider(CredentialsProvider) defaultCredentialsProvider(CredentialsProvider)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultAuthSchemeRegistry(Lookup) defaultAuthSchemeRegistry(Lookup&lt;AuthSchemeProvider>)}
+ * 		<li class='jm'>{@link RestClientBuilder#contentDecoderRegistry(Map) contentDecoderRegistry(Map&lt;String,InputStreamFactory>)}
+ * 		<li class='jm'>{@link RestClientBuilder#defaultRequestConfig(RequestConfig) defaultRequestConfig(RequestConfig)}
+ * 		<li class='jm'>{@link RestClientBuilder#useSystemProperties() useSystemProperties()}
+ * 		<li class='jm'>{@link RestClientBuilder#evictExpiredConnections() evictExpiredConnections()}
+ * 		<li class='jm'>{@link RestClientBuilder#evictIdleConnections(long,TimeUnit) evictIdleConnections(long,TimeUnit)}
+ * 	</ul>
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Custom Call Handlers</h4>
+ *
+ * <p class='w900'>
+ * The {@link RestCallHandler} interface provides the ability to provide custom handling of requests.
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#callHandler(Class) callHandler(Class&lt;? extends RestCallHandler&gt;)}
+ * 		<li class='jm'>{@link RestClientBuilder#callHandler(RestCallHandler) callHandler(RestCallHandler)}
+ * 	</ul>
+ * 	<li class='jic'>{@link RestCallHandler}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestCallHandler#execute(HttpHost,HttpEntityEnclosingRequestBase,HttpContext) execute(HttpHost,HttpEntityEnclosingRequestBase,HttpContext)} <jk>returns</jk> HttpResponse</c>
+ * 		<li class='jm'><c>{@link RestCallHandler#execute(HttpHost,HttpRequestBase,HttpContext) execute(HttpHost,HttpRequestBase,HttpContext)} <jk>returns</jk> HttpResponse</c>
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Note that there are other ways of accomplishing this such as extending the {@link RestClient} class and overriding
+ * the {@link #execute(HttpHost,HttpEntityEnclosingRequestBase,HttpContext)} and {@link #execute(HttpHost,HttpRequestBase,HttpContext)}
+ * or by defining your own {@link HttpRequestExecutor}.  Using this interface is often simpler though.
+ *
+ *
+ * <h4 class='topic'>Logging / Debugging</h4>
+ *
+ * <p class='w900'>
+ * The following methods provide logging of requests and responses:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#logTo(Level,Logger) logTo(Level,Logger)}
+ * 		<li class='jm'>{@link RestClientBuilder#logToConsole() logToConsole()}
+ * 	</ul>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#logTo(Level,Logger) logTo(Level,Logger)}
+ * 		<li class='jm'>{@link RestRequest#logToConsole() logToConsole()}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='notes w900'>
+ * It should be noted that if you enable logging, response bodies will be cached by default which may introduce
+ * a performance penalty.
+ *
+ * <p class='w900'>
+ * Additionally, the following method is also provided for enabling debug mode:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#debug() debug()}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Enabling debug mode has the following effects:
+ * <ul>
+ * 	<li>{@link BeanContext#BEAN_debug} is enabled.
+ * 	<li>{@link #RESTCLIENT_leakDetection} is enabled.
+ * 	<li>{@link RestClientBuilder#logToConsole()} is called.
+ * </ul>
+ *
+ *
+ * <h4 class='topic'>Interceptors</h4>
+ *
+ * <p class='w900'>
+ * The {@link RestCallInterceptor} API provides a quick way of intercepting and manipulating requests and responses.
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClientBuilder}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestClientBuilder#interceptors(RestCallInterceptor...) interceptors(RestCallInterceptor...)}
+ * 	</ul>
+ * 	<li class='jc'>{@link RestRequest}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestRequest#interceptors(RestCallInterceptor...) interceptors(RestCallInterceptor...)}
+ * 	</ul>
+ * 	<li class='jic'>{@link RestCallInterceptor}
+ * 	<ul>
+ * 		<li class='jm'>{@link RestCallInterceptor#onInit(RestRequest) onInit(RestRequest)}
+ * 		<li class='jm'>{@link RestCallInterceptor#onConnect(RestRequest,RestResponse) onConnect(RestRequest,RestResponse)}
+ * 		<li class='jm'>{@link RestCallInterceptor#onClose(RestRequest,RestResponse) onClose(RestRequest,RestResponse)}
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Note that the {@link HttpRequestInterceptor} and {@link HttpResponseInterceptor} classes can also be used for
+ * intercepting requests.
+ *
+ *
+ * <h4 class='topic'>REST Proxies</h4>
+ *
+ * <p class='w900'>
+ * One of the more powerful features of the REST client class is the ability to produce Java interface proxies against
+ * arbitrary remote REST resources.
+ *
+ * <h5 class='figure'>Example:</h5>
+ * <p class='bcode w800'>
+ * 	<jc>// Define a Remote proxy for interacting with a REST interface.</jc>
+ * 	<ja>@Remote</ja>(path=<js>"/petstore"</js>)
+ * 	<jk>public interface</jk> PetStore {
+ * 		<ja>@RemoteMethod</ja>(httpMethod=<jsf>POST</jsf>, path=<js>"/pets"</js>)
+ * 		Pet addPet(
+ * 			<ja>@Body</ja> CreatePet pet,
+ * 			<ja>@Header</ja>(<js>"E-Tag"</js>) UUID etag,
+ * 			<ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> debug
+ * 		);
+ * 	}
+ *
+ * 	<jc>// Use a RestClient with default Simple JSON support.</jc>
+ * 	<jk>try</jk> (RestClient c = RestClient.<jsm>create</jsm>().simpleJson().build()) {
+ * 		PetStore store = c.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
+ * 		CreatePet cp = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
+ * 		Pet p = store.addPet(cp, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
+ * 	}
+ * </p>
+ *
+ * <p class='w900'>
+ * The methods to retrieve remote interfaces are:
+ *
+ * <ul class='javatree'>
+ * 	<li class='jc'>{@link RestClient}
+ * 	<ul>
+ * 		<li class='jm'><c>{@link RestClient#getRemote(Class) getRemote(Class&lt;T&gt;)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestClient#getRemote(Class,Object) getRemote(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestClient#getRrpcInterface(Class) getRrpcInterface(Class&lt;T&gt;)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
+ * 		<li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
+ * 	</ul>
+ * </ul>
+ *
+ * <p class='w900'>
+ * Two basic types of remote interfaces are provided:
+ *
+ * <ul class='spaced-list'>
+ * 	<li>{@link Remote @Remote}-annotated interfaces.  These can be defined against arbitrary external REST resources.
+ * 	<li>RPC-over-REST interfaces.  These are Java interfaces that allow you to make method calls on server-side POJOs.
+ * </ul>
+ *
+ * <p class='w900'>
+ * Refer to the following documentation on both flavors:
+ *
+ * <ul class='doctree'>
+ * 	<li class='link'>{@doc juneau-rest-client.RestProxies}
+ * 	<li class='link'>{@doc juneau-rest-server.restRPC}
+ * </ul>
+ *
+ * <br>
+ * <hr class='w900'>
+ *
+ * <ul class='seealso'>
+ * 	<li class='link'>{@doc juneau-rest-client}
+ * </ul>
+ */
+@ConfigurableContext(nocache=true)
+public class RestClient extends BeanContext implements HttpClient, Closeable {
+
+	//-------------------------------------------------------------------------------------------------------------------
+	// Configurable properties
+	//-------------------------------------------------------------------------------------------------------------------
+
+	private static final String PREFIX = "RestClient.";
+
+	/**
+	 * Configuration property:  REST call handler.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_callHandler RESTCLIENT_callHandler}
+	 * 	<li><b>Name:</b>  <js>"RestClient.callHandler.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link org.apache.juneau.rest.client2.RestCallHandler}&gt;
+	 * 			<li>{@link org.apache.juneau.rest.client2.RestCallHandler}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  <c><jk>null</jk></c>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#callHandler(Class)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#callHandler(RestCallHandler)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Allows you to provide a custom handler for making HTTP calls.
+	 */
+	public static final String RESTCLIENT_callHandler = PREFIX + "callHandler.o";
+
+	/**
+	 * Configuration property:  Debug.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_debug RESTCLIENT_debug}
+	 * 	<li><b>Name:</b>  <js>"RestClient.debug.b"</js>
+	 * 	<li><b>Data type:</b>  <jk>boolean</jk>
+	 * 	<li><b>System property:</b>  <c>RestClient.debug</c>
+	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_DEBUG</c>
+	 * 	<li><b>Default:</b>  <jk>false</jk>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#debug()}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Enable debug mode.
+	 *
+	 * <p>
+	 * Has the following effects:
+	 * <ul class='spaced-list'>
+	 * 	<li>{@link BeanContext#BEAN_debug} is enabled.
+	 * 	<li>{@link #RESTCLIENT_leakDetection} is enabled.
+	 * 	<li>{@link RestClientBuilder#logToConsole()} is called.
+	 * </ul>
+	 */
+	public static final String RESTCLIENT_debug = PREFIX + "debug.b";
+
+	/**
+	 * Configuration property:  Error codes predicate.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_errorCodes RESTCLIENT_errorCodes}
+	 * 	<li><b>Name:</b>  <js>"RestClient.errorCodes.o"</js>
+	 * 	<li><b>Data type:</b>  {@link java.util.function.Predicate}&lt;{@link java.lang.Integer}&gt;
+	 * 	<li><b>Default:</b>  <code>x -&gt; x&gt;=400</code>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#errorCodes(Predicate)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#errorCodes(Predicate)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Defines the predicate used to determine which response status codes are considered errors.
+	 */
+	public static final String RESTCLIENT_errorCodes = PREFIX + "errorCodes.o";
+
+	/**
+	 * Configuration property:  Executor service.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_executorService RESTCLIENT_executorService}
+	 * 	<li><b>Name:</b>  <js>"RestClient.executorService.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link java.util.concurrent.ExecutorService}&gt;</c>
+	 * 			<li>{@link java.util.concurrent.ExecutorService}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  <jk>null</jk>.
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#executorService(ExecutorService, boolean)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Defines the executor service to use when calling future methods on the {@link RestRequest} class.
+	 *
+	 * <p>
+	 * This executor service is used to create {@link Future} objects on the following methods:
+	 * <ul>
+	 * 	<li>{@link RestRequest#runFuture()}
+	 * </ul>
+	 *
+	 * <p>
+	 * The default executor service is a single-threaded {@link ThreadPoolExecutor} with a 30 second timeout
+	 * and a queue size of 10.
+	 */
+	public static final String RESTCLIENT_executorService = PREFIX + "executorService.o";
+
+	/**
+	 * Configuration property:  Shut down executor service on close.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_executorServiceShutdownOnClose RESTCLIENT_executorServiceShutdownOnClose}
+	 * 	<li><b>Name:</b>  <js>"RestClient.executorServiceShutdownOnClose.b"</js>
+	 * 	<li><b>Data type:</b>  <jk>boolean</jk>
+	 * 	<li><b>System property:</b>  <c>RestClient.executorServiceShutdownOnClose</c>
+	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_EXECUTORSERVICESHUTDOWNONCLOSE</c>
+	 * 	<li><b>Default:</b>  <jk>false</jk>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#executorService(ExecutorService, boolean)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Call {@link ExecutorService#shutdown()} when {@link RestClient#close()} is called.
+	 */
+	public static final String RESTCLIENT_executorServiceShutdownOnClose = PREFIX + "executorServiceShutdownOnClose.b";
+
+	/**
+	 * Configuration property:  Request form-data parameters.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_formData RESTCLIENT_formData}
+	 * 	<li><b>Name:</b>  <js>"RestClient.formData.lo"</js>
+	 * 	<li><b>Data type:</b>  <c>List&lt;{@link org.apache.http.NameValuePair}&gt;</c>
+	 * 	<li><b>Default:</b>  empty map
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestClientBuilder}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(Map) formData(Map<String, Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(NameValuePair) formData(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(NameValuePair...) formData(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(NameValuePairs) formData(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(Object...) formData(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(ObjectMap) formData(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(String,Object) formData(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#formData(String,Object,HttpPartSerializer,HttpPartSchema) formData(String,Object,HttpPartSerializer,HttpPartSchema)}
+	 * 			</ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestRequest}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(CharSequence) formData(CharSequence)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(InputStream) formData(InputStream)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(Map) formData(Map<String,Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(NameValuePair) formData(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(NameValuePair,boolean) formData(NameValuePair,boolean)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(NameValuePair...) formData(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(NameValuePairs) formData(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(Object) formData(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(Object...) formData(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(ObjectMap) formData(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(Reader) formData(Reader)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(String,Object) formData(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#formData(String,Object,boolean,HttpPartSerializer,HttpPartSchema) formData(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+	 * 			</ul>
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Query parameters to add to every request.
+	 */
+	public static final String RESTCLIENT_formData = PREFIX + "formData.smo";
+
+	/**
+	 * Configuration property:  Request headers.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_headers RESTCLIENT_headers}
+	 * 	<li><b>Name:</b>  <js>"RestClient.headers.lo"</js>
+	 * 	<li><b>Data type:</b>  <c>List&lt;{@link org.apache.http.Header} | {@link org.apache.juneau.http.HttpHeader} | {@link org.apache.http.NameValuePair}&gt;</c>
+	 * 	<li><b>Default:</b>  empty map
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestClientBuilder}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#header(Header) header(Header)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#header(HttpHeader) header(HttpHeader)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#header(NameValuePair) header(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#header(String,Object) header(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#header(String,Object,HttpPartSerializer,HttpPartSchema) header(String,Object,HttpPartSerializer,HttpPartSchema)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(Header...) headers(Header...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(HttpHeader...) headers(HttpHeader...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(Map) headers(Map<String,Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(NameValuePair...) headers(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(NameValuePairs) headers(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(Object...) headers(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#headers(ObjectMap) headers(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#accept(Object) accept(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#acceptCharset(Object) acceptCharset(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#acceptEncoding(Object) acceptEncoding(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#acceptLanguage(Object) acceptLanguage(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#authorization(Object) authorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#cacheControl(Object) cacheControl(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#clientVersion(Object) clientVersion(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#connection(Object) connection(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#contentLength(Object) contentLength(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#contentType(Object) contentType(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#date(Object) date(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#expect(Object) expect(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#forwarded(Object) forwarded(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#from(Object) from(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#host(Object) host(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#ifMatch(Object) ifMatch(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#ifModifiedSince(Object) ifModifiedSince(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#ifNoneMatch(Object) ifNoneMatch(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#ifRange(Object) ifRange(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#maxForwards(Object) maxForwards(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#origin(Object) origin(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#pragma(Object) pragma(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#proxyAuthorization(Object) proxyAuthorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#range(Object) proxyAuthorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#referer(Object) referer(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#te(Object) te(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#userAgent(Object) userAgent(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#upgrade(Object) upgrade(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#via(Object) via(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#warning(Object) warning(Object)}
+	 * 			</ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestRequest}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(Header) header(Header)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(Header,boolean) header(Header,boolean)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(HttpHeader) header(HttpHeader)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(NameValuePair) header(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(NameValuePair,boolean) header(NameValuePair,boolean)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(String,Object) header(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#header(String,Object,boolean,HttpPartSerializer,HttpPartSchema) header(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(Header...) headers(Header...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(HttpHeader...) headers(HttpHeader...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(Map) headers(Map<String,Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(NameValuePair...) headers(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(NameValuePairs) headers(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(Object) headers(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(Object...) headers(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#headers(ObjectMap) headers(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#accept(Object) accept(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#acceptCharset(Object) acceptCharset(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#acceptEncoding(Object) acceptEncoding(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#acceptLanguage(Object) acceptLanguage(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#authorization(Object) authorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#cacheControl(Object) cacheControl(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#clientVersion(Object) clientVersion(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#connection(Object) connection(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#contentLength(Object) contentLength(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#contentType(Object) contentType(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#date(Object) date(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#expect(Object) expect(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#forwarded(Object) forwarded(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#from(Object) from(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#host(Object) host(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#ifMatch(Object) ifMatch(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#ifModifiedSince(Object) ifModifiedSince(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#ifNoneMatch(Object) ifNoneMatch(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#ifRange(Object) ifRange(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#maxForwards(Object) maxForwards(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#origin(Object) origin(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#pragma(Object) pragma(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#proxyAuthorization(Object) proxyAuthorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#range(Object) proxyAuthorization(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#referer(Object) referer(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#te(Object) te(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#userAgent(Object) userAgent(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#upgrade(Object) upgrade(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#via(Object) via(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#warning(Object) warning(Object)}
+	 * 			</ul>
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Headers to add to every request.
+	 */
+	public static final String RESTCLIENT_headers = PREFIX + "headers.smo";
+
+	/**
+	 * Configuration property:  Call interceptors.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_interceptors RESTCLIENT_interceptors}
+	 * 	<li><b>Name:</b>  <js>"RestClient.interceptors.lo"</js>
+	 * 	<li><b>Data type:</b>  <c>List&lt;Class&lt;{@link org.apache.juneau.rest.client2.RestCallInterceptor}&gt; | {@link org.apache.juneau.rest.client2.RestCallInterceptor}&gt;&gt;</c>
+	 * 	<li><b>Default:</b>  empty list.
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#interceptors(Class...)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#interceptors(RestCallInterceptor...)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Interceptors that get called immediately after a connection is made.
+	 */
+	public static final String RESTCLIENT_interceptors = PREFIX + "interceptors.so";
+
+	/**
+	 * Add to the Call interceptors property.
+	 */
+	public static final String RESTCLIENT_interceptors_add = PREFIX + "interceptors.so/add";
+
+	/**
+	 * Configuration property:  Keep HttpClient open.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_keepHttpClientOpen RESTCLIENT_keepHttpClientOpen}
+	 * 	<li><b>Name:</b>  <js>"RestClient.keepHttpClientOpen.b"</js>
+	 * 	<li><b>Data type:</b>  <jk>boolean</jk>
+	 * 	<li><b>System property:</b>  <c>RestClient.keepHttpClientOpen</c>
+	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_KEEPHTTPCLIENTOPEN</c>
+	 * 	<li><b>Default:</b>  <jk>false</jk>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#keepHttpClientOpen(boolean)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Don't close this client when the {@link RestClient#close()} method is called.
+	 */
+	public static final String RESTCLIENT_keepHttpClientOpen = PREFIX + "keepHttpClientOpen.b";
+
+	/**
+	 * Configuration property:  Enable leak detection.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_leakDetection RESTCLIENT_leakDetection}
+	 * 	<li><b>Name:</b>  <js>"RestClient.leakDetection.b"</js>
+	 * 	<li><b>Data type:</b>  <jk>boolean</jk>
+	 * 	<li><b>System property:</b>  <c>RestClient.leakDetection</c>
+	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_LEAKDETECTION</c>
+	 * 	<li><b>Default:</b>  <jk>false</jk>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#leakDetection()}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#leakDetection(boolean)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Enable client and request/response leak detection.
+	 *
+	 * <p>
+	 * Causes messages to be logged to the console if clients or request/response objects are not properly closed
+	 * when the <c>finalize</c> methods are invoked.
+	 *
+	 * <p>
+	 * Automatically enabled with {@link #RESTCLIENT_debug}.
+	 */
+	public static final String RESTCLIENT_leakDetection = PREFIX + "leakDetection.b";
+
+	/**
+	 * Configuration property:  Parser.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_parser RESTCLIENT_parser}
+	 * 	<li><b>Name:</b>  <js>"RestClient.parser.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link org.apache.juneau.parser.Parser}&gt;</c>
+	 * 			<li>{@link org.apache.juneau.parser.Parser}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  {@link org.apache.juneau.json.JsonParser};
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#parser(Class)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#parser(Parser)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * The parser to use for parsing POJOs in response bodies.
+	 */
+	public static final String RESTCLIENT_parser = PREFIX + "parser.o";
+
+	/**
+	 * Configuration property:  Part parser.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_partParser RESTCLIENT_partParser}
+	 * 	<li><b>Name:</b>  <js>"RestClient.partParser.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link org.apache.juneau.httppart.HttpPartParser}&gt;</c>
+	 * 			<li>{@link org.apache.juneau.httppart.HttpPartParser}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  {@link org.apache.juneau.oapi.OpenApiParser};
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#partParser(Class)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#partParser(HttpPartParser)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * The parser to use for parsing POJOs from form data, query parameters, headers, and path variables.
+	 */
+	public static final String RESTCLIENT_partParser = PREFIX + "partParser.o";
+
+	/**
+	 * Configuration property:  Part serializer.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_partSerializer RESTCLIENT_partSerializer}
+	 * 	<li><b>Name:</b>  <js>"RestClient.partSerializer.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link org.apache.juneau.httppart.HttpPartSerializer}&gt;</c>
+	 * 			<li>{@link org.apache.juneau.httppart.HttpPartSerializer}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  {@link org.apache.juneau.oapi.OpenApiSerializer};
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#partSerializer(Class)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#partSerializer(HttpPartSerializer)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
+	 */
+	public static final String RESTCLIENT_partSerializer = PREFIX + "partSerializer.o";
+
+	/**
+	 * Configuration property:  Request query parameters.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_query RESTCLIENT_query}
+	 * 	<li><b>Name:</b>  <js>"RestClient.query.lo"</js>
+	 * 	<li><b>Data type:</b>  <c>List&lt;{@link org.apache.http.NameValuePair}&gt;</c>
+	 * 	<li><b>Default:</b>  empty map
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestClientBuilder}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(Map) query(Map<String,Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(NameValuePair) query(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(NameValuePair...) query(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(NameValuePairs) query(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(Object...) query(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(ObjectMap) query(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(String,Object) query(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#query(String,Object,HttpPartSerializer,HttpPartSchema) query(String,Object,HttpPartSerializer,HttpPartSchema)}
+	 * 			</ul>
+	 * 			<li class='jc'>{@link org.apache.juneau.rest.client2.RestRequest}
+	 * 			<ul>
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(Map) query(Map<String,Object>)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(NameValuePair) query(NameValuePair)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(NameValuePair,boolean) query(NameValuePair,boolean)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(NameValuePair...) query(NameValuePair...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(NameValuePairs) query(NameValuePairs)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(Object) query(Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(Object...) query(Object...)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(ObjectMap) query(ObjectMap)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(String) query(String)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(String,Object) query(String,Object)}
+	 * 				<li class='jm'>{@link org.apache.juneau.rest.client2.RestRequest#query(String,Object,boolean,HttpPartSerializer,HttpPartSchema) query(String,Object,boolean,HttpPartSerializer,HttpPartSchema)}
+	 * 			</ul>
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * Query parameters to add to every request.
+	 */
+	public static final String RESTCLIENT_query = PREFIX + "query.smo";
+
+	/**
+	 * Configuration property:  Root URI.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_rootUri RESTCLIENT_rootUri}
+	 * 	<li><b>Name:</b>  <js>"RestClient.rootUri.s"</js>
+	 * 	<li><b>Data type:</b>  <c>String</c>
+	 * 	<li><b>System property:</b>  <c>RestClient.rootUri</c>
+	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_ROOTURI</c>
+	 * 	<li><b>Default:</b>  <jk>false</jk>
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#rootUrl(Object)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * When set, relative URL strings passed in through the various rest call methods (e.g. {@link RestClient#get(Object)}
+	 * will be prefixed with the specified root.
+	 * <br>This root URL is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URL string.
+	 * <br>Trailing slashes are trimmed.
+	 */
+	public static final String RESTCLIENT_rootUri = PREFIX + "rootUri.s";
+
+	/**
+	 * Configuration property:  Serializer.
+	 *
+	 * <h5 class='section'>Property:</h5>
+	 * <ul class='spaced-list'>
+	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client2.RestClient#RESTCLIENT_serializer RESTCLIENT_serializer}
+	 * 	<li><b>Name:</b>  <js>"RestClient.serializer.o"</js>
+	 * 	<li><b>Data type:</b>
+	 * 		<ul>
+	 * 			<li><c>Class&lt;? <jk>extends</jk> {@link org.apache.juneau.serializer.Serializer}&gt;</c>
+	 * 			<li>{@link org.apache.juneau.serializer.Serializer}
+	 * 		</ul>
+	 * 	<li><b>Default:</b>  {@link org.apache.juneau.json.JsonSerializer};
+	 * 	<li><b>Methods:</b>
+	 * 		<ul>
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#serializer(Class)}
+	 * 			<li class='jm'>{@link org.apache.juneau.rest.client2.RestClientBuilder#serializer(Serializer)}
+	 * 		</ul>
+	 * </ul>
+	 *
+	 * <h5 class='section'>Description:</h5>
+	 * <p>
+	 * The serializer to use for serializing POJOs in request bodies.
+	 */
+	public static final String RESTCLIENT_serializer = PREFIX + "serializer.o";
+
+	private static final Set<String> NO_BODY_METHODS = Collections.unmodifiableSet(ASet.<String>create("GET","HEAD","DELETE","CONNECT","OPTIONS","TRACE"));
+
+	private final List<Object> headers, query, formData;
+	private final HttpClientBuilder httpClientBuilder;
+	private final CloseableHttpClient httpClient;
+	private final boolean keepHttpClientOpen, debug, leakDetection;
+	private final UrlEncodingSerializer urlEncodingSerializer;  // Used for form posts only.
+	private final HttpPartSerializer partSerializer;
+	private final HttpPartParser partParser;
+	private final RestCallHandler callHandler;
+	private final String rootUrl;
+	private volatile boolean isClosed = false;
+	private final StackTraceElement[] creationStack;
+	private StackTraceElement[] closedStack;
+
+	// These are read directly by RestCall.
+	final Serializer serializer;
+	final Parser parser;
+	Predicate<Integer> errorCodes;
+
+	final RestCallInterceptor[] interceptors;
+
+	// This is lazy-created.
+	private volatile ExecutorService executorService;
+	private final boolean executorServiceShutdownOnClose;
+
+	/**
+	 * Instantiates a new clean-slate {@link RestClientBuilder} object.
+	 *
+	 * @return A new {@link RestClientBuilder} object.
+	 */
+	public static RestClientBuilder create() {
+		return new RestClientBuilder(PropertyStore.DEFAULT, null);
+	}
+
+	/**
+	 * Instantiates a new {@link RestClientBuilder} object using the specified serializer and parser.
+	 *
+	 * <p>
+	 * Shortcut for calling <code>RestClient.<jsm>create</jsm>().serializer(s).parser(p);</code>
+	 *
+	 * @param s The serializer to use for output.
+	 * @param p The parser to use for input.
+	 * @return A new {@link RestClientBuilder} object.
+	 */
+	public static RestClientBuilder create(Serializer s, Parser p) {
+		return create().serializer(s).parser(p);
+	}
+
+	/**
+	 * Instantiates a new {@link RestClientBuilder} object using the specified serializer and parser.
+	 *
+	 * <p>
+	 * Shortcut for calling <code>RestClient.<jsm>create</jsm>().serializer(s).parser(p);</code>
+	 *
+	 * @param s The serializer class to use for output.
+	 * @param p The parser class to use for input.
+	 * @return A new {@link RestClientBuilder} object.
+	 */
+	public static RestClientBuilder create(Class<? extends Serializer> s, Class<? extends Parser> p) {
+		return create().serializer(s).parser(p);
+	}
+
+	@Override /* Context */
+	public RestClientBuilder builder() {
+		return new RestClientBuilder(getPropertyStore(), httpClientBuilder);
+	}
+
+	private static final
+		Predicate<Integer> ERROR_CODES_DEFAULT = x ->  x>=400;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param builder The REST client builder.
+	 */
+	@SuppressWarnings("unchecked")
+	protected RestClient(RestClientBuilder builder) {
+		super(builder.getPropertyStore());
+		PropertyStore ps = getPropertyStore();
+		this.httpClientBuilder = builder.getHttpClientBuilder();
+		this.httpClient = builder.getHttpClient();
+		this.keepHttpClientOpen = getBooleanProperty(RESTCLIENT_keepHttpClientOpen, false);
+		this.errorCodes = getInstanceProperty(RESTCLIENT_errorCodes, Predicate.class, ERROR_CODES_DEFAULT);
+		this.debug = getBooleanProperty(RESTCLIENT_debug, false);
+		this.executorServiceShutdownOnClose = getBooleanProperty(RESTCLIENT_executorServiceShutdownOnClose, false);
+		this.rootUrl = StringUtils.nullIfEmpty(getStringProperty(RESTCLIENT_rootUri, "").replaceAll("\\/$", ""));
+		this.leakDetection = getBooleanProperty(RESTCLIENT_leakDetection, debug);
+
+		Object o = getProperty(RESTCLIENT_serializer, Object.class, null);
+		if (o instanceof Serializer) {
+			this.serializer = ((Serializer)o).builder().apply(ps).build();
+		} else if (o instanceof Class) {
+			this.serializer = ContextCache.INSTANCE.create((Class<? extends Serializer>)o, ps);
+		} else {
+			this.serializer = null;
+		}
+
+		o = getProperty(RESTCLIENT_parser, Object.class, null);
+		if (o instanceof Parser) {
+			this.parser = ((Parser)o).builder().apply(ps).build();
+		} else if (o instanceof Class) {
+			this.parser = ContextCache.INSTANCE.create((Class<? extends Parser>)o, ps);
+		} else {
+			this.parser = null;
+		}
+
+		this.urlEncodingSerializer = new SerializerBuilder(ps).build(UrlEncodingSerializer.class);
+		this.partSerializer = getInstanceProperty(RESTCLIENT_partSerializer, HttpPartSerializer.class, OpenApiSerializer.class, ResourceResolver.FUZZY, ps);
+		this.partParser = getInstanceProperty(RESTCLIENT_partParser, HttpPartParser.class, OpenApiParser.class, ResourceResolver.FUZZY, ps);
+		this.executorService = getInstanceProperty(RESTCLIENT_executorService, ExecutorService.class, null);
+
+		Function<Object,Object> f = x -> x instanceof SerializedNameValuePair.Builder ? ((SerializedNameValuePair.Builder)x).serializer(partSerializer, false).build() : x;
+
+		this.headers = Collections.unmodifiableList(
+			getMapProperty(RESTCLIENT_headers, Object.class)
+				.values()
+				.stream()
+				.map(f)
+				.collect(Collectors.toList())
+		);
+
+		this.query = Collections.unmodifiableList(
+			getMapProperty(RESTCLIENT_query, Object.class)
+				.values()
+				.stream()
+				.map(f)
+				.collect(Collectors.toList())
+		);
+
+		this.formData = Collections.unmodifiableList(
+			getMapProperty(RESTCLIENT_formData, Object.class)
+				.values()
+				.stream()
+				.map(f)
+				.collect(Collectors.toList())
+		);
+
+		RestCallHandler callHandler = getInstanceProperty(RESTCLIENT_callHandler, RestCallHandler.class, null);
+		if (callHandler == null) {
+			callHandler = new RestCallHandler() {
+				@Override
+				public HttpResponse execute(HttpHost target, HttpEntityEnclosingRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+					return target == null ? RestClient.this.execute(request, context) : RestClient.this.execute(target, (HttpRequest)request, context);
+				}
+
+				@Override
+				public HttpResponse execute(HttpHost target, HttpRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+					return target == null ? RestClient.this.execute(request, context) : RestClient.this.execute(target, (HttpRequest)request, context);
+				}
+			};
+		}
+		this.callHandler = callHandler;
+
+		RestCallInterceptor[] rci = getInstanceArrayProperty(RESTCLIENT_interceptors, RestCallInterceptor.class, new RestCallInterceptor[0]);
+		if (debug)
+			rci = ArrayUtils.append(rci, new ConsoleRestCallLogger());
+		this.interceptors = rci;
+
+		creationStack = debug ? Thread.currentThread().getStackTrace() : null;
+	}
+
+	/**
+	 * Returns <jk>true</jk> if specified http method has content.
+	 * <p>
+	 * By default, anything not in this list can have content:  <c>GET, HEAD, DELETE, CONNECT, OPTIONS, TRACE</c>.
+	 *
+	 * @param httpMethod The HTTP method.  Must be upper-case.
+	 * @return <jk>true</jk> if specified http method has content.
+	 */
+	protected boolean hasContent(String httpMethod) {
+		return ! NO_BODY_METHODS.contains(httpMethod);
+	}
+
+	/**
+	 * Calls {@link CloseableHttpClient#close()} on the underlying {@link CloseableHttpClient}.
+	 *
+	 * <p>
+	 * It's good practice to call this method after the client is no longer used.
+	 *
+	 * @throws IOException Thrown by underlying stream.
+	 */
+	@Override
+	public void close() throws IOException {
+		isClosed = true;
+		if (httpClient != null && ! keepHttpClientOpen)
+			httpClient.close();
+		if (executorService != null && executorServiceShutdownOnClose)
+			executorService.shutdown();
+		if (creationStack != null)
+			closedStack = Thread.currentThread().getStackTrace();
+	}
+
+	/**
+	 * Same as {@link #close()}, but ignores any exceptions.
+	 */
+	public void closeQuietly() {
+		isClosed = true;
+		try {
+			if (httpClient != null && ! keepHttpClientOpen)
+				httpClient.close();
+			if (executorService != null && executorServiceShutdownOnClose)
+				executorService.shutdown();
+		} catch (Throwable t) {}
+		if (creationStack != null)
+			closedStack = Thread.currentThread().getStackTrace();
+	}
+
+	/**
+	 * Execute the specified no-body request (e.g. GET/DELETE).
+	 *
+	 * <p>
+	 * Subclasses can override this method to provide specialized handling.
+	 *
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	protected HttpResponse execute(HttpHost target, HttpRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+		return callHandler.execute(target, request, context);
+	}
+
+	/**
+	 * Execute the specified body request (e.g. POST/PUT).
+	 *
+	 * <p>
+	 * Subclasses can override this method to provide specialized handling.
+	 *
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	protected HttpResponse execute(HttpHost target, HttpEntityEnclosingRequestBase request, HttpContext context) throws ClientProtocolException, IOException {
+		return callHandler.execute(target, request, context);
+	}
+
+	/**
+	 * Perform a <c>GET</c> request against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest get(Object url) throws RestCallException {
+		return request("GET", url, false);
+	}
+
+	/**
+	 * Perform a <c>PUT</c> request against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param body
+	 * 	The object to serialize and transmit to the URL as the body of the request.
+	 * 	Can be of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>
+	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link ReaderResource} - Raw contents of {@code Reader} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link StreamResource} - Raw contents of {@code InputStream} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
+	 * 			{@link RestClient}.
+	 * 		<li class='jc'>
+	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
+	 * 		<li class='jc'>
+	 * 			{@link NameValuePairs} - Converted to a URL-encoded FORM post.
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request
+	 * 	and getting the response as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest put(Object url, Object body) throws RestCallException {
+		return request("PUT", url, true).body(body);
+	}
+
+	/**
+	 * Same as {@link #put(Object, Object)} but don't specify the input yet.
+	 *
+	 * <p>
+	 * You must call either {@link RestRequest#body(Object)} or {@link RestRequest#formData(String, Object)}
+	 * to set the contents on the result object.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException REST call failed.
+	 */
+	public RestRequest put(Object url) throws RestCallException {
+		return request("PUT", url, true);
+	}
+
+	/**
+	 * Perform a <c>POST</c> request against the specified URL.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
+	 * </ul>
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param body
+	 * 	The object to serialize and transmit to the URL as the body of the request.
+	 * 	Can be of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>
+	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link ReaderResource} - Raw contents of {@code Reader} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link StreamResource} - Raw contents of {@code InputStream} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
+	 * 			{@link RestClient}.
+	 * 		<li class='jc'>
+	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
+	 * 		<li class='jc'>
+	 * 			{@link NameValuePairs} - Converted to a URL-encoded FORM post.
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest post(Object url, Object body) throws RestCallException {
+		return request("POST", url, true).body(body);
+	}
+
+	/**
+	 * Same as {@link #post(Object, Object)} but don't specify the input yet.
+	 *
+	 * <p>
+	 * You must call either {@link RestRequest#body(Object)} or {@link RestRequest#formData(String, Object)} to set the
+	 * contents on the result object.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
+	 * </ul>
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException REST call failed.
+	 */
+	public RestRequest post(Object url) throws RestCallException {
+		return request("POST", url, true);
+	}
+
+	/**
+	 * Perform a <c>DELETE</c> request against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest delete(Object url) throws RestCallException {
+		return request("DELETE", url, false);
+	}
+
+	/**
+	 * Perform an <c>OPTIONS</c> request against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest options(Object url) throws RestCallException {
+		return request("OPTIONS", url, true);
+	}
+
+	/**
+	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
+	 * against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param body
+	 * 	The object to serialize and transmit to the URL as the body of the request.
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link HttpEntity} - Serialized directly.
+	 * 		<li class='jc'>{@link Object} - Converted to a {@link SerializedHttpEntity} using {@link UrlEncodingSerializer} to serialize.
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest formPost(Object url, Object body) throws RestCallException {
+		return request("POST", url, true)
+			.body(body instanceof HttpEntity ? body : new SerializedHttpEntity(body, urlEncodingSerializer, null));
+	}
+
+	/**
+	 * Same as {@link #formPost(Object, Object)} but doesn't specify the input yet.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest formPost(Object url) throws RestCallException {
+		return request("POST", url, true);
+	}
+
+	/**
+	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
+	 * against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param parameters
+	 * 	The parameters of the form post.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest formPost(Object url, NameValuePairs parameters) throws RestCallException {
+		try {
+			return request("POST", url, true).body(new UrlEncodedFormEntity(parameters));
+		} catch (UnsupportedEncodingException e) {
+			throw new RestCallException(e);
+		}
+	}
+
+	/**
+	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
+	 * against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param parameters
+	 * 	The parameters of the form post.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest formPost(Object url, NameValuePair...parameters) throws RestCallException {
+		return formPost(url, new NameValuePairs(parameters));
+	}
+
+	/**
+	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
+	 * against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param parameters
+	 * 	The parameters of the form post.
+	 * 	<br>The parameters represent name/value pairs and must be an even number of arguments.
+	 * 	<br>Parameters are converted to {@link SimpleNameValuePair} objects.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest formPost(Object url, Object...parameters) throws RestCallException {
+		return formPost(url, new NameValuePairs(parameters));
+	}
+
+	/**
+	 * Perform a <c>PATCH</c> request against the specified URL.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param body
+	 * 	The object to serialize and transmit to the URL as the body of the request.
+	 * 	Can be of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>
+	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link ReaderResource} - Raw contents of {@code Reader} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link StreamResource} - Raw contents of {@code InputStream} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
+	 * 			{@link RestClient}.
+	 * 		<li class='jc'>
+	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
+	 * 		<li class='jc'>
+	 * 			{@link NameValuePairs} - Converted to a URL-encoded FORM post.
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest patch(Object url, Object body) throws RestCallException {
+		return request("PATCH", url, true).body(body);
+	}
+
+	/**
+	 * Same as {@link #patch(Object, Object)} but don't specify the input yet.
+	 *
+	 * <p>
+	 * You must call {@link RestRequest#body(Object)} to set the contents on the result object.
+	 *
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException REST call failed.
+	 */
+	public RestRequest patch(Object url) throws RestCallException {
+		return request("PATCH", url, true);
+	}
+
+
+	/**
+	 * Performs a REST call where the entire call is specified in a simple string.
+	 *
+	 * <p>
+	 * This method is useful for performing callbacks when the target of a callback is passed in
+	 * on an initial request, for example to signal when a long-running process has completed.
+	 *
+	 * <p>
+	 * The call string can be any of the following formats:
+	 * <ul class='spaced-list'>
+	 * 	<li>
+	 * 		<js>"[method] [url]"</js> - e.g. <js>"GET http://localhost/callback"</js>
+	 * 	<li>
+	 * 		<js>"[method] [url] [payload]"</js> - e.g. <js>"POST http://localhost/callback some text payload"</js>
+	 * 	<li>
+	 * 		<js>"[method] [headers] [url] [payload]"</js> - e.g. <js>"POST {'Content-Type':'text/json'} http://localhost/callback {'some':'json'}"</js>
+	 * </ul>
+	 * <p>
+	 * The payload will always be sent using a simple {@link StringEntity}.
+	 *
+	 * @param callString The call string.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException REST call failed.
+	 */
+	public RestRequest callback(String callString) throws RestCallException {
+		String s = callString;
+		try {
+			RestRequest rc = null;
+			String method = null, uri = null, content = null;
+			ObjectMap h = null;
+			int i = s.indexOf(' ');
+			if (i != -1) {
+				method = s.substring(0, i).trim();
+				s = s.substring(i).trim();
+				if (s.length() > 0) {
+					if (s.charAt(0) == '{') {
+						i = s.indexOf('}');
+						if (i != -1) {
+							String json = s.substring(0, i+1);
+							h = JsonParser.DEFAULT.parse(json, ObjectMap.class);
+							s = s.substring(i+1).trim();
+						}
+					}
+					if (s.length() > 0) {
+						i = s.indexOf(' ');
+						if (i == -1)
+							uri = s;
+						else {
+							uri = s.substring(0, i).trim();
+							s = s.substring(i).trim();
+							if (s.length() > 0)
+								content = s;
+						}
+					}
+				}
+			}
+			if (method != null && uri != null) {
+				rc = request(method, uri, content != null);
+				if (content != null)
+					rc.body(new StringEntity(content));
+				if (h != null)
+					for (Map.Entry<String,Object> e : h.entrySet())
+						rc.header(e.getKey(), e.getValue());
+				return rc;
+			}
+		} catch (Exception e) {
+			throw new RestCallException(e);
+		}
+		throw new RestCallException("Invalid format for call string.");
+	}
+
+	/**
+	 * Perform a generic REST call.
+	 *
+	 * @param method The HTTP method.
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param body
+	 * 	The HTTP body content.
+	 * 	Can be of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>
+	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
+	 * 		<li class='jc'>
+	 * 			{@link ReaderResource} - Raw contents of {@code Reader} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link StreamResource} - Raw contents of {@code InputStream} will be serialized to remote resource.  Additional headers and media type will be set on request.
+	 * 		<li class='jc'>
+	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
+	 * 			{@link RestClient}.
+	 * 		<li class='jc'>
+	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
+	 * 		<li class='jc'>
+	 * 			{@link NameValuePairs} - Converted to a URL-encoded FORM post.
+	 * 	</ul>
+	 * 	This parameter is IGNORED if {@link HttpMethod#hasContent()} is <jk>false</jk>.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest request(HttpMethod method, Object url, Object body) throws RestCallException {
+		RestRequest rc = request(method.name(), url, method.hasContent());
+		if (method.hasContent())
+			rc.body(body);
+		return rc;
+	}
+
+	/**
+	 * Perform a generic REST call.
+	 *
+	 * @param method The method name (e.g. <js>"GET"</js>, <js>"OPTIONS"</js>).
+	 * @param url
+	 * 	The URL of the remote REST resource.
+	 * 	Can be any of the following types:
+	 * 	<ul class='spaced-list'>
+	 * 		<li class='jc'>{@link URIBuilder}
+	 * 		<li class='jc'>{@link URI}
+	 * 		<li class='jc'>{@link URL}
+	 * 		<li class='jc'>{@link String}
+	 * 		<li class='jc'>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
+	 * 	</ul>
+	 * @param hasBody Boolean flag indicating if the specified request has content associated with it.
+	 * @return
+	 * 	A {@link RestRequest} object that can be further tailored before executing the request and getting the response
+	 * 	as a parsed object.
+	 * @throws RestCallException If any authentication errors occurred.
+	 */
+	public RestRequest request(String method, Object url, boolean hasBody) throws RestCallException {
+		if (isClosed) {
+			Exception e2 = null;
+			if (closedStack != null) {
+				e2 = new Exception("Creation stack:");
+				e2.setStackTrace(closedStack);
+				throw new RestCallException(e2, "RestClient.close() has already been called.  This client cannot be reused.");
+			}
+			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.client2.RestClient.trackCreation' to true.");
+		}
+
+		RestRequest req = null;
+		final String methodUC = method.toUpperCase(Locale.ENGLISH);
+		try {
+			HttpRequestBase reqb = null;
+			if (hasBody) {
+				reqb = new HttpEntityEnclosingRequestBase() {
+					@Override /* HttpRequest */
+					public String getMethod() {
+						return methodUC;
+					}
+				};
+				req = new RestRequest(this, reqb, toURI(url));
+			} else {
+				reqb = new HttpRequestBase() {
+					@Override /* HttpRequest */
+					public String getMethod() {
+						return methodUC;
+					}
+				};
+				req = new RestRequest(this, reqb, toURI(url));
+			}
+		} catch (URISyntaxException e1) {
+			throw new RestCallException(e1);
+		}
+
+		for (Object o : headers) {
+			if (o instanceof Header)
+				req.header((Header)o);
+			else if (o instanceof NameValuePair)
+				req.header((NameValuePair)o);
+			else if (o instanceof HttpHeader)
+				req.header((HttpHeader)o);
+			else
+				throw new RestCallException("Invalid type {0} for header.", o.getClass());
+		}
+
+		for (Object o : query) {
+			if (o instanceof NameValuePair)
+				req.query((NameValuePair)o);
+			else
+				throw new RestCallException("Invalid type {0} for query.", o.getClass());
+		}
+
+		for (Object o : formData) {
+			if (o instanceof NameValuePair)
+				req.formData((NameValuePair)o);
+			else
+				throw new RestCallException("Invalid type {0} for form-data.", o.getClass());
+		}
+
+		if (parser != null && ! req.containsHeader("Accept"))
+			req.setHeader("Accept", parser.getPrimaryMediaType().toString());
+
+		return req;
+	}
+
+	/**
+	 * Create a new proxy interface against a 3rd-party REST interface.
+	 *
+	 * <p>
+	 * The URL to the REST interface is based on the following values:
+	 * <ul>
+	 * 	<li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
+	 * 	<li>The {@link RestClientBuilder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
+	 * 	<li>The fully-qualified class name of the interface (<c>class-name</c>).
+	 * </ul>
+	 *
+	 * <p>
+	 * The URL calculation is as follows:
+	 * <ul>
+	 * 	<li><c>remote-path</c> - If remote path is absolute.
+	 * 	<li><c>root-url/remote-path</c> - If remote path is relative and root-url has been specified.
+	 * 	<li><c>root-url/class-name</c> - If remote path is not specified.
+	 * </ul>
+	 *
+	 * <p>
+	 * If the information is not available to resolve to an absolute URL, a {@link RemoteMetadataException} is thrown.
+	 *
+	 * <h5 class='section'>Examples:</h5>
+	 * <p class='bcode w800'>
+	 * 	<jk>package</jk> org.apache.foo;
+	 *
+	 * 	<ja>@RemoteResource</ja>(path=<js>"http://hostname/resturl/myinterface1"</js>)
+	 * 	<jk>public interface</jk> MyInterface1 { ... }
+	 *
+	 * 	<ja>@RemoteResource</ja>(path=<js>"/myinterface2"</js>)
+	 * 	<jk>public interface</jk> MyInterface2 { ... }
+	 *
+	 * 	<jk>public interface</jk> MyInterface3 { ... }
+	 *
+	 * 	<jc>// Resolves to "http://localhost/resturl/myinterface1"</jc>
+	 * 	MyInterface1 i1 = RestClient
+	 * 		.<jsm>create</jsm>()
+	 * 		.build()
+	 * 		.getRemote(MyInterface1.<jk>class</jk>);
+	 *
+	 * 	<jc>// Resolves to "http://hostname/resturl/myinterface2"</jc>
+	 * 	MyInterface2 i2 = RestClient
+	 * 		.<jsm>create</jsm>()
+	 * 		.rootUrl(<js>"http://hostname/resturl"</js>)
+	 * 		.build()
+	 * 		.getRemote(MyInterface2.<jk>class</jk>);
+	 *
+	 * 	<jc>// Resolves to "http://hostname/resturl/org.apache.foo.MyInterface3"</jc>
+	 * 	MyInterface3 i3 = RestClient
+	 * 		.<jsm>create</jsm>()
+	 * 		.rootUrl(<js>"http://hostname/resturl"</js>)
+	 * 		.build()
+	 * 		.getRemote(MyInterface3.<jk>class</jk>);
+	 * </p>
+	 *
+	 * <ul class='notes'>
+	 * 	<li>
+	 * 		If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
+	 * 		pooling client connection manager.
+	 * </ul>
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-client.RestProxies}
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @return The new proxy interface.
+	 * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
+	 */
+	public <T> T getRemote(final Class<T> interfaceClass) {
+		return getRemote(interfaceClass, null);
+	}
+
+	/**
+	 * Same as {@link #getRemote(Class)} except explicitly specifies the URL of the REST interface.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-client.RestProxies}
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @param restUrl The URL of the REST interface.
+	 * @return The new proxy interface.
+	 */
+	public <T> T getRemote(final Class<T> interfaceClass, final Object restUrl) {
+		return getRemote(interfaceClass, restUrl, serializer, parser);
+	}
+
+	/**
+	 * Same as {@link #getRemote(Class, Object)} but allows you to override the serializer and parser used.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-client.RestProxies}
+	 * </ul>
+
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @param restUrl The URL of the REST interface.
+	 * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
+	 * @param parser The parser used to parse POJOs from the body of the HTTP response.
+	 * @return The new proxy interface.
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <T> T getRemote(final Class<T> interfaceClass, Object restUrl, final Serializer serializer, final Parser parser) {
+
+		if (restUrl == null)
+			restUrl = rootUrl;
+
+		final String restUrl2 = trimSlashes(emptyIfNull(restUrl));
+
+		try {
+			return (T)Proxy.newProxyInstance(
+				interfaceClass.getClassLoader(),
+				new Class[] { interfaceClass },
+				new InvocationHandler() {
+
+					final RemoteMeta rm = new RemoteMeta(interfaceClass);
+
+					@Override /* InvocationHandler */
+					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+						RemoteMethodMeta rmm = rm.getMethodMeta(method);
+
+						if (rmm == null)
+							throw new RuntimeException("Method is not exposed as a remote method.");
+
+						String url = rmm.getFullPath();
+						if (url.indexOf("://") == -1)
+							url = restUrl2 + '/' + url;
+						if (url.indexOf("://") == -1)
+							throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote resource.");
+
+						String httpMethod = rmm.getHttpMethod();
+						HttpPartSerializer s = getPartSerializer();
+
+						try {
+							RestRequest rc = request(httpMethod, url, hasContent(httpMethod));
+
+							rc.serializer(serializer);
+
+							for (RemoteMethodArg a : rmm.getPathArgs())
+								rc.path(a.getName(), args[a.getIndex()], a.getSerializer(s), a.getSchema());
+
+							for (RemoteMethodArg a : rmm.getQueryArgs())
+								rc.query(a.getName(), args[a.getIndex()], a.isSkipIfEmpty(), a.getSerializer(s), a.getSchema());
+
+							for (RemoteMethodArg a : rmm.getFormDataArgs())
+								rc.formData(a.getName(), args[a.getIndex()], a.isSkipIfEmpty(), a.getSerializer(s), a.getSchema());
+
+							for (RemoteMethodArg a : rmm.getHeaderArgs())
+								rc.header(a.getName(), args[a.getIndex()], a.isSkipIfEmpty(), a.getSerializer(s), a.getSchema());
+
+							RemoteMethodArg ba = rmm.getBodyArg();
+							if (ba != null)
+								rc.body(args[ba.getIndex()], ba.getSchema());
+
+							if (rmm.getRequestArgs().length > 0) {
+								for (RemoteMethodBeanArg rmba : rmm.getRequestArgs()) {
+									RequestBeanMeta rbm = rmba.getMeta();
+									Object bean = args[rmba.getIndex()];
+									if (bean != null) {
+										for (RequestBeanPropertyMeta p : rbm.getProperties()) {
+											Object val = p.getGetter().invoke(bean);
+											HttpPartType pt = p.getPartType();
+											HttpPartSerializer ps = p.getSerializer(s);
+											String pn = p.getPartName();
+											HttpPartSchema schema = p.getSchema();
+											boolean sie = schema.isSkipIfEmpty();
+											if (pt == PATH)
+												rc.path(pn, val, p.getSerializer(s), schema);
+											else if (val != null) {
+												if (pt == QUERY)
+													rc.query(pn, val, sie, ps, schema);
+												else if (pt == FORMDATA)
+													rc.formData(pn, val, sie, ps, schema);
+												else if (pt == HEADER)
+													rc.header(pn, val, sie, ps, schema);
+												else if (pt == HttpPartType.BODY)
+													rc.body(val, schema);
+											}
+										}
+									}
+								}
+							}
+
+							if (rmm.getOtherArgs().length > 0) {
+								Object[] otherArgs = new Object[rmm.getOtherArgs().length];
+								int i = 0;
+								for (RemoteMethodArg a : rmm.getOtherArgs())
+									otherArgs[i++] = args[a.getIndex()];
+								rc.body(otherArgs);
+							}
+
+							RemoteMethodReturn rmr = rmm.getReturns();
+							if (rmr.getReturnValue() == RemoteReturn.NONE) {
+								rc.execute();
+								return null;
+							} else if (rmr.getReturnValue() == RemoteReturn.STATUS) {
+								rc.ignoreErrors();
+								int returnCode = rc.execute().getStatusCode();
+								Class<?> rt = method.getReturnType();
+								if (rt == Integer.class || rt == int.class)
+									return returnCode;
+								if (rt == Boolean.class || rt == boolean.class)
+									return returnCode < 400;
+								throw new RestCallException("Invalid return type on method annotated with @RemoteMethod(returns=HTTP_STATUS).  Only integer and booleans types are valid.");
+							} else if (rmr.getReturnValue() == RemoteReturn.BEAN) {
+								rc.ignoreErrors();
+								return rc.run().as(rmr.getResponseBeanMeta());
+							} else {
+								rc.ignoreErrors();
+								Object v = rc.run().getBody().as(rmr.getReturnType());
+								if (v == null && method.getReturnType().isPrimitive())
+									v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
+								return v;
+							}
+
+						} catch (RestCallException e) {
+							// Try to throw original exception if possible.
+							e.throwServerException(interfaceClass.getClassLoader(), rmm.getExceptions());
+							throw new RuntimeException(e);
+						} catch (Exception e) {
+							throw new RuntimeException(e);
+						}
+					}
+			});
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	/**
+	 * Create a new Remote Interface against a {@link RemoteInterface @RemoteInterface}-annotated class.
+	 *
+	 * <p>
+	 * Remote interfaces are interfaces exposed on the server side using either the <c>RrpcServlet</c>
+	 * or <c>RRPC</c> REST methods.
+	 *
+	 * <p>
+	 * The URL to the REST interface is based on the following values:
+	 * <ul>
+	 * 	<li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
+	 * 	<li>The {@link RestClientBuilder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
+	 * 	<li>The fully-qualified class name of the interface (<c>class-name</c>).
+	 * </ul>
+	 *
+	 * <p>
+	 * The URL calculation is as follows:
+	 * <ul>
+	 * 	<li><c>remote-path</c> - If remote path is absolute.
+	 * 	<li><c>root-url/remote-path</c> - If remote path is relative and root-url has been specified.
+	 * 	<li><c>root-url/class-name</c> - If remote path is not specified.
+	 * </ul>
+	 *
+	 * <p>
+	 * If the information is not available to resolve to an absolute URL, a {@link RemoteMetadataException} is thrown.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>
+	 * 		If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
+	 * 		pooling client connection manager.
+	 * </ul>
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-server.restRPC}
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @return The new proxy interface.
+	 * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
+	 */
+	public <T> T getRrpcInterface(final Class<T> interfaceClass) {
+		return getRrpcInterface(interfaceClass, null);
+	}
+
+	/**
+	 * Same as {@link #getRrpcInterface(Class)} except explicitly specifies the URL of the REST interface.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-server.restRPC}
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @param restUrl The URL of the REST interface.
+	 * @return The new proxy interface.
+	 */
+	public <T> T getRrpcInterface(final Class<T> interfaceClass, final Object restUrl) {
+		return getRrpcInterface(interfaceClass, restUrl, serializer, parser);
+	}
+
+	/**
+	 * Same as {@link #getRrpcInterface(Class, Object)} but allows you to override the serializer and parser used.
+	 *
+	 * <ul class='seealso'>
+	 * 	<li class='link'>{@doc juneau-rest-server.restRPC}
+	 * </ul>
+	 *
+	 * @param interfaceClass The interface to create a proxy for.
+	 * @param restUrl The URL of the REST interface.
+	 * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
+	 * @param parser The parser used to parse POJOs from the body of the HTTP response.
+	 * @return The new proxy interface.
+	 */
+	@SuppressWarnings({ "unchecked" })
+	public <T> T getRrpcInterface(final Class<T> interfaceClass, Object restUrl, final Serializer serializer, final Parser parser) {
+
+		if (restUrl == null) {
+			RemoteInterfaceMeta rm = new RemoteInterfaceMeta(interfaceClass, stringify(restUrl));
+			String path = rm.getPath();
+			if (path.indexOf("://") == -1) {
+				if (rootUrl == null)
+					throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote interface.");
+				path = trimSlashes(rootUrl) + '/' + path;
+			}
+			restUrl = path;
+		}
+
+		final String restUrl2 = stringify(restUrl);
+
+		try {
+			return (T)Proxy.newProxyInstance(
+				interfaceClass.getClassLoader(),
+				new Class[] { interfaceClass },
+				new InvocationHandler() {
+
+					final RemoteInterfaceMeta rm = new RemoteInterfaceMeta(interfaceClass, restUrl2);
+
+					@Override /* InvocationHandler */
+					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+						RemoteInterfaceMethod rim = rm.getMethodMeta(method);
+
+						if (rim == null)
+							throw new RuntimeException("Method is not exposed as a remote method.");
+
+						String url = rim.getUrl();
+
+						try {
+							RestRequest rc = request("POST", url, true).serializer(serializer).body(args);
+
+							Object v = rc.run().getBody().as(method.getGenericReturnType());
+							if (v == null && method.getReturnType().isPrimitive())
+								v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
+							return v;
+
+						} catch (RestCallException e) {
+							// Try to throw original exception if possible.
+							e.throwServerException(interfaceClass.getClassLoader(), method.getExceptionTypes());
+							throw new RuntimeException(e);
+						} catch (Exception e) {
+							throw new RuntimeException(e);
+						}
+					}
+			});
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+	}
+
+	@Override
+	protected void finalize() throws Throwable {
+		if (leakDetection && ! isClosed && ! keepHttpClientOpen) {
+			System.err.println("WARNING:  RestClient garbage collected before it was finalized.");  // NOT DEBUG
+			if (creationStack != null) {
+				System.err.println("Creation Stack:");  // NOT DEBUG
+				for (StackTraceElement e : creationStack)
+					System.err.println(e);  // NOT DEBUG
+			}
+		}
+	}
+
+	//------------------------------------------------------------------------------------------------
+	// Passthrough methods for HttpClient.
+	//------------------------------------------------------------------------------------------------
+
+	/**
+	 * Obtains the parameters for this client.
+	 *
+	 * These parameters will become defaults for all requests being executed with this client, and for the parameters of dependent objects in this client.
+	 *
+	 * @return The default parameters.
+	 * @deprecated Use {@link RequestConfig}.
+	 */
+	@Deprecated
+	@Override /* HttpClient */
+	public HttpParams getParams() {
+		return httpClient.getParams();
+	}
+
+	/**
+	 * Obtains the connection manager used by this client.
+	 *
+	 * @return The connection manager.
+	 * @deprecated Use {@link HttpClientBuilder}.
+	 */
+	@Deprecated
+	@Override /* HttpClient */
+	public ClientConnectionManager getConnectionManager() {
+		return httpClient.getConnectionManager();
+	}
+
+	/**
+	 * Executes HTTP request using the default context.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * </ul>
+	 *
+	 * @param request The request to execute.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	@Override /* HttpClient */
+	public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
+		return httpClient.execute(request);
+	}
+
+	/**
+	 * Executes HTTP request using the given context.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * </ul>
+	 *
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	@Override /* HttpClient */
+	public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
+		return httpClient.execute(request, context);
+	}
+
+	/**
+	 * Executes HTTP request using the default context.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * </ul>
+	 *
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @return The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	@Override /* HttpClient */
+	public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
+		return httpClient.execute(target, request);
+	}
+
+	/**
+	 * Executes HTTP request using the given context.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * 	<li>The {@link #execute(HttpHost,HttpEntityEnclosingRequestBase,HttpContext)} and
+	 * 		{@link #execute(HttpHost,HttpRequestBase,HttpContext)} methods have been provided as wrappers around this method.
+	 * 		Subclasses can override these methods for handling requests with and without bodies separately.
+	 * 	<li>The {@link RestCallHandler} interface can also be implemented to intercept this method.
+	 * </ul>
+	 *
+	 * @param target The target host for the request.
+	 * 	<br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
+	 * 		target or by inspecting the request.
+	 * @param request The request to execute.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return
+	 * 	The response to the request.
+	 * 	<br>This is always a final response, never an intermediate response with an 1xx status code.
+	 * 	<br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
+	 * 		implementation and configuration of this client.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	@Override /* HttpClient */
+	public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException {
+		return httpClient.execute(target, request, context);
+	}
+
+	/**
+	 * Executes HTTP request using the default context and processes the response using the given response handler.
+	 *
+ 	 * <p>
+	 * The content entity associated with the response is fully consumed and the underlying connection is released back
+	 * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
+	 * from having to manage resource deallocation internally.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * </ul>
+	 *
+	 * @param request The request to execute.
+	 * @param responseHandler The response handler.
+	 * @return Object returned by response handler.
+	 * @throws IOException In case of a problem or the connection was aborted.
+	 * @throws ClientProtocolException In case of an http protocol error.
+	 */
+	@Override /* HttpClient */
+	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
+		return httpClient.execute(request, responseHandler);
+	}
+
+	/**
+	 * Executes HTTP request using the given context and processes the response using the given response handler.
+	 *
+	 * <p>
+	 * The content entity associated with the response is fully consumed and the underlying connection is released back
+	 * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
+	 * from having to manage resource deallocation internally.
+	 *
+	 * <ul class='notes'>
+	 * 	<li>This method gets passed on directly to the underlying {@link HttpClient} class.
+	 * </ul>
+	 *
+	 * @param request The request to execute.
+	 * @param responseHandler The response handler.
+	 * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
+	 * @return The response object as generated by the response handler.
+	 * @throws IOException In case of a problem or the connection was aborted.
... 9590 lines suppressed ...