// ***************************************************************************************************************************
// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
// * with the License.  You may obtain a copy of the License at                                                              *
// *                                                                                                                         *
// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
// *                                                                                                                         *
// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
// * specific language governing permissions and limitations under the License.                                              *
// ***************************************************************************************************************************
package org.apache.juneau.rest.client;

import static org.apache.juneau.internal.StringUtils.*;
import static org.apache.juneau.AddFlag.*;
import static org.apache.juneau.httppart.HttpPartType.*;
import static org.apache.juneau.http.HttpMethod.*;
import static org.apache.juneau.http.HttpHeaders.*;
import static org.apache.juneau.http.HttpParts.*;
import static org.apache.juneau.http.HttpEntities.*;
import static java.util.logging.Level.*;
import static org.apache.juneau.internal.ClassUtils.*;
import static org.apache.juneau.internal.ExceptionUtils.*;
import static org.apache.juneau.internal.StateMachineState.*;
import static java.lang.Character.*;
import static java.util.Collections.*;

import java.io.*;
import java.lang.reflect.*;
import java.lang.reflect.Proxy;
import java.net.*;
import java.net.URI;
import java.nio.charset.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.logging.*;
import java.util.regex.*;

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.conn.*;
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.collections.*;
import org.apache.juneau.cp.*;
import org.apache.juneau.http.remote.RemoteReturn;
import org.apache.juneau.http.resource.*;
import org.apache.juneau.http.entity.*;
import org.apache.juneau.http.header.*;
import org.apache.juneau.http.part.*;
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.marshall.*;
import org.apache.juneau.oapi.*;
import org.apache.juneau.parser.*;
import org.apache.juneau.parser.ParseException;
import org.apache.juneau.reflect.*;
import org.apache.juneau.rest.client.assertion.*;
import org.apache.juneau.rest.client.remote.*;
import org.apache.juneau.serializer.*;
import org.apache.juneau.urlencoding.*;
import org.apache.juneau.utils.*;
import org.apache.juneau.http.HttpHeaders;

/**
 * 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>
 * 	MyBean <jv>bean</jv> = RestClient.<jsm>create</jsm>()
 * 		.simpleJson()
 * 		.build()
 * 		.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.assertStatus().code().is(200)
 * 		.assertHeader(<js>"Content-Type"</js>).matchesSimple(<js>"application/json*"</js>)
 * 		.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'>
 * 	RestClientBuilder <jv>builder</jv> = RestClient.<jsm>create</jsm>().simpleJson();
 * 	RestClient <jv>client</jv> = <jv>builder</jv>.build();
 * 	RestRequest <jv>req</jv> = <jv>client</jv>.get(<jsf>URI</jsf>);
 * 	RestResponse <jv>res</jv> = <jv>req</jv>.run();
 * 	RestResponseStatusLineAssertion <jv>statusLineAssertion</jv> = <jv>res</jv>.assertStatus();
 * 	FluentIntegerAssertion&lt;RestResponse&gt; <jv>codeAssertion</jv> = <jv>statusLineAssertion</jv>.code();
 * 	<jv>res</jv> = <jv>codeAssertion</jv>.is(200);
 * 	FluentStringAssertion&lt;RestResponse&gt; <jv>headerAssertion</jv> = <jv>res</jv>.assertHeader(<js>"Content-Type"</js>);
 * 	<jv>res</jv> = <jv>headerAssertion</jv>.matchesSimple(<js>"application/json*"</js>);
 * 	RestResponseBody <jv>body</jv> = <jv>res</jv>.getBody();
 * 	MyBean <jv>bean</jv> = <jv>body</jv>.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>@RemotePost</ja>(<js>"/pets"</js>)
 * 		Pet addPet(
 * 			<ja>@Body</ja> CreatePet <jv>pet</jv>,
 * 			<ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
 * 			<ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
 * 		);
 * 	}
 *
 * 	<jc>// Use a RestClient with default Simple JSON support.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
 *
 * 	PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
 * 	CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
 * 	Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, 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} creates {@link ResponseBody} and {@link ResponseHeader} objects.
 * 	<li class='jc'>{@link ResponseBody} <jk>extends</jk> {@link HttpEntity}
 * 	<li class='jc'>{@link ResponseHeader} <jk>extends</jk> {@link Header}
 * </ul>
 *
 *
 * <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 URI so that relative URIs can be used when making requests.
 * This is done using the {@link RestClientBuilder#rootUri(Object)} method.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Create a client where all URIs are relative to localhost.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().rootUri(<js>"http://localhost:5000"</js>).build();
 *
 * 	<jc>// Use relative paths.</jc>
 * 	String <jv>body</jv> = <jv>client</jv>.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(uri)} / {@link RestClient#get() get()}
 * 		<li class='jm'>{@link RestClient#put(Object,Object) put(uri,body)} / {@link RestClient#put(Object) put(uri)}
 * 		<li class='jm'>{@link RestClient#post(Object) post(uri,body)} / {@link RestClient#post(Object) post(uri)}
 * 		<li class='jm'>{@link RestClient#patch(Object,Object) patch(uri,body)} / {@link RestClient#patch(Object) patch(uri)}
 * 		<li class='jm'>{@link RestClient#delete(Object) delete(uri)}
 * 		<li class='jm'>{@link RestClient#head(Object) head(uri)}
 * 		<li class='jm'>{@link RestClient#options(Object) options(uri)}
 * 		<li class='jm'>{@link RestClient#formPost(Object,Object) formPost(uri,body)} / {@link RestClient#formPost(Object) formPost(uri)}
 * 		<li class='jm'>{@link RestClient#formPostPairs(Object,Object...) formPostPairs(uri,parameters...)}
 * 		<li class='jm'>{@link RestClient#request(String,Object,Object) request(method,uri,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#complete() complete()}
 * 	</ul>
 * </ul>
 *
 * <p class='w900'>
 * The distinction between the two methods is that {@link RestRequest#complete() complete()} 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 ResponseBody} 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 <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).run().getBody().asString();
 *
 * 	<jc>// Only interested in response status code, so use complete().</jc>
 *   <jk>int</jk> <jv>status</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
 * </p>
 *
 *
 * <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 <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build();
 * </p>
 *
 * <p>
 * Clients can also support multiple languages:
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Create a REST client with support for multiple languages.</jc>
 * 	RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().xml().openApi().build();
 *
 * 	<jc>// Create a REST client with support for all supported languages.</jc>
 * 	RestClient <jv>client2</jv> = RestClient.<jsm>create</jsm>().universal().build();
 * </p>
 *
 * <p class='w900'>
 * When using clients with multiple language support, you must specify the <c>Content-Type</c> header on requests
 * with bodies to specify which serializer should be selected.
 *
 * <p class='bcode w800'>
 * 	<jc>// Create a REST client with support for multiple languages.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
 *
 * 	<jv>client</jv>
 * 		.post(<jsf>URI</jsf>, <jv>myBean</jv>)
 * 		.contentType(<js>"application/json"</js>)
 * 		.complete()
 * 		.assertStatus().is(200);
 * </p>
 *
 * <p>
 * Languages can also be specified per-request.
 *
 * <p class='bcode w800'>
 * 	<jc>// Create a REST client with no default languages supported.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().build();
 *
 * 	<jc>// Use JSON for this request.</jc>
 * 	<jv>client</jv>
 * 		.post(<jsf>URI</jsf>, <jv>myBean</jv>)
 * 		.json()
 * 		.complete()
 * 		.assertStatus().is(200);
 * </p>
 *
 *
 * <p class='w900'>
 * The {@link RestClientBuilder} class 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 <jv>client</jv> = RestClient.<jsm>create</jsm>().json().sq().ws().build();
 *
 * 	<jc>// Same, but using properties.</jc>
 * 	RestClient <jv>client2</jv> = RestClient
 * 		.<jsm>create</jsm>()
 * 		.json()
 * 		.set(<jsf>WSERIALIZER_quoteChar</jsf>, <js>'\''</js>)
 * 		.set(<jsf>WSERIALIZER_useWhitespace</jsf>)
 * 		.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#parser(Parser) parser(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(Class) partSerializer(Class&lt;? extends HttpPartSerializer>)}
 * 		<li class='jm'>{@link RestClientBuilder#partParser(Class) partParser(Class&lt;? extends HttpPartParser>)}
 * 	</ul>
 * </ul>
 *
 *
 * <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(String,Object) header(String,Object)}
 * 		<li class='jm'>{@link RestClientBuilder#header(String,Object,HttpPartSchema) header(String,Object,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#header(String,Supplier) header(String,Supplier&lt;?&gt;)}
 * 		<li class='jm'>{@link RestClientBuilder#header(String,Supplier,HttpPartSchema) header(String,Supplier&lt;?&gt;,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#header(Header) header(Header)}
 * 		<li class='jm'>{@link RestClientBuilder#headers(Object...) headers(Object...)}
 * 		<li class='jm'>{@link RestClientBuilder#headerPairs(Object...) headerPairs(Object...)}
 * 	</ul>
 * 	<li class='jc'>{@link RestRequest}
 * 	<ul>
 * 		<li class='jm'>{@link RestRequest#header(String,Object) header(String,Object)}
 * 		<li class='jm'>{@link RestRequest#header(String,Object,HttpPartSchema) header(String,Object,HttpPartSchema)}
 * 		<li class='jm'>{@link RestRequest#header(AddFlag,String,Object) header(AddFlag,String,Object)}
 * 		<li class='jm'>{@link RestRequest#header(AddFlag,String,Object,HttpPartSchema) header(AddFlag,String,Object,HttpPartSchema)}
 * 		<li class='jm'>{@link RestRequest#header(Header) header(Header)}
 * 		<li class='jm'>{@link RestRequest#headers(Object...) headers(Object...)}
 * 		<li class='jm'>{@link RestRequest#headers(AddFlag,Object...) headers(AddFlag;Object...)}
 * 		<li class='jm'>{@link RestRequest#headerPairs(Object...) headers(Object...)}
 * 	</ul>
 * </ul>
 *
 * <p>
 * Additionally, methods are provided on the client builder and per request for all standard HTTP headers
 * such as {@link RestClientBuilder#authorization(Object) authorization(Object)}.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Create a client that adds an Authorization header to every request.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().authorization(<js>"Foo"</js>).build();
 *
 * 	<jc>// Or do it per-request.</jc>
 * 	String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).authorization(<js>"Foo"</js>).run().getBody().asString();
 *
 * 	<jc>// Or use an HttpHeader.</jc>
 * 	<jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).headers(Authorization.<jsm>of</jsm>(<js>"Foo"</js>)).run().getBody().asString();
 * </p>
 *
 * <p class='w900'>
 * The supplier methods are particularly useful for header values 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'>
 * 	<jc>// Create a client that adds a dynamic Authorization header to every request.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, ()-&gt;getMyAuthToken()).build();
 * </p>
 *
 * <p>
 * The {@link HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on both requests
 * and responses.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Create a client that adds a header "Foo: bar|baz" to every request.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
 * 		.header(<js>"Foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
 * 		.build();
 * </p>
 *
 * <p>
 * The methods with {@link AddFlag} parameters allow you to control whether new headers get appended, prepended, or
 * replace existing headers with the same name.
 *
 * <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 parameters can be specified using the following methods:
 * <ul class='javatree'>
 * 	<li class='jc'>{@link RestClientBuilder}
 * 	<ul>
 * 		<li class='jm'>{@link RestClientBuilder#query(String,Object) query(String,Object)}
 * 		<li class='jm'>{@link RestClientBuilder#query(String,Object,HttpPartSchema) query(String,Object,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#query(String,Supplier) query(String,Supplier&lt;?&gt;)}
 * 		<li class='jm'>{@link RestClientBuilder#query(String,Supplier,HttpPartSchema) query(String,Supplier&lt;?&gt;,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#queries(Object...) queries(Object...)}
 * 		<li class='jm'>{@link RestClientBuilder#queryPairs(Object...) queryPairs(Object...)}
 * 	</ul>
 * 	<li class='jc'>{@link RestRequest}
 * 	<ul>
 * 		<li class='jm'>{@link RestRequest#query(String,Object) query(String,Object)}
 * 		<li class='jm'>{@link RestRequest#query(AddFlag,String,Object) query(AddFlag,String,Object)}
 * 		<li class='jm'>{@link RestRequest#queries(Object...) queries(Object...)}
 * 		<li class='jm'>{@link RestRequest#queries(AddFlag,Object...) queries(AddFlag,Object...)}
 * 		<li class='jm'>{@link RestRequest#queryPairs(Object...) queryPairs(Object...)}
 * 		<li class='jm'>{@link RestRequest#queryCustom(Object) queryCustom(Object)}
 * 	</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 <jv>client</jv> = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
 *
 * 	<jc>// Or do it on every request.</jc>
 * 	String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getBody().asString();
 * </p>
 *
 * <ul class='notes'>
 * 	<li>Like header values, dynamic values and OpenAPI schemas are supported.
 * 	<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(String,Object) formData(String,Object)}
 * 		<li class='jm'>{@link RestClientBuilder#formData(String,Object,HttpPartSchema) formData(String,Object,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#formData(String,Supplier) formData(String,Supplier&lt;?&gt;)}
 * 		<li class='jm'>{@link RestClientBuilder#formData(String,Supplier,HttpPartSchema) formData(String,Supplier&lt;?&gt;,HttpPartSchema)}
 * 		<li class='jm'>{@link RestClientBuilder#formDatas(Object...) formDatas(Object...)}
 * 		<li class='jm'>{@link RestClientBuilder#formDataPairs(Object...) formDataPairs(Object...)}
 * 	</ul>
 * 	<li class='jc'>{@link RestRequest}
 * 	<ul>
 * 		<li class='jm'>{@link RestRequest#formData(String,Object) formData(String,Object)}
 * 		<li class='jm'>{@link RestRequest#formData(AddFlag,String,Object) formData(AddFlag,String,Object)}
 * 		<li class='jm'>{@link RestRequest#formDatas(Object...) formDatas(Object...)}
 * 		<li class='jm'>{@link RestRequest#formDatas(AddFlag,Object...) formDatas(AddFlag,Object...)}
 * 		<li class='jm'>{@link RestRequest#formDataPairs(Object...) formDataPairs(Object...)}
 * 		<li class='jm'>{@link RestRequest#formDataCustom(Object) formDataCustom(Object)}
 * 	</ul>
 * </ul>
 *
 * <ul class='notes'>
 * 	<li>Like header values, dynamic values and OpenAPI schemas are supported.
 * 	<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) post(uri,body)}),
 * 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 HttpResource} - Raw contents 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 PartList} - Converted to a URL-encoded FORM post.
 * 		<li class='jc'>
 * 			{@link Supplier} - A supplier of anything on this list.
 * 	</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#complete()}, 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#getStatusCode() getStatusCode()} <jk>returns</jk> <jk>int</jk></c>
 * 		<li class='jm'><c>{@link RestResponse#getReasonPhrase() getReasonPhrase()} <jk>returns</jk> String</c>
 * 		<li class='jm'><c>{@link RestResponse#assertStatus() assertStatus()} <jk>returns</jk> {@link FluentResponseStatusLineAssertion}</c>
 * 	</ul>
 * </ul>
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Only interested in status code.</jc>
 * 	<jk>int</jk> <jv>statusCode</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
 * </p>
 *
 * <p class='w900'>
 * Equivalent 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>// Interested in multiple values.</jc>
 * 	Mutable&lt;Integer&gt; <jv>statusCode</jv> = Mutable.<jsm>create</jsm>();
 * 	Mutable&lt;String&gt; <jv>reasonPhrase</jv> = Mutable.<jsm>create</jsm>();
 *
 * 	<jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode(<jv>statusCode</jv>).getReasonPhrase(<jv>reasonPhrase</jv>);
 * 	System.<jsf>err</jsf>.println(<js>"statusCode="</js>+<jv>statusCode</jv>.get()+<js>", reasonPhrase="</js>+<jv>reasonPhrase</jv>.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#complete()} 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 method is 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 <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.assertStatus().code().isBetween(200,399)
 * 		.getBody().asString();
 *
 * 	<jc>// Status assertion using a predicate.</jc>
 * 	String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.assertStatus().code().passes(<jv>x</jv> -&gt; <jv>x</jv>&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#getHeaders(String) getHeaders(String)} <jk>returns</jk> {@link ResponseHeader}[]</c>
 * 		<li class='jm'><c>{@link RestResponse#getFirstHeader(String) getFirstHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
 * 		<li class='jm'><c>{@link RestResponse#getLastHeader(String) getLastHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
 * 		<li class='jm'><c>{@link RestResponse#getAllHeaders() getAllHeaders()} <jk>returns</jk> {@link ResponseHeader}[]</c>
 * 		<li class='jm'><c>{@link RestResponse#getStringHeader(String) getStringHeader(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'>
 * The {@link RestResponse#getFirstHeader(String)} and {@link RestResponse#getLastHeader(String)} methods return an empty {@link ResponseHeader} object instead of<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> <jv>hasLocationHeader</jv> = client.get(<jsf>URI</jsf>).complete().getLastHeader(<js>"Location"</js>).exists();
 * </p>
 *
 * <p class='w900'>
 * The {@link ResponseHeader} class extends from the HttpClient {@link Header} class and provides several convenience
 * methods:
 *
 * <ul class='javatree'>
 * 	<li class='jc'>{@link ResponseHeader}
 * 	<ul>
 * 		<li class='jm'><c>{@link ResponseHeader#isPresent() isPresent()} <jk>returns</jk> <jk>boolean</jk></c>
 * 		<li class='jm'><c>{@link ResponseHeader#asString() asString()} <jk>returns</jk> String</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asType(Type,Type...) asType(Type,Type...)} <jk>returns</jk> T</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asType(Class) asType(Class&lt;T&gt;)} <jk>returns</jk> T</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asHeader(Class) asHeader(Class&lt;T <jk>extends</jk> BasicHeader&gt; c)} <jk>returns</jk> {@link BasicHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asStringHeader() asStringHeader()} <jk>returns</jk> {@link BasicStringHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asIntegerHeader() asIntegerHeader()} <jk>returns</jk> {@link BasicIntegerHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asLongHeader() asLongHeader()} <jk>returns</jk> {@link BasicLongHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asDateHeader() asDateHeader()} <jk>returns</jk> {@link BasicDateHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asCsvArrayHeader() asCsvArrayHeader()} <jk>returns</jk> {@link BasicCsvArrayHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asEntityTagArrayHeader() asEntityValidatorArrayHeader()} <jk>returns</jk> {@link BasicEntityTagArrayHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asStringRangeArrayHeader() asRangeArrayHeader()} <jk>returns</jk> {@link BasicStringRangeArrayHeader}</c>
 * 		<li class='jm'><c>{@link ResponseHeader#asUriHeader() asUriHeader()} <jk>returns</jk> {@link BasicUriHeader}</c>
 * 	</ul>
 * </ul>
 *
 * <p>
 * The {@link ResponseHeader#schema(HttpPartSchema)} method allows you to perform parsing of OpenAPI formats for
 * header parts.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Parse the header "Foo: bar|baz".</jc>
 * 	List&lt;String&gt; <jv>fooHeader</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</jsf>)
 * 		.complete()
 * 		.getHeader(<js>"Foo"</js>).schema(<jsf>T_ARRAY_PIPES</jsf>).as(List.<jk>class</jk>, String.<jk>class</jk>);
 * </p>
 *
 * <p>
 * Assertion methods are also provided for fluent-style calls:
 *
 * <ul class='javatree'>
 * 	<li class='jc'>{@link ResponseHeader}
 * 	<ul>
 * 		<li class='jm'><c>{@link ResponseHeader#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseHeaderAssertion}</c>
 * 	</ul>
 * </ul>
 *
 * <p>
 * Note how in the following example, the fluent assertion returns control to the {@link RestResponse} object after
 * the assertion has been completed:
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Assert the response content type is any sort of JSON.</jc>
 * 	String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.getHeader(<js>"Content-Type"</js>).assertValue().matchesSimple(<js>"application/json*"</js>)
 * 		.getBody().asString();
 * </p>
 *
 *
 * <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 ResponseBody}</c>
 * 	</ul>
 * </ul>
 *
 * <p class='w900'>
 * The {@link ResponseBody} class extends from the HttpClient {@link HttpEntity} class and provides several convenience
 * methods:
 *
 * <ul class='javatree'>
 * 	<li class='jc'>{@link ResponseBody}
 * 	<ul>
 * 		<li class='jm'><c>{@link ResponseBody#asInputStream() asInputStream()} <jk>returns</jk> InputStream</c>
 * 		<li class='jm'><c>{@link ResponseBody#asReader() asReader()} <jk>returns</jk> Reader</c>
 * 		<li class='jm'><c>{@link ResponseBody#asReader(Charset) asReader(Charset)} <jk>returns</jk> Reader</c>
 * 		<li class='jm'><c>{@link ResponseBody#pipeTo(OutputStream) pipeTo(OutputStream)} <jk>returns</jk> {@link RestResponse}</c>
 * 		<li class='jm'><c>{@link ResponseBody#pipeTo(Writer) pipeTo(Writer)} <jk>returns</jk> {@link RestResponse}</c>
 * 		<li class='jm'><c>{@link ResponseBody#asType(Type,Type...) asType(Type,Type...)} <jk>returns</jk> T</c>
 * 		<li class='jm'><c>{@link ResponseBody#asType(Class) asType(Class&lt;T&gt;)} <jk>returns</jk> T</c>
 * 		<li class='jm'><c>{@link ResponseBody#asFuture(Class) asFuture(Class&lt;T&gt;)} <jk>returns</jk> Future&lt;T&gt;</c>
 * 		<li class='jm'><c>{@link ResponseBody#asFuture(Type,Type...) asFuture(Type,Type...)} <jk>returns</jk> Future&lt;T&gt;</c>
 * 		<li class='jm'><c>{@link ResponseBody#asString() asString()} <jk>returns</jk> String</c>
 * 		<li class='jm'><c>{@link ResponseBody#asStringFuture() asStringFuture()} <jk>returns</jk> Future&lt;String&gt;</c>
 * 		<li class='jm'><c>{@link ResponseBody#asAbbreviatedString(int) asAbbreviatedString(int)} <jk>returns</jk> String</c>
 * 		<li class='jm'><c>{@link ResponseBody#asPojoRest(Class) asPojoRest(Class&lt;?&gt;)} <jk>returns</jk> {@link PojoRest}</c>
 * 		<li class='jm'><c>{@link ResponseBody#asPojoRest() asPojoRest()} <jk>returns</jk> {@link PojoRest}</c>
 * 		<li class='jm'><c>{@link ResponseBody#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
 * 		<li class='jm'><c>{@link ResponseBody#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
 * 	</ul>
 * </ul>
 *
 * <br>
 *
 * <h5 class='figure'>Examples:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Parse into a linked-list of strings.</jc>
 * 	List&lt;String&gt; <jv>l1</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</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; <jv>l2</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</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; <jv>l3</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</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; <jv>m1</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</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; <jv>m2<jv> = <jv>client</jv>
 * 		.get(<jsf>URI</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 unless it has been cached into memory.  In many cases, the body is
 * automatically cached when using the assertions methods or methods such as {@link ResponseBody#asString()}.
 * However, methods that involve reading directly from the input stream cannot be called twice.
 * In these cases, the {@link RestResponse#cacheBody()} and {@link ResponseBody#cache()} methods are provided
 * to cache the response body in memory so that you can perform several operations against it.
 *
 * <p class='bcode w800'>
 * 	<jc>// Cache the response body so we can access it twice.</jc>
 * 	InputStream <jv>inputStream</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.cacheBody()
 * 		.getBody().pipeTo(<jv>someOtherStream</jv>)
 * 		.getBody().asInputStream();
 * </p>
 *
 * <p>
 * Assertion methods are also provided for fluent-style calls:
 *
 * <ul class='javatree'>
 * 	<li class='jc'>{@link ResponseBody}
 * 	<ul>
 * 		<li class='jm'><c>{@link ResponseBody#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseBodyAssertion}</c>
 * 	</ul>
 * </ul>
 *
 * <br>
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Assert that the body contains the string "Success".</jc>
 * 	String <jv>body</jv> = <jv>client</jv>
 * 		.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.getBody().assertString().contains(<js>"Success"</js>)
 * 		.getBody().asString();
 * </p>
 *
 * <p>
 * Object assertions allow you to parse the response body into a POJO and then perform various tests on that resulting
 * POJO.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Parse bean into POJO and then validate that it was parsed correctly.</jc>
 * 	MyBean <jv>bean</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
 * 		.run()
 * 		.getBody().assertObject(MyBean.<jk>class</jk>).json().is(<js>"{foo:'bar'}"</js>)
 * 		.getBody().as(MyBean.<jk>class</jk>);
 * </p>
 *
 *
 * <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#run(HttpHost,HttpRequest,HttpContext) run(HttpHost,HttpRequest,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 #run(HttpHost,HttpRequest,HttpContext)} method
 * or by defining your own {@link HttpRequestExecutor}.  Using this interface is often simpler though.
 *
 *
 * <h4 class='topic'>Interceptors</h4>
 *
 * <p class='w900'>
 * The {@link RestCallInterceptor} API provides a quick way of intercepting and manipulating requests and responses beyond
 * the existing {@link HttpRequestInterceptor} and {@link HttpResponseInterceptor} APIs.
 *
 * <ul class='javatree'>
 * 	<li class='jc'>{@link RestClientBuilder}
 * 	<ul>
 * 		<li class='jm'>{@link RestClientBuilder#interceptors(Object...) interceptors(Object...)}
 * 	</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>
 *
 *
 * <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#logger(Logger) logger(Logger)}
 * 		<li class='jm'>{@link RestClientBuilder#logToConsole() logToConsole()}
 * 		<li class='jm'>{@link RestClientBuilder#logRequests(DetailLevel,Level,BiPredicate) logRequests(DetailLevel,Level,BiPredicate)}
 * 	</ul>
 * </ul>
 *
 * <p>
 * The following example shows the results of logging all requests that end with <c>/bean</c>.
 *
 * <h5 class='figure'>Examples:</h5>
 * <p class='bcode w800'>
 * 	MyBean <jv>bean</jv> = RestClient
 * 		.<jsm>create</jsm>()
 * 		.simpleJson()
 * 		.logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (<jv>req</jv>,<jv>res</jv>)-&gt;<jv>req</jv>.getUri().endsWith(<js>"/bean"</js>))
 * 		.logToConsole()
 * 		.build()
 * 		.post(<js>"http://localhost/bean"</js>, <jv>anotherBean</jv>)
 * 		.run()
 * 		.getBody().as(MyBean.<jk>class</jk>);
 * </p>
 *
 * <p>
 * This produces the following console output:
 *
 * <p class='bcode w800 console'>
 * 	=== HTTP Call (outgoing) ======================================================
 * 	=== REQUEST ===
 * 	POST http://localhost/bean
 * 	---request headers---
 * 		Accept: application/json+simple
 * 	---request entity---
 * 	Content-Type: application/json+simple
 * 	---request content---
 * 	{f:1}
 * 	=== RESPONSE ===
 * 	HTTP/1.1 200
 * 	---response headers---
 * 		Content-Type: application/json
 * 	---response content---
 * 	{f:1}
 * 	=== END =======================================================================",
 * </p>
 *
 *
 * <p class='notes w900'>
 * It should be noted that if you enable request logging detail level {@link DetailLevel#FULL}, 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 Context#CONTEXT_debug} is enabled.
 * 	<li>{@link #RESTCLIENT_leakDetection} is enabled.
 * 	<li>{@link RestClientBuilder#logToConsole()} is called.
 * </ul>
 *
 *
 * <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>@RemotePost</ja>(<js>"/pets"</js>)
 * 		Pet addPet(
 * 			<ja>@Body</ja> CreatePet <jv>pet</jv>,
 * 			<ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
 * 			<ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
 * 		);
 * 	}
 *
 * 	<jc>// Use a RestClient with default Simple JSON support.</jc>
 * 	RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().simpleJson().build())
 *
 * 	PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
 * 	CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
 * 	Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, 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 RestcProxies}
 * 	<li class='link'>{@doc RestRpc}
 * </ul>
 *
 * <br>
 * <hr class='w900'>
 * <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#httpClientBuilder(HttpClientBuilder) httpClientBuilder(HttpClientBuilder)} - Set the client builder yourself.
 * 		<li class='jm'>{@link RestClientBuilder#createHttpClientBuilder() createHttpClientBuilder()} - Override to create the client builder.
 * 		<li class='jm'>{@link RestClientBuilder#createHttpClient() createHttpClient()} - Override to create the client.
 * 		<li class='jm'>{@link RestClientBuilder#createConnectionManager() createConnectionManager()} - Override to create the connection management.
 * 	</ul>
 * </ul>
 *
 * <p class='w900'>
 * Additionally, all methods on the <c>HttpClientBuilder</c> class have been extended with fluent setters.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jc>// Create a client with customized HttpClient settings.</jc>
 * 	MyBean <jv>bean</jv> = RestClient
 * 		.<jsm>create</jsm>()
 * 		.disableRedirectHandling()
 * 		.connectionManager(<jv>myConnectionManager</jv>)
 * 		.addInterceptorFirst(<jv>myHttpRequestInterceptor</jv>)
 * 		.build();
 * </p>
 *
 * <p>
 * Refer to the {@link HttpClientBuilder HTTP Client Builder API} for more information.
 *
 *
 * <h4 class='topic'>Extending RestClient</h4>
 *
 * <p class='w900'>
 * The <c>RestClient</c> API has been designed to allow for the ability to be easily extended.
 * The following example that overrides the primary run method shows how this can be done.
 *
 * <h5 class='figure'>Example:</h5>
 * <p class='bcode w800'>
 * 	<jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
 *
 * 		<jc>// Must provide this constructor!</jc>
 * 		<jk>public</jk> MyRestClient(ContextProperties <jv>properties</jv>) {
 * 			<jk>super</jk>(<jv>properties</jv>);
 * 		}
 *
 * 		<ja>@Override</ja>
 * 		<jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
 * 			<jc>// Perform special handling of requests.</jc>
 * 		}
 * 	}
 *
 * 	<jc>// Instantiate your client.</jc>
 * 	MyRestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build(MyRestClient.<jk>class</jk>);
 * </p>
 *
 * <p class='w900'>
 * The {@link RestRequest} and {@link RestResponse} objects can also be extended and integrated by overriding the
 * {@link RestClient#createRequest(URI, String, boolean)} and {@link RestClient#createResponse(RestRequest, HttpResponse, Parser)} methods.
 *
 *
 * <ul class='seealso'>
 * 	<li class='link'>{@doc juneau-rest-client}
 * </ul>
 */
@ConfigurableContext(nocache=true)
public class RestClient extends BeanContext implements HttpClient, Closeable, RestCallHandler, RestCallInterceptor {

	//-------------------------------------------------------------------------------------------------------------------
	// 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.client.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.client.RestCallHandler}&gt;</c>
	 * 			<li>{@link org.apache.juneau.rest.client.RestCallHandler}
	 * 		</ul>
	 * 	<li><b>Default:</b>  <c><jk>null</jk></c>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#callHandler(Class)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#callHandler(RestCallHandler)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 *
	 * <p>
	 * Allows you to provide a custom handler for making HTTP calls.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that handles processing of requests using a custom handler.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.callHandler(
	 * 			<jk>new</jk> RestCallHandler() {
	 * 				<ja>@Override</ja>
	 * 				<jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
	 * 					<jc>// Custom handle requests.</jc>
	 * 				}
	 * 			}
	 * 		)
	 * 		.build();
	 * </p>
	 */
	public static final String RESTCLIENT_callHandler = PREFIX + "callHandler.o";

	/**
	 * Configuration property:  Connection manager
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_connectionManager RESTCLIENT_connectionManager}
	 * 	<li><b>Name:</b>  <js>"RestClient.connectionManager.o"</js>
	 * 	<li><b>System property:</b>  <c>RestClient.connectionManager</c>
	 * 	<li><b>Data type:</b>
	 * 	<ul>
	 * 		<li><b>Data type:</b>  {@link org.apache.http.conn.HttpClientConnectionManager}</c>
	 * 	</ul>
	 * 	<li><b>Default:</b>  Value returned by {@link org.apache.juneau.rest.client.RestClientBuilder#createConnectionManager()}
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#connectionManager(HttpClientConnectionManager)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Allows you to override the connection manager used by the HTTP client.
	 */
	public static final String RESTCLIENT_connectionManager = PREFIX + "connectionManager.o";

	/**
	 * Configuration property:  Console print stream.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_console RESTCLIENT_console}
	 * 	<li><b>Name:</b>  <js>"RestClient.console.o"</js>
	 * 	<li><b>System property:</b>  <c>RestClient.console</c>
	 * 	<li><b>Data type:</b>
	 * 	<ul>
	 * 		<li><b>Data type:</b>  <c>Class&lt;? <jk>extends</jk> {@link java.io.PrintStream}&gt; | {@link java.io.PrintStream}</c>
	 * 	</ul>
	 * 	<li><b>Default:</b>  <c>System.<jsf>out</jsf></c>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#console(PrintStream)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#console(Class)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Allows you to redirect the console output to a different print stream.
	 */
	public static final String RESTCLIENT_console = PREFIX + "console.o";

	/**
	 * Configuration property:  Error codes predicate.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.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.client.RestClientBuilder#errorCodes(Predicate)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#errorCodes(Predicate)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 *
	 * <p>
	 * Defines a predicate to test for error codes.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that considers any 300+ responses to be errors.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.errorCodes(<jv>x</jv> -&gt; <jv>x</jv> &gt;= 300)
	 * 		.build();
	 * </p>
	 */
	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.client.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.client.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 class='jm'>{@link RestRequest#runFuture()}
	 * 	<li class='jm'>{@link RestRequest#completeFuture()}
	 * 	<li class='jm'>{@link ResponseBody#asFuture(Class)} (and similar methods)
	 * </ul>
	 *
	 * <p>
	 * The default executor service is a single-threaded {@link ThreadPoolExecutor} with a 30 second timeout
	 * and a queue size of 10.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client with a customized executor service.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.executorService(<jk>new</jk> ThreadPoolExecutor(1, 1, 30, TimeUnit.<jsf>SECONDS</jsf>, <jk>new</jk> ArrayBlockingQueue&lt;Runnable&gt;(10)), <jk>true</jk>)
	 * 		.build();
	 *
	 * 	<jc>// Use it to asynchronously run a request.</jc>
	 * 	Future&lt;RestResponse&gt; <jv>responseFuture</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).runFuture();
	 *
	 * 	<jc>// Do some other stuff.</jc>
	 *
	 * 	<jc>// Now read the response.</jc>
	 * 	String <jv>body</jv> = <jv>responseFuture</jv>.get().getBody().asString();
	 *
	 * 	<jc>// Use it to asynchronously retrieve a response.</jc>
	 * 	Future&lt;MyBean&gt; <jv>myBeanFuture</jv> = <jv>client</jv>
	 * 		.get(<jsf>URI</jsf>)
	 * 		.run()
	 * 		.getBody().asFuture(MyBean.<jk>class</jk>);
	 *
	 * 	<jc>// Do some other stuff.</jc>
	 *
	 * 	<jc>// Now read the response.</jc>
	 * 	MyBean <jv>bean</jv> = <jv>myBeanFuture</jv>.get();
	 * </p>
	 */
	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.client.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.client.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.client.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.client.RestClientBuilder}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#formData(String,Object) formData(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#formData(String,Object,HttpPartSchema,HttpPartSerializer) formData(String,Object,HttpPartSerializer,HttpPartSchema)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#formDatas(Object...) formDatas(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#formDataPairs(Object...) formDataPairs(Map<String, Object>)}
	 * 			</ul>
	 * 			<li class='jc'>{@link org.apache.juneau.rest.client.RestRequest}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formData(String,Object) formData(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formData(AddFlag,String,Object) formData(EnumSet&lt;AddFlag&gt;,String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formDatas(Object...) formDatas(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formDatas(AddFlag,Object...) formDatas(EnumSet&lt;AddFlag&gt;Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formDataPairs(Object...) formDataPairs(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#formDataCustom(Object) formDataCustom(Object)}
	 * 			</ul>
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Query parameters to add to every request.
	 */
	public static final String RESTCLIENT_formData = PREFIX + "formData.lo";

	/**
	 * Configuration property:  Request headers.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.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.http.NameValuePair}&gt;</c>
	 * 	<li><b>Default:</b>  empty map
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jc'>{@link org.apache.juneau.rest.client.RestClientBuilder}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#header(String,Object) header(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#header(String,Object,HttpPartSchema,HttpPartSerializer) header(String,Object,HttpPartSerializer,HttpPartSchema)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#header(Header) header(Header)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#headers(Object...) headers(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#headerPairs(Object...) headerPairs(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#accept(Object) accept(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#acceptCharset(Object) acceptCharset(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#acceptEncoding(Object) acceptEncoding(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#acceptLanguage(Object) acceptLanguage(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#authorization(Object) authorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#cacheControl(Object) cacheControl(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#clientVersion(Object) clientVersion(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#connection(Object) connection(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#contentLength(Object) contentLength(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#contentType(Object) contentType(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#date(Object) date(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#expect(Object) expect(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#forwarded(Object) forwarded(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#from(Object) from(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#host(Object) host(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ifMatch(Object) ifMatch(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ifModifiedSince(Object) ifModifiedSince(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ifNoneMatch(Object) ifNoneMatch(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ifRange(Object) ifRange(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#maxForwards(Object) maxForwards(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#origin(Object) origin(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#pragma(Object) pragma(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#proxyAuthorization(Object) proxyAuthorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#range(Object) proxyAuthorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#referer(Object) referer(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#te(Object) te(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#userAgent(Object) userAgent(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#upgrade(Object) upgrade(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#via(Object) via(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#warning(Object) warning(Object)}
	 * 			</ul>
	 * 			<li class='jc'>{@link org.apache.juneau.rest.client.RestRequest}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#header(String,Object) header(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#header(AddFlag,String,Object) header(EnumSet&gt;AddFlag&gt;,String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#header(Header) header(Header)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#headers(Object...) headers(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#headers(AddFlag,Object...) headers(EnumSet&gt;AddFlag&gt;,Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#headerPairs(Object...) headerPairs(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#accept(Object) accept(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#acceptCharset(Object) acceptCharset(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#acceptEncoding(Object) acceptEncoding(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#acceptLanguage(Object) acceptLanguage(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#authorization(Object) authorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#cacheControl(Object) cacheControl(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#clientVersion(Object) clientVersion(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#connection(Object) connection(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#contentLength(Object) contentLength(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#contentType(Object) contentType(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#date(Object) date(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#expect(Object) expect(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#forwarded(Object) forwarded(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#from(Object) from(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#hostHeader(Object) hostHeader(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ifMatch(Object) ifMatch(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ifModifiedSince(Object) ifModifiedSince(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ifNoneMatch(Object) ifNoneMatch(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ifRange(Object) ifRange(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ifUnmodifiedSince(Object) ifUnmodifiedSince(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#maxForwards(Object) maxForwards(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#origin(Object) origin(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#pragma(Object) pragma(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#proxyAuthorization(Object) proxyAuthorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#range(Object) proxyAuthorization(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#referer(Object) referer(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#te(Object) te(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#userAgent(Object) userAgent(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#upgrade(Object) upgrade(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#via(Object) via(Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.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.lo";

	/**
	 * Configuration property:  Ignore errors.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_ignoreErrors RESTCLIENT_ignoreErrors}
	 * 	<li><b>Name:</b>  <js>"RestClient.ignoreErrors.b"</js>
	 * 	<li><b>Data type:</b>  <jk>boolean</jk>
	 * 	<li><b>Default:</b>  <jk>false</jk>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ignoreErrors()}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#ignoreErrors(boolean)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#ignoreErrors()}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 *
	 * <p>
	 * When enabled, HTTP error response codes (e.g. <l>&gt;=400</l>) will not cause a {@link RestCallException} to
	 * be thrown.
	 * <p>
	 * Note that this is equivalent to <c>builder.errorCodes(x -&gt; <jk>false</jk>);</c>
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that doesn't throws a RestCallException when a 500 error occurs.</jc>
	 * 	RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.ignoreErrors()
	 * 		.build()
	 * 		.get(<js>"/error"</js>)  <jc>// Throws a 500 error</jc>
	 * 		.run()
	 * 		.assertStatus().is(500);
	 * </p>
	 */
	public static final String RESTCLIENT_ignoreErrors = PREFIX + "ignoreErrors.b";

	/**
	 * Configuration property:  Call interceptors.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.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.client.RestCallInterceptor}&gt; | {@link org.apache.juneau.rest.client.RestCallInterceptor}&gt;&gt;</c>
	 * 	<li><b>Default:</b>  empty list.
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#interceptors(Object...)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Adds an interceptor that can be called to hook into specified events in the lifecycle of a single request.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 *   <jc>// Customized interceptor (note you can also extend from BasicRestCallInterceptor as well.</jc>
	 * 	<jk>public class</jk> MyRestCallInterceptor <jk>implements</jk> RestCallInterceptor {
	 *
	 * 		<ja>@Override</ja>
	 * 		<jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
	 *			<jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
	 *			// set on the request from the client.</jc>
	 *		}
	 *		<ja>@Override</ja>
	 *		<jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
	 *			<jc>// Intercept immediately after an HTTP response has been received.</jc>
	 *		}
	 *
	 *		<ja>@Override</ja>
	 *		<jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
	 * 			<jc>// Intercept when the response body is consumed.</jc>
	 * 		}
	 * 	}
	 *
	 * 	<jc>// Create a client with a customized interceptor.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.interceptors(MyRestCallInterceptor.<jk>class</jk>)
	 * 		.build();
	 * </p>
	 */
	public static final String RESTCLIENT_interceptors = PREFIX + "interceptors.lo";

	/**
	 * 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.client.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.client.RestClientBuilder#keepHttpClientOpen()}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Don't close this client when the {@link RestClient#close()} method is called.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client with a customized client and don't close the client  service.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.httpClient(<jv>myHttpClient</jv>)
	 * 		.keepHttpClientOpen()
	 * 		.build();
	 *
	 * 	<jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
	 * </p>
	 */
	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.client.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.client.RestClientBuilder#leakDetection()}
	 * 		</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 Context#CONTEXT_debug}.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that logs a message if </jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.leakDetection()
	 * 		.logToConsole()  <jc>// Also log the error message to System.err</jc>
	 * 		.build();
	 *
	 * 	<jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
	 * </p>
	 */
	public static final String RESTCLIENT_leakDetection = PREFIX + "leakDetection.b";

	/**
	 * Configuration property:  Logger.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logger RESTCLIENT_logger}
	 * 	<li><b>Name:</b>  <js>"RestClient.logger.o"</js>
	 * 	<li><b>Data type:</b>
	 * 		<ul>
	 * 			<li>{@link java.util.logging.Logger}
	 * 		</ul>
	 * 	<li><b>Default:</b>  <c>Logger.<jsm>getLogger</jsm>(RestClient.<jk>class</jk>.getName())</c>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#logger(Logger)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Specifies the logger to use for logging.
	 */
	public static final String RESTCLIENT_logger = PREFIX + "logger.o";

	/**
	 * Configuration property:  Log to console.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logToConsole RESTCLIENT_logToConsole}
	 * 	<li><b>Name:</b>  <js>"RestClient.logToConsole.b"</js>
	 * 	<li><b>System property:</b>  <c>RestClient.logToConsole</c>
	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_LOGTOCONSOLE</c>
	 * 	<li><b>Data type:</b>
	 * 		<ul>
	 * 			<li><jk>boolean</jk>
	 * 		</ul>
	 * 	<li><b>Default:</b>  <jk>false</jk>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#logToConsole()}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * When enabled, log messages are sent to the console in addition to the existing logger.
	 */
	public static final String RESTCLIENT_logToConsole = PREFIX + "logToConsole.b";

	/**
	 * Configuration property:  Log requests.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logRequests RESTCLIENT_logRequests}
	 * 	<li><b>Name:</b>  <js>"RestClient.logRequests.s"</js>
	 * 	<li><b>System property:</b>  <c>RestClient.logRequests</c>
	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_LOGREQUESTS</c>
	 * 	<li><b>Data type:</b>
	 * 		<ul>
	 * 			<li>{@link org.apache.juneau.DetailLevel}
	 * 		</ul>
	 * 	<li><b>Default:</b>  {@link org.apache.juneau.DetailLevel#NONE}
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#logRequests(DetailLevel,Level,BiPredicate)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Causes requests/responses to be logged at the specified log level at the end of the request.
	 *
	 * <p>
	 * <jsf>SIMPLE</jsf> detail produces a log message like the following:
	 * <p class='bcode w800 console'>
	 * 	POST http://localhost:10000/testUrl, HTTP/1.1 200 OK
	 * </p>
	 *
	 * <p>
	 * <jsf>FULL</jsf> detail produces a log message like the following:
	 * <p class='bcode w800 console'>
	 * 	=== HTTP Call (outgoing) =======================================================
	 * 	=== REQUEST ===
	 * 	POST http://localhost:10000/testUrl
	 * 	---request headers---
	 * 		Debug: true
	 * 		No-Trace: true
	 * 		Accept: application/json
	 * 	---request entity---
	 * 		Content-Type: application/json
	 * 	---request content---
	 * 	{"foo":"bar","baz":123}
	 * 	=== RESPONSE ===
	 * 	HTTP/1.1 200 OK
	 * 	---response headers---
	 * 		Content-Type: application/json;charset=utf-8
	 * 		Content-Length: 21
	 * 		Server: Jetty(8.1.0.v20120127)
	 * 	---response content---
	 * 	{"message":"OK then"}
	 * 	=== END ========================================================================
	 * </p>
	 *
	 * <p>
	 * By default, the message is logged to the default logger.  It can be logged to a different logger via the
	 * {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logger} setting or logged to the console using the
	 * {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logToConsole} setting.
	 */
	public static final String RESTCLIENT_logRequests = PREFIX + "logRequests.s";

	/**
	 * Configuration property:  Log requests log level.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logRequestsLevel RESTCLIENT_logRequestsLevel}
	 * 	<li><b>Name:</b>  <js>"RestClient.logRequestsLevel.s"</js>
	 * 	<li><b>System property:</b>  <c>RestClient.logRequestsLevel</c>
	 * 	<li><b>Environment variable:</b>  <c>RESTCLIENT_LOGREQUESTLEVEL</c>
	 * 	<li><b>Data type:</b>
	 * 		<ul>
	 * 			<li>{@link java.util.logging.Level}
	 * 		</ul>
	 * 	<li><b>Default:</b>  {@link java.util.logging.Level#INFO}
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#logRequests(DetailLevel,Level,BiPredicate)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Used in combination with {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logRequests} to specify the
	 * level to log request messages to.
	 */
	public static final String RESTCLIENT_logRequestsLevel = PREFIX + "logRequestsLevel.s";

	/**
	 * Configuration property:  Log requests predicate.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logRequestsPredicate RESTCLIENT_logRequestsPredicate}
	 * 	<li><b>Name:</b>  <js>"RestClient.logRequestsPredicate.o"</js>
	 * 	<li><b>Data type:</b>
	 * 		<ul>
	 * 			<li>{@link java.util.function.BiPredicate}&lt;{@link org.apache.juneau.rest.client.RestRequest},{@link org.apache.juneau.rest.client.RestResponse}&gt;
	 * 		</ul>
	 * 	<li><b>Default:</b>  <c>(req,res) -&gt; <jk>true</jk></c>
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#logRequests(DetailLevel,Level,BiPredicate)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Used in combination with {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_logRequests} to specify the
	 * level to log request messages to.
	 */
	public static final String RESTCLIENT_logRequestsPredicate = PREFIX + "logRequestsPredicate.o";

	/**
	 * Configuration property:  Parsers.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_parsers RESTCLIENT_parsers}
	 * 	<li><b>Name:</b>  <js>"RestClient.parsers.lo"</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>  No parsers.
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#parser(Class)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#parser(Parser)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#parsers(Class...)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#parsers(Parser...)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Associates the specified {@link Parser Parsers} with the HTTP client.
	 *
	 * <p>
	 * The parsers are used to parse the HTTP response body into a POJO.
	 *
	 * <p>
	 * The parser that best matches the <c>Accept</c> header will be used to parse the response body.
	 * <br>If no <c>Accept</c> header is specified, the first parser in the list will be used.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that uses JSON and XML transport for response bodies.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.parser(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>)
	 * 		.strict()  <jc>// Enable strict mode on parsers.</jc>
	 * 		.build();
	 * </p>
	 */
	public static final String RESTCLIENT_parsers = PREFIX + "parsers.lo";

	/**
	 * Configuration property:  Part parser.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.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.client.RestClientBuilder#partParser(Class)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.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.
	 *
	 * <p>
	 * The default part parser is {@link OpenApiParser} which allows for schema-driven marshalling.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that uses UON format by default for incoming HTTP parts.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.partParser(UonParser.<jk>class</jk>)
	 * 		.build();
	 * </p>
	 */
	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.client.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.client.RestClientBuilder#partSerializer(Class)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.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.
	 *
	 * <p>
	 * The default part serializer is {@link OpenApiSerializer} which allows for schema-driven marshalling.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that uses UON format by default for outgoing HTTP parts.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.partSerializer(UonSerializer.<jk>class</jk>)
	 * 		.build();
	 * </p>
	 */
	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.client.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.client.RestClientBuilder}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#queries(Object...) queries(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#query(String,Object) query(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#query(String,Object,HttpPartSchema,HttpPartSerializer) query(String,Object,HttpPartSerializer,HttpPartSchema)}
	 * 			</ul>
	 * 			<li class='jc'>{@link org.apache.juneau.rest.client.RestRequest}
	 * 			<ul>
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#query(String,Object) query(String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#query(AddFlag,String,Object) query(EnumSet&lt;AddFlag&gt;,String,Object)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#queries(Object...) queries(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#queries(AddFlag,Object...) queries(EnumSet&lt;AddFlag&gt;,Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#queryPairs(Object...) queryPairs(Object...)}
	 * 				<li class='jm'>{@link org.apache.juneau.rest.client.RestRequest#queryCustom(Object) queryCustom(Object)}
	 * 			</ul>
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Query parameters to add to every request.
	 */
	public static final String RESTCLIENT_query = PREFIX + "query.lo";

	/**
	 * Configuration property:  Root URI.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.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.client.RestClientBuilder#rootUri(Object)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * When set, relative URI 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 URI is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URI string.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that uses UON format by default for HTTP parts.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.rootUri(<js>"http://localhost:10000/foo"</js>)
	 * 		.build();
	 *
	 * 	Bar <jv>bar</jv> = <jv>client</jv>
	 * 		.get(<js>"/bar"</js>)  <jc>// Relative to http://localhost:10000/foo</jc>
	 * 		.run()
	 * 		.getBody().as(Bar.<jk>class</jk>);
	 * </p>
	 */
	public static final String RESTCLIENT_rootUri = PREFIX + "rootUri.s";

	/**
	 * Configuration property:  Serializers.
	 *
	 * <h5 class='section'>Property:</h5>
	 * <ul class='spaced-list'>
	 * 	<li><b>ID:</b>  {@link org.apache.juneau.rest.client.RestClient#RESTCLIENT_serializers RESTCLIENT_serializers}
	 * 	<li><b>Name:</b>  <js>"RestClient.serializers.lo"</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>  No serializers.
	 * 	<li><b>Methods:</b>
	 * 		<ul>
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#serializer(Class)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#serializer(Serializer)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#serializers(Class...)}
	 * 			<li class='jm'>{@link org.apache.juneau.rest.client.RestClientBuilder#serializers(Serializer...)}
	 * 		</ul>
	 * </ul>
	 *
	 * <h5 class='section'>Description:</h5>
	 * <p>
	 * Associates the specified {@link Serializer Serializers} with the HTTP client.
	 *
	 * <p>
	 * The serializer is used to serialize POJOs into the HTTP request body.
	 *
	 * <p>
	 * The serializer that best matches the <c>Content-Type</c> header will be used to serialize the request body.
	 * <br>If no <c>Content-Type</c> header is specified, the first serializer in the list will be used.
	 *
	 * <h5 class='section'>Example:</h5>
	 * <p class='bcode w800'>
	 * 	<jc>// Create a client that uses JSON and XML transport for request bodies.</jc>
	 * 	RestClient <jv>client</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.serializers(JsonSerializer.<jk>class</jk>,XmlSerializer.<jk>class</jk>)
	 * 		.sortCollections()  <jc>// Sort any collections being serialized.</jc>
	 * 		.build();
	 * </p>
	 */
	public static final String RESTCLIENT_serializers = PREFIX + "serializers.lo";

	static final String RESTCLIENT_httpClient = PREFIX + "httpClient.o";
	static final String RESTCLIENT_httpClientBuilder= PREFIX + "httpClientBuilder.o";

	private final HeaderList headers;
	private final PartList query, formData;
	final CloseableHttpClient httpClient;
	private final HttpClientConnectionManager connectionManager;
	private final boolean keepHttpClientOpen, 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 rootUri;
	private volatile boolean isClosed = false;
	private final StackTraceElement[] creationStack;
	private final Logger logger;
	final DetailLevel logRequests;
	final BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
	final Level logRequestsLevel;
	final boolean ignoreErrors;
	private final boolean logToConsole;
	private final PrintStream console;
	private StackTraceElement[] closedStack;
	private static final ConcurrentHashMap<Class<?>,Context> requestContexts = new ConcurrentHashMap<>();

	// These are read directly by RestCall.
	final SerializerGroup serializers;
	final ParserGroup parsers;
	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();
	}

	@Override /* Context */
	public RestClientBuilder copy() {
		return new RestClientBuilder(this);
	}

	private static final
		Predicate<Integer> ERROR_CODES_DEFAULT = x ->  x<=0 || x>=400;

	private static final
		BiPredicate<RestRequest,RestResponse> LOG_REQUESTS_PREDICATE_DEFAULT = (req,res) -> true;

	/**
	 * Constructor.
	 *
	 * @param cp The property store containing the unmodifiable configuration for this client.
	 */
	@SuppressWarnings("unchecked")
	protected RestClient(ContextProperties cp) {
		super(cp);
		this.httpClient = cp.getInstance(RESTCLIENT_httpClient, CloseableHttpClient.class).orElse(null);
		this.connectionManager = cp.getInstance(RESTCLIENT_connectionManager, HttpClientConnectionManager.class).orElse(null);
		this.keepHttpClientOpen = cp.getBoolean(RESTCLIENT_keepHttpClientOpen).orElse(false);
		this.errorCodes = cp.getInstance(RESTCLIENT_errorCodes, Predicate.class).orElse(ERROR_CODES_DEFAULT);
		this.executorServiceShutdownOnClose = cp.getBoolean(RESTCLIENT_executorServiceShutdownOnClose).orElse(false);
		this.rootUri = StringUtils.nullIfEmpty(cp.getString(RESTCLIENT_rootUri).orElse("").replaceAll("\\/$", ""));
		this.leakDetection = cp.getBoolean(RESTCLIENT_leakDetection).orElse(isDebug());
		this.ignoreErrors = cp.getBoolean(RESTCLIENT_ignoreErrors).orElse(false);
		this.logger = cp.getInstance(RESTCLIENT_logger, Logger.class).orElseGet(()->Logger.getLogger(RestClient.class.getName()));
		this.logRequests = cp.getInstance(RESTCLIENT_logRequests, DetailLevel.class).orElse(isDebug() ? DetailLevel.FULL : DetailLevel.NONE);
		this.logRequestsLevel = cp.getInstance(RESTCLIENT_logRequestsLevel, Level.class).orElse(isDebug() ? Level.WARNING : Level.OFF);
		this.logToConsole = cp.getBoolean(RESTCLIENT_logToConsole).orElse(isDebug());
		this.console = cp.getInstance(RESTCLIENT_console, PrintStream.class).orElse(System.err);
		this.logRequestsPredicate = cp.getInstance(RESTCLIENT_logRequestsPredicate, BiPredicate.class).orElse(LOG_REQUESTS_PREDICATE_DEFAULT);

		SerializerGroupBuilder sgb = SerializerGroup.create();
		for (Object o : cp.getArray(RESTCLIENT_serializers, Object.class).orElse(new Object[0])) {
			if (o instanceof Serializer) {
				sgb.append((Serializer)o);  // Don't apply ContextProperties.
			} else if (o instanceof Class) {
				Class<?> c = (Class<?>)o;
				if (! Serializer.class.isAssignableFrom(c))
					throw new ConfigException("RESTCLIENT_serializers property had invalid class of type ''{0}''", className(c));
				sgb.append(ContextCache.INSTANCE.create((Class<? extends Serializer>)o, cp));
			} else {
				throw new ConfigException("RESTCLIENT_serializers property had invalid object of type ''{0}''", className(o));
			}
		}
		this.serializers = sgb.build();

		ParserGroupBuilder pgb = ParserGroup.create();
		for (Object o : cp.getArray(RESTCLIENT_parsers, Object.class).orElse(new Object[0])) {
			if (o instanceof Parser) {
				pgb.append((Parser)o);  // Don't apply ContextProperties.
			} else if (o instanceof Class) {
				Class<?> c = (Class<?>)o;
				if (! Parser.class.isAssignableFrom(c))
					throw new ConfigException("RESTCLIENT_parsers property had invalid class of type ''{0}''", className(c));
				pgb.append(ContextCache.INSTANCE.create((Class<? extends Parser>)o, cp));
			} else {
				throw new ConfigException("RESTCLIENT_parsers property had invalid object of type ''{0}''", className(o));
			}
		}
		this.parsers = pgb.build();

		BeanStore bs = new BeanStore()
			.addBean(ContextProperties.class, cp)
			.addBean(RestClient.class, this);

		this.urlEncodingSerializer = UrlEncodingSerializer.create().apply(cp).build();
		this.partSerializer = cp.getInstance(RESTCLIENT_partSerializer, HttpPartSerializer.class, bs).orElseGet(bs.createBeanSupplier(OpenApiSerializer.class));
		this.partParser = cp.getInstance(RESTCLIENT_partParser, HttpPartParser.class, bs).orElseGet(bs.createBeanSupplier(OpenApiParser.class));
		this.executorService = cp.getInstance(RESTCLIENT_executorService, ExecutorService.class).orElse(null);

		HttpPartSerializerSession partSerializerSession = partSerializer.createPartSession(null);

		HeaderListBuilder headers = HeaderList.create();
		for (Object o : cp.getList(RESTCLIENT_headers, Object.class).orElse(emptyList())) {
			o = buildBuilders(o, partSerializerSession);
			if (o instanceof HeaderList)
				headers.append(((HeaderList)o));
			else
				headers.append(HttpHeaders.cast(o));
		}
		this.headers = headers.build();

		PartListBuilder query = PartList.create();
		for (Object o : cp.getList(RESTCLIENT_query, Object.class).orElse(emptyList())) {
			o = buildBuilders(o, partSerializerSession);
			if (o instanceof PartList)
				query.append((PartList)o);
			else
				query.append(BasicPart.cast(o));
		}
		this.query = query.build();

		PartListBuilder formData = PartList.create();
		for (Object o : cp.getList(RESTCLIENT_formData, Object.class).orElse(emptyList())) {
			o = buildBuilders(o, partSerializerSession);
			if (o instanceof PartList)
				formData.append((PartList)o);
			else
				formData.append(BasicPart.cast(o));
		}
		this.formData = formData.build();

		this.callHandler = cp.getInstance(RESTCLIENT_callHandler, RestCallHandler.class, bs).orElseGet(bs.createBeanSupplier(BasicRestCallHandler.class));

		this.interceptors = cp.getInstanceArray(RESTCLIENT_interceptors, RestCallInterceptor.class).orElse(new RestCallInterceptor[0]);

		creationStack = isDebug() ? Thread.currentThread().getStackTrace() : null;
	}

	private static Object buildBuilders(Object o, HttpPartSerializerSession ss) {
		if (o instanceof SerializedHeader)
			return ((SerializedHeader)o).copyWith(ss, null);
		if (o instanceof SerializedPart)
			return ((SerializedPart)o).copy().copyWith(ss, null);
		return o;
	}

	/**
	 * 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 (! 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 (! keepHttpClientOpen)
				httpClient.close();
			if (executorService != null && executorServiceShutdownOnClose)
				executorService.shutdown();
		} catch (Throwable t) {}
		if (creationStack != null)
			closedStack = Thread.currentThread().getStackTrace();
	}

	/**
	 * Entrypoint for executing all requests and returning a response.
	 *
	 * <p>
	 * Subclasses can override this method to provide specialized handling.
	 *
	 * <p>
	 * The behavior of this method can also be modified by specifying a different {@link RestCallHandler}.
	 *
	 * <ul class='seealso'>
	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_callHandler}
	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(Class)}
	 * 	<li class='jm'>{@link RestClientBuilder#callHandler(RestCallHandler)}
	 * </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 /* RestCallHandler */
	public HttpResponse run(HttpHost target, HttpRequest request, HttpContext context) throws ClientProtocolException, IOException {
		return callHandler.run(target, request, context);
	}

	/**
	 * Perform a <c>GET</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("GET", uri));
	}

	/**
	 * Perform a <c>GET</c> request against the root URI.
	 *
	 * @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() throws RestCallException {
		return request(op("GET", null));
	}

	/**
	 * Perform a <c>PUT</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request.
	 * 	Can be of the following types:
	 * 	<ul class='spaced-list'>
	 * 		<li>
	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
	 * 			{@link RestClient}.
	 * 		<li>
	 * 			{@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
	 * 		<li>
	 * 			{@link PartList} - Converted to a URL-encoded FORM post.
	 * 		<li>
	 * 			{@link Supplier} - A supplier of anything on this list.
	 * 	</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 uri, Object body) throws RestCallException {
		return request(op("PUT", uri, body));
	}

	/**
	 * Perform a <c>PUT</c> request against the specified URI using a plain text body bypassing the serializer.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
	 * @param contentType The content type of the request.
	 * @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 uri, String body, String contentType) throws RestCallException {
		return request(op("PUT", uri, stringBody(body))).contentType(contentType);
	}

	/**
	 * 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 uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("PUT", uri));
	}

	/**
	 * Perform a <c>POST</c> request against the specified URI.
	 *
	 * <ul class='notes'>
	 * 	<li>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
	 * </ul>
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request.
	 * 	Can be of the following types:
	 * 	<ul class='spaced-list'>
	 * 		<li>
	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
	 * 			{@link RestClient}.
	 * 		<li>
	 * 			{@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
	 * 		<li>
	 * 			{@link PartList} - Converted to a URL-encoded FORM post.
	 * 		<li>
	 * 			{@link Supplier} - A supplier of anything on this list.
	 * 	</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 uri, Object body) throws RestCallException {
		return request(op("POST", uri, body));
	}

	/**
	 * Perform a <c>POST</c> request against the specified URI as a plain text body bypassing the serializer.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
	 * @param contentType
	 * 	The content type of the request.
	 * @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 uri, String body, String contentType) throws RestCallException {
		return request(op("POST", uri, stringBody(body))).contentType(contentType);
	}

	/**
	 * 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 uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("POST", uri));
	}

	/**
	 * Perform a <c>DELETE</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("DELETE", uri));
	}

	/**
	 * Perform an <c>OPTIONS</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("OPTIONS", uri));
	}

	/**
	 * Perform a <c>HEAD</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 head(Object uri) throws RestCallException {
		return request(op("HEAD", uri));
	}

	/**
	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
	 * against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request.
	 * 	<ul class='spaced-list'>
	 * 		<li>{@link NameValuePair} - URL-encoded as a single name-value pair.
	 * 		<li>{@link NameValuePair} array - URL-encoded as name value pairs.
	 * 		<li>{@link PartList} - URL-encoded as name value pairs.
	 * 		<li>{@link Reader}/{@link InputStream}- Streamed directly and <l>Content-Type</l> set to <js>"application/x-www-form-urlencoded"</js>
	 * 		<li>{@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
	 * 		<li>{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
	 * 		<li>{@link Object} - Converted to a {@link SerializedEntity} using {@link UrlEncodingSerializer} to serialize.
	 * 		<li>{@link Supplier} - A supplier of anything on this list.
	 * 	</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 uri, Object body) throws RestCallException {
		RestRequest req = request(op("POST", uri));
		try {
			if (body instanceof Supplier)
				body = ((Supplier<?>)body).get();
			if (body instanceof NameValuePair)
				return req.body(new UrlEncodedFormEntity(AList.of((NameValuePair)body)));
			if (body instanceof NameValuePair[])
				return req.body(new UrlEncodedFormEntity(Arrays.asList((NameValuePair[])body)));
			if (body instanceof PartList)
				return req.body(new UrlEncodedFormEntity(((PartList)body).asNameValuePairs()));
			if (body instanceof HttpResource)
				((HttpResource)body).getHeaders().forEach(x-> req.header(x));
			if (body instanceof HttpEntity) {
				HttpEntity e = (HttpEntity)body;
				if (e.getContentType() == null)
					req.contentType("application/x-www-form-urlencoded");
				return req.body(e);
			}
			if (body instanceof Reader || body instanceof InputStream)
				return req.contentType("application/x-www-form-urlencoded").body(body);
			return req.body(serializedEntity(body, urlEncodingSerializer, null).build());
		} catch (IOException e) {
			throw new RestCallException(null, e, "Could not read form post body.");
		}
	}

	/**
	 * Same as {@link #formPost(Object, Object)} but doesn't specify the input yet.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("POST", uri));
	}

	/**
	 * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
	 * against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 BasicPart} 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 formPostPairs(Object uri, Object...parameters) throws RestCallException {
		return formPost(uri, partList(parameters));
	}

	/**
	 * Perform a <c>PATCH</c> request against the specified URI.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request.
	 * 	Can be of the following types:
	 * 	<ul class='spaced-list'>
	 * 		<li>
	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
	 * 		<li>
	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
	 * 		<li>
	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
	 * 			{@link RestClient}.
	 * 		<li>
	 * 			{@link PartList} - Converted to a URL-encoded FORM post.
	 * 		<li>
	 * 			{@link Supplier} - A supplier of anything on this list.
	 * 	</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 uri, Object body) throws RestCallException {
		return request(op("PATCH", uri, body));
	}

	/**
	 * Perform a <c>PATCH</c> request against the specified URI as a plain text body bypassing the serializer.
	 *
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
	 * 	</ul>
	 * @param body
	 * 	The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
	 * @param contentType
	 * 	The content type of the request.
	 * @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 uri, String body, String contentType) throws RestCallException {
		return request(op("PATCH", uri, stringBody(body))).contentType(contentType);
	}

	/**
	 * 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 uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri) throws RestCallException {
		return request(op("PATCH", uri));
	}


	/**
	 * 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] [uri]"</js> - e.g. <js>"GET http://localhost/callback"</js>
	 * 	<li>
	 * 		<js>"[method] [uri] [payload]"</js> - e.g. <js>"POST http://localhost/callback some text payload"</js>
	 * 	<li>
	 * 		<js>"[method] [headers] [uri] [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 {
		callString = emptyIfNull(callString);

		// S01 - Looking for end of method.
		// S02 - Found end of method, looking for beginning of URI or headers.
		// S03 - Found beginning of headers, looking for end of headers.
		// S04 - Found end of headers, looking for beginning of URI.
		// S05 - Found beginning of URI, looking for end of URI.

		StateMachineState state = S01;

		int mark = 0;
		String method = null, headers = null, uri = null, content = null;
		for (int i = 0; i < callString.length(); i++) {
			char c = callString.charAt(i);
			if (state == S01) {
				if (isWhitespace(c)) {
					method = callString.substring(mark, i);
					state = S02;
				}
			} else if (state == S02) {
				if (! isWhitespace(c)) {
					mark = i;
					if (c == '{')
						state = S03;
					else
						state = S05;
				}
			} else if (state == S03) {
				if (c == '}') {
					headers = callString.substring(mark, i+1);
					state = S04;
				}
			} else if (state == S04) {
				if (! isWhitespace(c)) {
					mark = i;
					state = S05;
				}
			} else /* (state == S05) */ {
				if (isWhitespace(c)) {
					uri = callString.substring(mark, i);
					content = callString.substring(i).trim();
					break;
				}
			}
		}

		if (state != S05)
			throw new RestCallException(null, null, "Invalid format for call string.  State={0}", state);

		try {
			RestRequest req = request(method, uri, isNotEmpty(content));
			if (headers != null)
				for (Map.Entry<String,Object> e : OMap.ofJson(headers).entrySet())
					req.header(stringHeader(e.getKey(), stringify(e.getValue())));
			if (isNotEmpty(content))
				req.bodyString(content);
			return req;
		} catch (ParseException e) {
			throw new RestCallException(null, e, "Invalid format for call string.");
		}
	}

	/**
	 * Perform a generic REST call.
	 *
	 * @param method The HTTP method.
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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>
	 * 			{@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
	 * 		<li>
	 * 			{@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
	 * 		<li>
	 * 			{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
	 * 		<li>
	 * 			{@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
	 * 			{@link RestClient}.
	 * 		<li>
	 * 			{@link PartList} - Converted to a URL-encoded FORM post.
	 * 		<li>
	 * 			{@link Supplier} - A supplier of anything on this list.
	 * 	</ul>
	 * 	This parameter is IGNORED if the method type normally does not have content.
	 * @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 uri, Object body) throws RestCallException {
		return request(op(method, uri, body));
	}

	/**
	 * Perform a generic REST call.
	 *
	 * @param method The HTTP method.
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 request(String method, Object uri) throws RestCallException {
		return request(op(method, uri));
	}

	/**
	 * Perform a generic REST call.
	 *
	 * <p>
	 * Typically you're going to use {@link #request(String, Object)} or {@link #request(String, Object, Object)},
	 * but this method is provided to allow you to perform non-standard HTTP methods (e.g. HTTP FOO).
	 *
	 * @param method The method name (e.g. <js>"GET"</js>, <js>"OPTIONS"</js>).
	 * @param uri
	 * 	The URI of the remote REST resource.
	 * 	<br>Can be any of the following types:
	 * 	<ul>
	 * 		<li>{@link URIBuilder}
	 * 		<li>{@link URI}
	 * 		<li>{@link URL}
	 * 		<li>{@link String}
	 * 		<li>{@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 uri, boolean hasBody) throws RestCallException {
		return request(op(method, uri).hasBody(hasBody));
	}

	/**
	 * Perform an arbitrary request against the specified URI.
	 *
	 * @param op The operation that identifies the HTTP method, URL, and optional payload.
	 * @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(RestOperation op) throws RestCallException {
		if (isClosed) {
			Exception e2 = null;
			if (closedStack != null) {
				e2 = new Exception("Creation stack:");
				e2.setStackTrace(closedStack);
				throw new RestCallException(null, e2, "RestClient.close() has already been called.  This client cannot be reused.");
			}
			throw new RestCallException(null, null, "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 = createRequest(toURI(op.getUri(), rootUri), op.getMethod(), op.hasBody());

		headers.forEach(x -> req.header(APPEND, x));

		query.forEach(x -> req.query(APPEND, x.getName(), x.getValue()));

		formData.forEach(x -> req.formData(APPEND, x.getName(), x.getValue()));

		onInit(req);

		if (op.hasBody())
			req.body(op.getBody());

		return req;
	}

	/**
	 * Creates a {@link RestRequest} object from the specified {@link HttpRequest} object.
	 *
	 * <p>
	 * Subclasses can override this method to provide their own specialized {@link RestRequest} objects.
	 *
	 * @param uri The target.
	 * @param method The HTTP method (uppercase).
	 * @param hasBody Whether this method has a request entity.
	 * @return A new {@link RestRequest} object.
	 * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
	 */
	protected RestRequest createRequest(URI uri, String method, boolean hasBody) throws RestCallException {
		return new RestRequest(this, uri, method, hasBody);
	}

	/**
	 * Creates a {@link RestResponse} object from the specified {@link HttpResponse} object.
	 *
	 * <p>
	 * Subclasses can override this method to provide their own specialized {@link RestResponse} objects.
	 *
	 * @param request The request creating this response.
	 * @param httpResponse The response object to wrap.
	 * @param parser The parser to use to parse the response.
	 *
	 * @return A new {@link RestResponse} object.
	 * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
	 */
	protected RestResponse createResponse(RestRequest request, HttpResponse httpResponse, Parser parser) throws RestCallException {
		return new RestResponse(this, request, httpResponse, parser);
	}

	/**
	 * Create a new proxy interface against a 3rd-party REST interface.
	 *
	 * <p>
	 * The URI 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#rootUri(Object) rootUri} on the client (<c>root-url</c>).
	 * 	<li>The fully-qualified class name of the interface (<c>class-name</c>).
	 * </ul>
	 *
	 * <p>
	 * The URI calculation is as follows:
	 * <ul>
	 * 	<li><c>remote-path</c> - If remote path is absolute.
	 * 	<li><c>root-uri/remote-path</c> - If remote path is relative and root-uri has been specified.
	 * 	<li><c>root-uri/class-name</c> - If remote path is not specified.
	 * </ul>
	 *
	 * <p>
	 * If the information is not available to resolve to an absolute URI, a {@link RemoteMetadataException} is thrown.
	 *
	 * <h5 class='section'>Examples:</h5>
	 * <p class='bcode w800'>
	 * 	<jk>package</jk> <jk>org.apache.foo</jk>;
	 *
	 * 	<ja>@RemoteResource</ja>(path=<js>"http://hostname/resturi/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/resturi/myinterface1"</jc>
	 * 	MyInterface1 <jv>i1</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.build()
	 * 		.getRemote(MyInterface1.<jk>class</jk>);
	 *
	 * 	<jc>// Resolves to "http://hostname/resturi/myinterface2"</jc>
	 * 	MyInterface2 <jv>i2</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.rootUri(<js>"http://hostname/resturi"</js>)
	 * 		.build()
	 * 		.getRemote(MyInterface2.<jk>class</jk>);
	 *
	 * 	<jc>// Resolves to "http://hostname/resturi/org.apache.foo.MyInterface3"</jc>
	 * 	MyInterface3 <jv>i3</jv> = RestClient
	 * 		.<jsm>create</jsm>()
	 * 		.rootUri(<js>"http://hostname/resturi"</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 RestcProxies}
	 * </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(Class<T> interfaceClass) {
		return getRemote(interfaceClass, null);
	}

	/**
	 * Same as {@link #getRemote(Class)} except explicitly specifies the URI of the REST interface.
	 *
	 * <ul class='seealso'>
	 * 	<li class='link'>{@doc RestcProxies}
	 * </ul>
	 *
	 * @param interfaceClass The interface to create a proxy for.
	 * @param rootUri The URI of the REST interface.
	 * @return The new proxy interface.
	 */
	public <T> T getRemote(Class<T> interfaceClass, Object rootUri) {
		return getRemote(interfaceClass, rootUri, null, null);
	}

	/**
	 * Same as {@link #getRemote(Class, Object)} but allows you to override the serializer and parser used.
	 *
	 * <ul class='seealso'>
	 * 	<li class='link'>{@doc RestcProxies}
	 * </ul>

	 * @param interfaceClass The interface to create a proxy for.
	 * @param rootUri The URI 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 rootUri, final Serializer serializer, final Parser parser) {

		if (rootUri == null)
			rootUri = this.rootUri;

		final String restUrl2 = trimSlashes(emptyIfNull(rootUri));

		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 {
					RemoteOperationMeta rom = rm.getOperationMeta(method);

					String uri = rom.getFullPath();
					if (uri.indexOf("://") == -1)
						uri = restUrl2 + '/' + uri;
					if (uri.indexOf("://") == -1)
						throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote resource.");

					String httpMethod = rom.getHttpMethod();
					HttpPartSerializerSession s = getPartSerializerSession();

					RestRequest rc = request(httpMethod, uri, hasContent(httpMethod));

					rc.serializer(serializer);
					rc.parser(parser);

					rm.getHeaders().forEach(x -> rc.header(APPEND, x));

					for (RemoteOperationArg a : rom.getPathArgs())
						rc.pathArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));

					for (RemoteOperationArg a : rom.getQueryArgs())
						rc.queryArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));

					for (RemoteOperationArg a : rom.getFormDataArgs())
						rc.formDataArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));

					for (RemoteOperationArg a : rom.getHeaderArgs())
						rc.headerArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));

					RemoteOperationArg ba = rom.getBodyArg();
					if (ba != null)
						rc.body(args[ba.getIndex()], ba.getSchema());

					if (rom.getRequestArgs().length > 0) {
						for (RemoteOperationBeanArg rmba : rom.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();
									HttpPartSerializerSession ps = p.getSerializer(s);
									String pn = p.getPartName();
									HttpPartSchema schema = p.getSchema();
									EnumSet<AddFlag> flags = schema.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS;
									if (pt == PATH)
										rc.pathArg(pn, val, schema, p.getSerializer(s));
									else if (val != null) {
										if (pt == QUERY)
											rc.queryArg(flags, pn, val, schema, ps);
										else if (pt == FORMDATA)
											rc.formDataArg(flags, pn, val, schema, ps);
										else if (pt == HEADER)
											rc.headerArg(flags, pn, val, schema, ps);
										else /* (pt == HttpPartType.BODY) */
											rc.body(val, schema);
									}
								}
							}
						}
					}

					RemoteOperationReturn ror = rom.getReturns();
					if (ror.isFuture()) {
						return getExecutorService().submit(new Callable<Object>() {
							@Override
							public Object call() throws Exception {
								try {
									return executeRemote(interfaceClass, rc, method, rom);
								} catch (Exception e) {
									throw e;
								} catch (Throwable e) {
									throw runtimeException(e);
								}
							}
						});
					} else if (ror.isCompletableFuture()) {
						CompletableFuture<Object> cf = new CompletableFuture<>();
						getExecutorService().submit(new Callable<Object>() {
							@Override
							public Object call() throws Exception {
								try {
									cf.complete(executeRemote(interfaceClass, rc, method, rom));
								} catch (Throwable e) {
									cf.completeExceptionally(e);
								}
								return null;
							}
						});
						return cf;
					}

					return executeRemote(interfaceClass, rc, method, rom);
				}
		});
	}

	static Consumer<Header> wrapper(Consumer<Header> consumer) {
		return i -> {
			try {
				consumer.accept(i);
			} catch (Exception e) {
				throw runtimeException(e);
			}
		};
	}

	Object executeRemote(Class<?> interfaceClass, RestRequest rc, Method method, RemoteOperationMeta rom) throws Throwable {
		RemoteOperationReturn ror = rom.getReturns();

		try {
			Object ret = null;
			RestResponse res = null;
			rc.rethrow(RuntimeException.class).rethrow(rom.getExceptions());
			if (ror.getReturnValue() == RemoteReturn.NONE) {
				res = rc.complete();
			} else if (ror.getReturnValue() == RemoteReturn.STATUS) {
				res = rc.complete();
				int returnCode = res.getStatusCode();
				Class<?> rt = method.getReturnType();
				if (rt == Integer.class || rt == int.class)
					ret = returnCode;
				else if (rt == Boolean.class || rt == boolean.class)
					ret = returnCode < 400;
				else
					throw new RestCallException(res, null, "Invalid return type on method annotated with @RemoteOp(returns=RemoteReturn.STATUS).  Only integer and booleans types are valid.");
			} else if (ror.getReturnValue() == RemoteReturn.BEAN) {
				rc.ignoreErrors();
				res = rc.run();
				ret = res.as(ror.getResponseBeanMeta());
			} else {
				Class<?> rt = method.getReturnType();
				if (Throwable.class.isAssignableFrom(rt))
					rc.ignoreErrors();
				res = rc.run();
				Object v = res.getBody().asType(ror.getReturnType());
				if (v == null && rt.isPrimitive())
					v = ClassInfo.of(rt).getPrimitiveDefault();
				ret = v;
			}
			return ret;
		} catch (RestCallException e) {
			Throwable t = e.getCause();
			if (t instanceof RuntimeException)
				throw t;
			for (Class<?> t2 : method.getExceptionTypes())
				if (t2.isInstance(t))
					throw t;
			throw runtimeException(e);
		}
	}

	/**
	 * Create a new proxy interface against an RRPC-style service.
	 *
	 * <p>
	 * Remote interfaces are interfaces exposed on the server side using either the <c>RrpcServlet</c>
	 * or <c>RRPC</c> REST methods.
	 *
	 * <p>
	 * The URI 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#rootUri(Object) rootUri} on the client (<c>root-url</c>).
	 * 	<li>The fully-qualified class name of the interface (<c>class-name</c>).
	 * </ul>
	 *
	 * <p>
	 * The URI 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 URI, 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 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 URI of the REST interface.
	 *
	 * <ul class='seealso'>
	 * 	<li class='link'>{@doc RestRpc}
	 * </ul>
	 *
	 * @param interfaceClass The interface to create a proxy for.
	 * @param uri The URI of the REST interface.
	 * @return The new proxy interface.
	 */
	public <T> T getRrpcInterface(final Class<T> interfaceClass, final Object uri) {
		return getRrpcInterface(interfaceClass, uri, null, null);
	}

	/**
	 * Same as {@link #getRrpcInterface(Class, Object)} but allows you to override the serializer and parser used.
	 *
	 * <ul class='seealso'>
	 * 	<li class='link'>{@doc RestRpc}
	 * </ul>
	 *
	 * @param interfaceClass The interface to create a proxy for.
	 * @param uri The URI 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 uri, final Serializer serializer, final Parser parser) {

		if (uri == null) {
			RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, "");
			String path = rm.getPath();
			if (path.indexOf("://") == -1) {
				if (isEmpty(rootUri))
					throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote interface.");
				path = trimSlashes(rootUri) + '/' + path;
			}
			uri = path;
		}

		final String restUrl2 = stringify(uri);

		return (T)Proxy.newProxyInstance(
			interfaceClass.getClassLoader(),
			new Class[] { interfaceClass },
			new InvocationHandler() {

				final RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, restUrl2);

				@Override /* InvocationHandler */
				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					RrpcInterfaceMethodMeta rim = rm.getMethodMeta(method);

					String uri = rim.getUri();
					RestResponse res = null;

					try {
						RestRequest rc = request("POST", uri, true)
							.serializer(serializer)
							.body(args)
							.rethrow(RuntimeException.class)
							.rethrow(method.getExceptionTypes());

						res = rc.run();

						Object v = res.getBody().asType(method.getGenericReturnType());
						if (v == null && method.getReturnType().isPrimitive())
							v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
						return v;

					} catch (Throwable e) {
						if (e instanceof RestCallException) {
							Throwable t = e.getCause();
							if (t != null)
								e = t;
						}
						if (e instanceof RuntimeException)
							throw e;
						for (Class<?> t2 : method.getExceptionTypes())
							if (t2.isInstance(e))
								throw e;
						throw runtimeException(e);
					}
				}
		});
	}

	@Override
	protected void finalize() throws Throwable {
		if (leakDetection && ! isClosed && ! keepHttpClientOpen) {
			StringBuilder sb = new StringBuilder("WARNING:  RestClient garbage collected before it was finalized.");  // NOT DEBUG
			if (creationStack != null) {
				sb.append("\nCreation Stack:");  // NOT DEBUG
				for (StackTraceElement e : creationStack)
					sb.append("\n\t" + e);  // NOT DEBUG
			}
			log(WARNING, sb.toString());
		}
	}

	/**
	 * Logs a message.
	 *
	 * @param level The log level.
	 * @param t Thrown exception.  Can be <jk>null</jk>.
	 * @param msg The message.
	 * @param args Optional message arguments.
	 */
	protected void log(Level level, Throwable t, String msg, Object...args) {
		logger.log(level, t, msg(msg, args));
		if (logToConsole) {
			console.println(msg(msg, args).get());
			if (t != null)
				t.printStackTrace(console);
		}
	}

	/**
	 * Logs a message.
	 *
	 * @param level The log level.
	 * @param msg The message with {@link MessageFormat}-style arguments.
	 * @param args The arguments.
	 */
	protected void log(Level level, String msg, Object...args) {
		logger.log(level, msg(msg, args));
		if (logToConsole)
			console.println(msg(msg, args).get());
	}

	private Supplier<String> msg(String msg, Object...args) {
		return ()->args.length == 0 ? msg : MessageFormat.format(msg, args);
	}


	//-----------------------------------------------------------------------------------------------------------------
	// RestCallInterceptor methods
	//-----------------------------------------------------------------------------------------------------------------

	/**
	 * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been copied from the client.
	 *
	 * <p>
	 * Subclasses can override this method to intercept the request and perform special modifications.
	 *
	 * <ul class='seealso'>
	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Object...)}
	 * </ul>
	 *
	 * @param req The HTTP request.
	 * @throws RestCallException If any of the interceptors threw an exception.
	 */
	@Override
	public void onInit(RestRequest req) throws RestCallException {
		try {
			for (RestCallInterceptor rci : interceptors)
				rci.onInit(req);
		} catch (RuntimeException | RestCallException e) {
			throw e;
		} catch (Exception e) {
			throw new RestCallException(null, e, "Interceptor threw an exception on init.");
		}
	}

	/**
	 * Interceptor method called immediately after an HTTP response has been received.
	 *
	 * <p>
	 * Subclasses can override this method to intercept the response and perform special modifications.
	 *
	 * <ul class='seealso'>
	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Object...)}
	 * </ul>
	 *
	 * @param req The HTTP request.
	 * @param res The HTTP response.
	 * @throws RestCallException If any of the interceptors threw an exception.
	 */
	@Override
	public void onConnect(RestRequest req, RestResponse res) throws RestCallException {
		try {
			for (RestCallInterceptor rci : interceptors)
				rci.onConnect(req, res);
		} catch (RuntimeException | RestCallException e) {
			throw e;
		} catch (Exception e) {
			throw new RestCallException(res, e, "Interceptor threw an exception on connect.");
		}
	}

	/**
	 * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been set on the request from the client.
	 *
	 * <p>
	 * Subclasses can override this method to handle any cleanup operations.
	 *
	 * <ul class='seealso'>
	 * 	<li class='jf'>{@link RestClient#RESTCLIENT_interceptors}
	 * 	<li class='jm'>{@link RestClientBuilder#interceptors(Object...)}
	 * </ul>
	 *
	 * @param req The HTTP request.
	 * @param res The HTTP response.
	 * @throws RestCallException If any of the interceptors threw an exception.
	 */
	@Override
	public void onClose(RestRequest req, RestResponse res) throws RestCallException {
		try {
			for (RestCallInterceptor rci : interceptors)
				rci.onClose(req, res);
		} catch (RuntimeException | RestCallException e) {
			throw e;
		} catch (Exception e) {
			throw new RestCallException(res, e, "Interceptor threw an exception on close.");
		}
	}

	//------------------------------------------------------------------------------------------------
	// 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();
	}

	/**
	 * Returns the connection manager if one was specified in the client builder.
	 *
	 * @return The connection manager.  May be <jk>null</jk>.
	 */
	public HttpClientConnectionManager getHttpClientConnectionManager() {
		return connectionManager;
	}

	/**
	 * 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 #run(HttpHost,HttpRequest,HttpContext)} method has been provided as a wrapper 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.
	 * @throws ClientProtocolException In case of an http protocol error.
	 */
	@Override /* HttpClient */
	public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
		return httpClient.execute(request, responseHandler, context);
	}

	/**
	 * Executes HTTP request to the target 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 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 responseHandler The response handler.
	 * @return The response object as generated by the 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(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
		return httpClient.execute(target, request, responseHandler);
	}

	/**
	 * Executes a 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 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 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.
	 * @throws ClientProtocolException In case of an http protocol error.
	 */
	@Override /* HttpClient */
	public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
		return httpClient.execute(target, request, responseHandler, context);
	}

	//-----------------------------------------------------------------------------------------------------------------
	// Other methods.
	//-----------------------------------------------------------------------------------------------------------------

	HttpPartSerializerSession getPartSerializerSession() {
		return partSerializer.createPartSession(null);
	}

	HttpPartParserSession getPartParserSession() {
		return partParser.createPartSession(null);
	}

	private Pattern absUrlPattern = Pattern.compile("^\\w+\\:\\/\\/.*");

	URI toURI(Object x, String rootUri) throws RestCallException {
		try {
			if (x instanceof URI)
				return (URI)x;
			if (x instanceof URL)
				((URL)x).toURI();
			if (x instanceof URIBuilder)
				return ((URIBuilder)x).build();
			String s = x == null ? "" : x.toString();
			if (rootUri != null && ! absUrlPattern.matcher(s).matches()) {
				if (s.isEmpty())
					s = rootUri;
				else {
					StringBuilder sb = new StringBuilder(rootUri);
					if (! s.startsWith("/"))
						sb.append('/');
					sb.append(s);
					s = sb.toString();
				}
			}
			s = fixUrl(s);
			return new URI(s);
		} catch (URISyntaxException e) {
			throw new RestCallException(null, e, "Invalid URI encountered:  {0}", x);  // Shouldn't happen.
		}
	}

	ExecutorService getExecutorService() {
		if (executorService != null)
			return executorService;
		synchronized(this) {
			executorService = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
			return executorService;
		}
	}

	/*
	 * Returns the serializer that best matches the specified content type.
	 * If no match found or the content type is null, returns the serializer in the list if it's a list of one.
	 * Returns null if no serializers are defined.
	 */
	Serializer getMatchingSerializer(String mediaType) {
		if (serializers.isEmpty())
			return null;
		if (mediaType != null) {
			Serializer s = serializers.getSerializer(mediaType);
			if (s != null)
				return s;
		}
		List<Serializer> l = serializers.getSerializers();
		return (l.size() == 1 ? l.get(0) : null);
	}

	boolean hasSerializers() {
		return ! serializers.getSerializers().isEmpty();
	}

	/*
	 * Returns the parser that best matches the specified content type.
	 * If no match found or the content type is null, returns the parser in the list if it's a list of one.
	 * Returns null if no parsers are defined.
	 */
	Parser getMatchingParser(String mediaType) {
		if (parsers.isEmpty())
			return null;
		if (mediaType != null) {
			Parser p = parsers.getParser(mediaType);
			if (p != null)
				return p;
		}
		List<Parser> l = parsers.getParsers();
		return (l.size() == 1 ? l.get(0) : null);
	}

	boolean hasParsers() {
		return ! parsers.getParsers().isEmpty();
	}

	@SuppressWarnings("unchecked")
	<T extends Context> T getInstance(Class<T> c) {
		Context o = requestContexts.get(c);
		if (o == null) {
			o = ContextCache.INSTANCE.create(c, getContextProperties());
			requestContexts.put(c, o);
		}
		return (T)o;
	}

	private RestOperation op(String method, Object url) {
		return RestOperation.of(method, url);
	}

	private RestOperation op(String method, Object url, Object body) {
		return RestOperation.of(method, url, body);
	}

	private Reader stringBody(String body) {
		return body == null ? null : new StringReader(stringify(body));
	}

	@Override /* Context */
	public OMap toMap() {
		return super.toMap()
			.a(
				"RestClient",
				OMap
					.create()
					.filtered()
					.a("errorCodes", errorCodes)
					.a("executorService", executorService)
					.a("executorServiceShutdownOnClose", executorServiceShutdownOnClose)
					.a("headers", headers)
					.a("interceptors", interceptors)
					.a("keepHttpClientOpen", keepHttpClientOpen)
					.a("partParser", partParser)
					.a("partSerializer", partSerializer)
					.a("query", query)
					.a("rootUri", rootUri)
			);
	}
}
