001// ***************************************************************************************************************************
002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.  See the NOTICE file *
003// * distributed with this work for additional information regarding copyright ownership.  The ASF licenses this file        *
004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance            *
005// * with the License.  You may obtain a copy of the License at                                                              *
006// *                                                                                                                         *
007// *  http://www.apache.org/licenses/LICENSE-2.0                                                                             *
008// *                                                                                                                         *
009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an  *
010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the        *
011// * specific language governing permissions and limitations under the License.                                              *
012// ***************************************************************************************************************************
013package org.apache.juneau.rest.client;
014
015import static org.apache.juneau.httppart.HttpPartType.*;
016import static org.apache.juneau.http.HttpMethod.*;
017import static org.apache.juneau.http.HttpHeaders.*;
018import static org.apache.juneau.http.HttpParts.*;
019import static org.apache.juneau.collections.JsonMap.*;
020import static org.apache.juneau.common.internal.ArgUtils.*;
021import static org.apache.juneau.common.internal.StringUtils.*;
022import static org.apache.juneau.common.internal.ThrowableUtils.*;
023import static org.apache.juneau.http.HttpEntities.*;
024import static org.apache.juneau.rest.client.RestOperation.*;
025import static java.util.logging.Level.*;
026import static org.apache.juneau.internal.CollectionUtils.*;
027import static org.apache.juneau.internal.StateMachineState.*;
028import static java.lang.Character.*;
029
030import java.io.*;
031import java.lang.annotation.Annotation;
032import java.lang.reflect.*;
033import java.lang.reflect.Proxy;
034import java.net.*;
035import java.nio.charset.*;
036import java.text.*;
037import java.util.*;
038import java.util.concurrent.*;
039import java.util.function.*;
040import java.util.logging.*;
041import java.util.regex.*;
042
043import javax.net.ssl.*;
044
045import org.apache.http.*;
046import org.apache.http.Header;
047import org.apache.http.auth.*;
048import org.apache.http.client.*;
049import org.apache.http.client.CookieStore;
050import org.apache.http.client.config.*;
051import org.apache.http.client.entity.*;
052import org.apache.http.client.methods.*;
053import org.apache.http.client.utils.*;
054import org.apache.http.config.*;
055import org.apache.http.conn.*;
056import org.apache.http.conn.routing.*;
057import org.apache.http.conn.socket.*;
058import org.apache.http.conn.util.*;
059import org.apache.http.cookie.*;
060import org.apache.http.impl.client.*;
061import org.apache.http.impl.conn.*;
062import org.apache.http.params.*;
063import org.apache.http.protocol.*;
064import org.apache.juneau.*;
065import org.apache.juneau.annotation.*;
066import org.apache.juneau.collections.*;
067import org.apache.juneau.cp.*;
068import org.apache.juneau.html.*;
069import org.apache.juneau.http.remote.RemoteReturn;
070import org.apache.juneau.http.resource.*;
071import org.apache.juneau.http.entity.*;
072import org.apache.juneau.http.header.*;
073import org.apache.juneau.http.part.*;
074import org.apache.juneau.http.remote.*;
075import org.apache.juneau.httppart.*;
076import org.apache.juneau.httppart.bean.*;
077import org.apache.juneau.internal.*;
078import org.apache.juneau.json.*;
079import org.apache.juneau.marshaller.*;
080import org.apache.juneau.msgpack.*;
081import org.apache.juneau.oapi.*;
082import org.apache.juneau.objecttools.*;
083import org.apache.juneau.parser.*;
084import org.apache.juneau.parser.ParseException;
085import org.apache.juneau.plaintext.*;
086import org.apache.juneau.reflect.*;
087import org.apache.juneau.rest.client.assertion.*;
088import org.apache.juneau.rest.client.remote.*;
089import org.apache.juneau.serializer.*;
090import org.apache.juneau.uon.*;
091import org.apache.juneau.urlencoding.*;
092import org.apache.juneau.utils.*;
093import org.apache.juneau.xml.*;
094
095/**
096 * Utility class for interfacing with remote REST interfaces.
097 *
098 * <p>
099 * Built upon the feature-rich Apache HttpClient library, the Juneau RestClient API adds support for fluent-style
100 * REST calls and the ability to perform marshalling of POJOs to and from HTTP parts.
101 *
102 * <h5 class='figure'>Example:</h5>
103 * <p class='bjava'>
104 *    <jc>// Create a basic REST client with JSON support and download a bean.</jc>
105 *    MyBean <jv>bean</jv> = RestClient.<jsm>create</jsm>()
106 *       .json5()
107 *       .build()
108 *       .get(<jsf>URI</jsf>)
109 *       .run()
110 *       .assertStatus().asCode().is(200)
111 *       .assertHeader(<js>"Content-Type"</js>).matchesSimple(<js>"application/json*"</js>)
112 *       .getContent().as(MyBean.<jk>class</jk>);
113 * </p>
114 *
115 * <p>
116 * Breaking apart the fluent call, we can see the classes being used:
117 * <p class='bjava'>
118 *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>().json5();
119 *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
120 *    RestRequest <jv>req</jv> = <jv>client</jv>.get(<jsf>URI</jsf>);
121 *    RestResponse <jv>res</jv> = <jv>req</jv>.run();
122 *    RestResponseStatusLineAssertion <jv>statusLineAssertion</jv> = <jv>res</jv>.assertStatus();
123 *    FluentIntegerAssertion&lt;RestResponse&gt; <jv>codeAssertion</jv> = <jv>statusLineAssertion</jv>.asCode();
124 *    <jv>res</jv> = <jv>codeAssertion</jv>.is(200);
125 *    FluentStringAssertion&lt;RestResponse&gt; <jv>headerAssertion</jv> = <jv>res</jv>.assertHeader(<js>"Content-Type"</js>);
126 *    <jv>res</jv> = <jv>headerAssertion</jv>.matchesSimple(<js>"application/json*"</js>);
127 *    RestResponseBody <jv>content</jv> = <jv>res</jv>.getContent();
128 *    MyBean <jv>bean</jv> = <jv>content</jv>.as(MyBean.<jk>class</jk>);
129 * </p>
130 *
131 * <p>
132 * It additionally provides support for creating remote proxy interfaces using REST as the transport medium.
133 *
134 * <h5 class='figure'>Example:</h5>
135 * <p class='bjava'>
136 *    <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
137 *    <ja>@Remote</ja>(path=<js>"/petstore"</js>)
138 *    <jk>public interface</jk> PetStore {
139 *
140 *       <ja>@RemotePost</ja>(<js>"/pets"</js>)
141 *       Pet addPet(
142 *          <ja>@Content</ja> CreatePet <jv>pet</jv>,
143 *          <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
144 *          <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
145 *       );
146 *    }
147 *
148 *    <jc>// Use a RestClient with default JSON 5 support.</jc>
149 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
150 *
151 *    PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
152 *    CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
153 *    Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
154 * </p>
155 *
156 * <p>
157 * The classes are closely tied to Apache HttpClient, yet provide lots of additional functionality:
158 * <ul class='javatree'>
159 *    <li class='jc'>{@link RestClient} <jk>extends</jk> {@link HttpClient}, creates {@link RestRequest} objects.
160 *    <li class='jc'>{@link RestRequest} <jk>extends</jk> {@link HttpUriRequest}, creates {@link RestResponse} objects.
161 *    <li class='jc'>{@link RestResponse} creates {@link ResponseContent} and {@link ResponseHeader} objects.
162 *    <li class='jc'>{@link ResponseContent} <jk>extends</jk> {@link HttpEntity}
163 *    <li class='jc'>{@link ResponseHeader} <jk>extends</jk> {@link Header}
164 * </ul>
165 *
166 *
167 * <p>
168 * Instances of this class are built using the {@link Builder} class which can be constructed using
169 * the {@link #create() RestClient.create()} method as shown above.
170 *
171 * <p>
172 * Clients are typically created with a root URI so that relative URIs can be used when making requests.
173 * This is done using the {@link Builder#rootUrl(Object)} method.
174 *
175 * <h5 class='figure'>Example:</h5>
176 * <p class='bjava'>
177 *    <jc>// Create a client where all URIs are relative to localhost.</jc>
178 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().rootUrl(<js>"http://localhost:5000"</js>).build();
179 *
180 *    <jc>// Use relative paths.</jc>
181 *    String <jv>body</jv> = <jv>client</jv>.get(<js>"/subpath"</js>).run().getContent().asString();
182 * </p>
183 *
184 * <p>
185 * The {@link RestClient} class creates {@link RestRequest} objects using the following methods:
186 *
187 * <ul class='javatree'>
188 *    <li class='jc'>{@link RestClient}
189 *    <ul>
190 *       <li class='jm'>{@link RestClient#get(Object) get(uri)} / {@link RestClient#get() get()}
191 *       <li class='jm'>{@link RestClient#put(Object,Object) put(uri,body)} / {@link RestClient#put(Object) put(uri)}
192 *       <li class='jm'>{@link RestClient#post(Object) post(uri,body)} / {@link RestClient#post(Object) post(uri)}
193 *       <li class='jm'>{@link RestClient#patch(Object,Object) patch(uri,body)} / {@link RestClient#patch(Object) patch(uri)}
194 *       <li class='jm'>{@link RestClient#delete(Object) delete(uri)}
195 *       <li class='jm'>{@link RestClient#head(Object) head(uri)}
196 *       <li class='jm'>{@link RestClient#options(Object) options(uri)}
197 *       <li class='jm'>{@link RestClient#formPost(Object,Object) formPost(uri,body)} / {@link RestClient#formPost(Object) formPost(uri)}
198 *       <li class='jm'>{@link RestClient#formPostPairs(Object,String...) formPostPairs(uri,parameters...)}
199 *       <li class='jm'>{@link RestClient#request(String,Object,Object) request(method,uri,body)}
200 *    </ul>
201 * </ul>
202 *
203 * <p>
204 * The {@link RestRequest} class creates {@link RestResponse} objects using the following methods:
205 *
206 * <ul class='javatree'>
207 *    <li class='jc'>{@link RestRequest}
208 *    <ul>
209 *       <li class='jm'>{@link RestRequest#run() run()}
210 *       <li class='jm'>{@link RestRequest#complete() complete()}
211 *    </ul>
212 * </ul>
213 *
214 * <p>
215 * The distinction between the two methods is that {@link RestRequest#complete() complete()} automatically consumes the response body and
216 * {@link RestRequest#run() run()} does not.  Note that you must consume response bodies in order for HTTP connections to be freed up
217 * for reuse!  The {@link InputStream InputStreams} returned by the {@link ResponseContent} object are auto-closing once
218 * they are exhausted, so it is often not necessary to explicitly close them.
219 *
220 * <p>
221 * The following examples show the distinction between the two calls:
222 *
223 * <p class='bjava'>
224 *    <jc>// Consuming the response, so use run().</jc>
225 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).run().getContent().asString();
226 *
227 *    <jc>// Only interested in response status code, so use complete().</jc>
228 *    <jk>int</jk> <jv>status</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
229 * </p>
230 *
231 *
232 * <h4 class='topic'>POJO Marshalling</h4>
233 *
234 * <p>
235 * By default, JSON support is provided for HTTP request and response bodies.
236 * Other languages can be specified using any of the following builder methods:
237 * <ul class='javatree'>
238 *    <li class='jc'>{@link Builder}
239 *    <ul>
240 *       <li class='jm'>{@link Builder#json() json()}
241 *       <li class='jm'>{@link Builder#json5() json5()}
242 *       <li class='jm'>{@link Builder#xml() xml()}
243 *       <li class='jm'>{@link Builder#html() html()}
244 *       <li class='jm'>{@link Builder#plainText() plainText()}
245 *       <li class='jm'>{@link Builder#msgPack() msgPack()}
246 *       <li class='jm'>{@link Builder#uon() uon()}
247 *       <li class='jm'>{@link Builder#urlEnc() urlEnc()}
248 *       <li class='jm'>{@link Builder#openApi() openApi()}
249 *    </ul>
250 * </ul>
251 *
252 * <h5 class='figure'>Example:</h5>
253 * <p class='bjava'>
254 *    <jc>// Create a basic REST client with JSON 5 support.</jc>
255 *    <jc>// Typically easier to use when performing unit tests.</jc>
256 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
257 * </p>
258 *
259 * <p>
260 * Clients can also support multiple languages:
261 *
262 * <h5 class='figure'>Example:</h5>
263 * <p class='bjava'>
264 *    <jc>// Create a REST client with support for multiple languages.</jc>
265 *    RestClient <jv>client1</jv> = RestClient.<jsm>create</jsm>().json().xml().openApi().build();
266 *
267 *    <jc>// Create a REST client with support for all supported languages.</jc>
268 *    RestClient <jv>client2</jv> = RestClient.<jsm>create</jsm>().universal().build();
269 * </p>
270 *
271 * <p>
272 * When using clients with multiple language support, you must specify the <c>Content-Type</c> header on requests
273 * with bodies to specify which serializer should be selected.
274 *
275 * <p class='bjava'>
276 *    <jc>// Create a REST client with support for multiple languages.</jc>
277 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
278 *
279 *    <jv>client</jv>
280 *       .post(<jsf>URI</jsf>, <jv>myBean</jv>)
281 *       .contentType(<js>"application/json"</js>)
282 *       .complete()
283 *       .assertStatus().is(200);
284 * </p>
285 *
286 * <p>
287 * Languages can also be specified per-request.
288 *
289 * <p class='bjava'>
290 *    <jc>// Create a REST client with no default languages supported.</jc>
291 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().build();
292 *
293 *    <jc>// Use JSON for this request.</jc>
294 *    <jv>client</jv>
295 *       .post(<jsf>URI</jsf>, <jv>myBean</jv>)
296 *       .json()
297 *       .complete()
298 *       .assertStatus().is(200);
299 * </p>
300 *
301 *
302 * <p>
303 * The {@link Builder} class provides convenience methods for setting common serializer and parser
304 * settings.
305 *
306 * <h5 class='figure'>Example:</h5>
307 * <p class='bjava'>
308 *    <jc>// Create a basic REST client with JSON support.</jc>
309 *    <jc>// Use single-quotes and whitespace.</jc>
310 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().sq().ws().build();
311 * </p>
312 *
313 * <p>
314 *    Other methods are also provided for specifying the serializers and parsers used for lower-level marshalling support:
315 * <ul class='javatree'>
316 *    <li class='jc'>{@link Builder}
317 *    <ul>
318 *       <li class='jm'>{@link Builder#serializer(Serializer) serializer(Serializer)}
319 *       <li class='jm'>{@link Builder#parser(Parser) parser(Parser)}
320 *       <li class='jm'>{@link Builder#marshaller(Marshaller) marshaller(Marshaller)}
321 *    </ul>
322 * </ul>
323 *
324 * <p>
325 * HTTP parts (headers, query parameters, form data...) are serialized and parsed using the {@link HttpPartSerializer}
326 * and {@link HttpPartParser} APIs.  By default, clients are configured to use {@link OpenApiSerializer} and
327 * {@link OpenApiParser}.  These can be overridden using the following methods:
328 * <ul class='javatree'>
329 *    <li class='jc'>{@link Builder}
330 *    <ul>
331 *       <li class='jm'>{@link Builder#partSerializer(Class) partSerializer(Class&lt;? extends HttpPartSerializer>)}
332 *       <li class='jm'>{@link Builder#partParser(Class) partParser(Class&lt;? extends HttpPartParser>)}
333 *    </ul>
334 * </ul>
335 *
336 *
337 * <h4 class='topic'>Request Headers</h4>
338 * <p>
339 * Per-client or per-request headers can be specified using the following methods:
340 * <ul class='javatree'>
341 *    <li class='jc'>{@link Builder}
342 *    <ul>
343 *       <li class='jm'>{@link Builder#headers() headerData()}
344 *       <li class='jm'>{@link Builder#header(String,String) header(String,Object)}
345 *       <li class='jm'>{@link Builder#header(String,Supplier) header(String,Supplier&lt;?&gt;)}
346 *       <li class='jm'>{@link Builder#headers(Header...) headers(Header...)}
347 *       <li class='jm'>{@link Builder#headersDefault(Header...) defaultHeaders(Header...)}
348 *    </ul>
349 *    <li class='jc'>{@link RestRequest}
350 *    <ul>
351 *       <li class='jm'>{@link RestRequest#header(String,Object) header(String,Object)}
352 *       <li class='jm'>{@link RestRequest#headers(Header...) headers(Header...)}
353 *       <li class='jm'>{@link RestRequest#headersBean(Object) headersBean(Object)}
354 *       <li class='jm'>{@link RestRequest#headerPairs(String...) headerPairs(String...)}
355 *    </ul>
356 * </ul>
357 *
358 * <p>
359 * The supplier methods are particularly useful for header values whose values may change over time (such as <c>Authorization</c> headers
360 * which may need to change every few minutes).
361 * </p>
362 *
363 * <h5 class='figure'>Example:</h5>
364 * <p class='bjava'>
365 *    <jc>// Create a client that adds a dynamic Authorization header to every request.</jc>
366 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().header(<js>"Authorization"</js>, ()-&gt;getMyAuthToken()).build();
367 * </p>
368 *
369 * <p>
370 * The {@link HttpPartSchema} API allows you to define OpenAPI schemas to POJO data structures on both requests
371 * and responses.
372 *
373 * <h5 class='figure'>Example:</h5>
374 * <p class='bjava'>
375 *    <jc>// Create a client that adds a header "Foo: bar|baz" to every request.</jc>
376 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>()
377 *       .header(<js>"Foo"</js>, AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), <jsf>T_ARRAY_PIPES</jsf>)
378 *       .build();
379 * </p>
380 *
381 * <p>
382 * The methods with {@link ListOperation} parameters allow you to control whether new headers get appended, prepended, or
383 * replace existing headers with the same name.
384 *
385 * <h5 class='section'>Notes:</h5><ul>
386 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>Header</c> or
387 *       <c>NameValuePair</c> objects use the values returned by that bean directly.
388 * </ul>
389 *
390 *
391 * <h4 class='topic'>Request Query Parameters</h4>
392 * <p>
393 * Per-client or per-request query parameters can be specified using the following methods:
394 * <ul class='javatree'>
395 *    <li class='jc'>{@link Builder}
396 *    <ul>
397 *       <li class='jm'>{@link Builder#queryData() queryData()}
398 *       <li class='jm'>{@link Builder#queryData(String,String) queryData(String,String)}
399 *       <li class='jm'>{@link Builder#queryData(String,Supplier) queryData(String,Supplier&lt;?&gt;)}
400 *       <li class='jm'>{@link Builder#queryData(NameValuePair...) queryData(NameValuePair...)}
401 *       <li class='jm'>{@link Builder#queryDataDefault(NameValuePair...) defaultQueryData(NameValuePair...)}
402 *    </ul>
403 *    <li class='jc'>{@link RestRequest}
404 *    <ul>
405 *       <li class='jm'>{@link RestRequest#queryData(String,Object) queryData(String,Object)}
406 *       <li class='jm'>{@link RestRequest#queryData(NameValuePair...) queryData(NameValuePair...)}
407 *       <li class='jm'>{@link RestRequest#queryDataBean(Object) queryDataBean(Object)}
408 *       <li class='jm'>{@link RestRequest#queryCustom(Object) queryCustom(Object)}
409 *       <li class='jm'>{@link RestRequest#queryDataPairs(String...) queryDataPairs(String...)}
410 *    </ul>
411 * </ul>
412 *
413 * <h5 class='figure'>Example:</h5>
414 * <p class='bjava'>
415 *    <jc>// Create a client that adds a ?foo=bar query parameter to every request.</jc>
416 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().query(<js>"foo"</js>, <js>"bar"</js>).build();
417 *
418 *    <jc>// Or do it on every request.</jc>
419 *    String <jv>response</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).query(<js>"foo"</js>, <js>"bar"</js>).run().getContent().asString();
420 * </p>
421 *
422 * <h5 class='section'>Notes:</h5><ul>
423 *    <li class='note'>Like header values, dynamic values and OpenAPI schemas are supported.
424 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
425 *       objects use the values returned by that bean directly.
426 * </ul>
427 *
428 *
429 * <h4 class='topic'>Request Form Data</h4>
430 *
431 * <p>
432 * Per-client or per-request form-data parameters can be specified using the following methods:
433 * <ul class='javatree'>
434 *    <li class='jc'>{@link Builder}
435 *    <ul>
436 *       <li class='jm'>{@link Builder#formData() formData()}
437 *       <li class='jm'>{@link Builder#formData(String,String) formData(String,String)}
438 *       <li class='jm'>{@link Builder#formData(String,Supplier) formData(String,Supplier&lt;?&gt;)}
439 *       <li class='jm'>{@link Builder#formData(NameValuePair...) formDatas(NameValuePair...)}
440 *       <li class='jm'>{@link Builder#formDataDefault(NameValuePair...) defaultFormData(NameValuePair...)}
441 *    </ul>
442 *    <li class='jc'>{@link RestRequest}
443 *    <ul>
444 *       <li class='jm'>{@link RestRequest#formData(String,Object) formData(String,Object)}
445 *       <li class='jm'>{@link RestRequest#formData(NameValuePair...) formData(NameValuePair...)}
446 *       <li class='jm'>{@link RestRequest#formDataBean(Object) formDataBean(Object)}
447 *       <li class='jm'>{@link RestRequest#formDataCustom(Object) formDataCustom(Object)}
448 *       <li class='jm'>{@link RestRequest#formDataPairs(String...) formDataPairs(String...)}
449 *    </ul>
450 * </ul>
451 *
452 * <h5 class='section'>Notes:</h5><ul>
453 *    <li class='note'>Like header values, dynamic values and OpenAPI schemas are supported.
454 *    <li class='note'>Methods that pass in POJOs convert values to strings using the part serializers.  Methods that pass in <c>NameValuePair</c>
455 *       objects use the values returned by that bean directly.
456 * </ul>
457 *
458 *
459 * <h4 class='topic'>Request Body</h4>
460 *
461 * <p>
462 * The request body can either be passed in with the client creator method (e.g. {@link RestClient#post(Object,Object) post(uri,body)}),
463 * or can be specified via the following methods:
464 *
465 * <ul class='javatree'>
466 *    <li class='jc'>{@link RestRequest}
467 *    <ul>
468 *       <li class='jm'>{@link RestRequest#content(Object) body(Object)}
469 *       <li class='jm'>{@link RestRequest#content(Object,HttpPartSchema) body(Object,HttpPartSchema)}
470 *    </ul>
471 * </ul>
472 *
473 * <p>
474 * The request body can be any of the following types:
475 * <ul class='javatree'>
476 *       <li class='jc'>
477 *          {@link Object} - POJO to be converted to text using the {@link Serializer} defined on the client or request.
478 *       <li class='jc'>
479 *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
480 *       <li class='jc'>
481 *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
482 *       <li class='jc'>
483 *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
484 *       <li class='jc'>
485 *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
486 *       <li class='jc'>
487 *          {@link PartList} - Converted to a URL-encoded FORM post.
488 *       <li class='jc'>
489 *          {@link Supplier} - A supplier of anything on this list.
490 *    </ul>
491 *
492 * <h5 class='section'>Notes:</h5><ul>
493 *    <li class='note'>If the serializer on the client or request is explicitly set to <jk>null</jk>, POJOs will be converted to strings
494 *       using the registered part serializer as content type <js>"text/plain</js>.  If the part serializer is also <jk>null</jk>,
495 *       POJOs will be converted to strings using {@link ClassMeta#toString(Object)} which typically just calls {@link Object#toString()}.
496 * </ul>
497 *
498 *
499 * <h4 class='topic'>Response Status</h4>
500 *
501 * <p>
502 * After execution using {@link RestRequest#run()} or {@link RestRequest#complete()}, the following methods can be used
503 * to get the response status:
504 *
505 * <ul class='javatree'>
506 *    <li class='jc'>{@link RestResponse}
507 *    <ul>
508 *       <li class='jm'><c>{@link RestResponse#getStatusLine() getStatusLine()} <jk>returns</jk> {@link StatusLine}</c>
509 *       <li class='jm'><c>{@link RestResponse#getStatusCode() getStatusCode()} <jk>returns</jk> <jk>int</jk></c>
510 *       <li class='jm'><c>{@link RestResponse#getReasonPhrase() getReasonPhrase()} <jk>returns</jk> String</c>
511 *       <li class='jm'><c>{@link RestResponse#assertStatus() assertStatus()} <jk>returns</jk> {@link FluentResponseStatusLineAssertion}</c>
512 *    </ul>
513 * </ul>
514 *
515 * <h5 class='figure'>Example:</h5>
516 * <p class='bjava'>
517 *    <jc>// Only interested in status code.</jc>
518 *    <jk>int</jk> <jv>statusCode</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode();
519 * </p>
520 *
521 * <p>
522 * Equivalent methods with mutable parameters are provided to allow access to status values without breaking fluent call chains.
523 *
524 * <h5 class='figure'>Example:</h5>
525 * <p class='bjava'>
526 *    <jc>// Interested in multiple values.</jc>
527 *    Value&lt;Integer&gt; <jv>statusCode</jv> = Value.<jsm>create</jsm>();
528 *    Value&lt;String&gt; <jv>reasonPhrase</jv> = Value.<jsm>create</jsm>();
529 *
530 *    <jv>client</jv>.get(<jsf>URI</jsf>).complete().getStatusCode(<jv>statusCode</jv>).getReasonPhrase(<jv>reasonPhrase</jv>);
531 *    System.<jsf>err</jsf>.println(<js>"statusCode="</js>+<jv>statusCode</jv>.get()+<js>", reasonPhrase="</js>+<jv>reasonPhrase</jv>.get());
532 * </p>
533 *
534 * <h5 class='section'>Notes:</h5><ul>
535 *    <li class='note'>If you are only interested in the response status and not the response body, be sure to use {@link RestRequest#complete()} instead
536 *       of {@link RestRequest#run()} to make sure the response body gets automatically cleaned up.  Otherwise you must
537 *       consume the response yourself.
538 * </ul>
539 *
540 * <p>
541 * The assertion method is provided for quickly asserting status codes in fluent calls.
542 *
543 * <h5 class='figure'>Example:</h5>
544 * <p class='bjava'>
545 *    <jc>// Status assertion using a static value.</jc>
546 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
547 *       .run()
548 *       .assertStatus().asCode().isBetween(200,399)
549 *       .getContent().asString();
550 *
551 *    <jc>// Status assertion using a predicate.</jc>
552 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
553 *       .run()
554 *       .assertStatus().asCode().is(<jv>x</jv> -&gt; <jv>x</jv>&lt;400)
555 *       .getContent().asString();
556 * </p>
557 *
558 *
559 * <h4 class='topic'>Response Headers</h4>
560 *
561 * <p>
562 * Response headers are accessed through the following methods:
563 *
564 * <ul class='javatree'>
565 *    <li class='jc'>{@link RestResponse}
566 *    <ul>
567 *       <li class='jm'><c>{@link RestResponse#getHeaders(String) getHeaders(String)} <jk>returns</jk> {@link ResponseHeader}[]</c>
568 *       <li class='jm'><c>{@link RestResponse#getFirstHeader(String) getFirstHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
569 *       <li class='jm'><c>{@link RestResponse#getLastHeader(String) getLastHeader(String)} <jk>returns</jk> {@link ResponseHeader}</c>
570 *       <li class='jm'><c>{@link RestResponse#getAllHeaders() getAllHeaders()} <jk>returns</jk> {@link ResponseHeader}[]</c>
571 *       <li class='jm'><c>{@link RestResponse#getStringHeader(String) getStringHeader(String)} <jk>returns</jk> String</c>
572 *       <li class='jm'><c>{@link RestResponse#containsHeader(String) containsHeader(String)} <jk>returns</jk> <jk>boolean</jk></c>
573 *    </ul>
574 * </ul>
575 *
576 * <p>
577 * The {@link RestResponse#getFirstHeader(String)} and {@link RestResponse#getLastHeader(String)} methods return an empty {@link ResponseHeader} object instead of<jk>null</jk>.
578 * This allows it to be used more easily in fluent calls.
579 *
580 * <h5 class='figure'>Example:</h5>
581 * <p class='bjava'>
582 *    <jc>// See if response contains Location header.</jc>
583 *    <jk>boolean</jk> <jv>hasLocationHeader</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).complete().getLastHeader(<js>"Location"</js>).exists();
584 * </p>
585 *
586 * <p>
587 * The {@link ResponseHeader} class extends from the HttpClient {@link Header} class and provides several convenience
588 * methods:
589 *
590 * <ul class='javatree'>
591 *    <li class='jc'>{@link ResponseHeader}
592 *    <ul>
593 *       <li class='jm'><c>{@link ResponseHeader#isPresent() isPresent()} <jk>returns</jk> <jk>boolean</jk></c>
594 *       <li class='jm'><c>{@link ResponseHeader#asString() asString()} <jk>returns</jk> String</c>
595 *       <li class='jm'><c>{@link ResponseHeader#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
596 *       <li class='jm'><c>{@link ResponseHeader#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk> T</c>
597 *       <li class='jm'><c>{@link ResponseHeader#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
598 *       <li class='jm'><c>{@link ResponseHeader#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
599 *       <li class='jm'><c>{@link ResponseHeader#asHeader(Class) asHeader(Class&lt;T <jk>extends</jk> BasicHeader&gt; c)} <jk>returns</jk> {@link BasicHeader}</c>
600 *       <li class='jm'><c>{@link ResponseHeader#asStringHeader() asStringHeader()} <jk>returns</jk> {@link BasicStringHeader}</c>
601 *       <li class='jm'><c>{@link ResponseHeader#asIntegerHeader() asIntegerHeader()} <jk>returns</jk> {@link BasicIntegerHeader}</c>
602 *       <li class='jm'><c>{@link ResponseHeader#asLongHeader() asLongHeader()} <jk>returns</jk> {@link BasicLongHeader}</c>
603 *       <li class='jm'><c>{@link ResponseHeader#asDateHeader() asDateHeader()} <jk>returns</jk> {@link BasicDateHeader}</c>
604 *       <li class='jm'><c>{@link ResponseHeader#asCsvHeader() asCsvHeader()} <jk>returns</jk> {@link BasicCsvHeader}</c>
605 *       <li class='jm'><c>{@link ResponseHeader#asEntityTagsHeader() asEntityTagsHeader()} <jk>returns</jk> {@link BasicEntityTagsHeader}</c>
606 *       <li class='jm'><c>{@link ResponseHeader#asStringRangesHeader() asStringRangesHeader()} <jk>returns</jk> {@link BasicStringRangesHeader}</c>
607 *       <li class='jm'><c>{@link ResponseHeader#asUriHeader() asUriHeader()} <jk>returns</jk> {@link BasicUriHeader}</c>
608 *    </ul>
609 * </ul>
610 *
611 * <p>
612 * The {@link ResponseHeader#schema(HttpPartSchema)} method allows you to perform parsing of OpenAPI formats for
613 * header parts.
614 *
615 * <h5 class='figure'>Example:</h5>
616 * <p class='bjava'>
617 *    <jc>// Parse the header "Foo: bar|baz".</jc>
618 *    List&lt;String&gt; <jv>fooHeader</jv> = <jv>client</jv>
619 *       .get(<jsf>URI</jsf>)
620 *       .complete()
621 *       .getHeader(<js>"Foo"</js>).schema(<jsf>T_ARRAY_PIPES</jsf>).as(List.<jk>class</jk>, String.<jk>class</jk>);
622 * </p>
623 *
624 * <p>
625 * Assertion methods are also provided for fluent-style calls:
626 *
627 * <ul class='javatree'>
628 *    <li class='jc'>{@link ResponseHeader}
629 *    <ul>
630 *       <li class='jm'><c>{@link ResponseHeader#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseHeaderAssertion}</c>
631 *    </ul>
632 * </ul>
633 *
634 * <p>
635 * Note how in the following example, the fluent assertion returns control to the {@link RestResponse} object after
636 * the assertion has been completed:
637 *
638 * <h5 class='figure'>Example:</h5>
639 * <p class='bjava'>
640 *    <jc>// Assert the response content type is any sort of JSON.</jc>
641 *    String <jv>body</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
642 *       .run()
643 *       .getHeader(<js>"Content-Type"</js>).assertValue().matchesSimple(<js>"application/json*"</js>)
644 *       .getContent().asString();
645 * </p>
646 *
647 *
648 * <h4 class='topic'>Response Body</h4>
649 *
650 * <p>
651 * The response body is accessed through the following method:
652 *
653 * <ul class='javatree'>
654 *    <li class='jc'>{@link RestResponse}
655 *    <ul>
656 *       <li class='jm'><c>{@link RestResponse#getContent() getContent()} <jk>returns</jk> {@link ResponseContent}</c>
657 *    </ul>
658 * </ul>
659 *
660 * <p>
661 * The {@link ResponseContent} class extends from the HttpClient {@link HttpEntity} class and provides several convenience
662 * methods:
663 *
664 * <ul class='javatree'>
665 *    <li class='jc'>{@link ResponseContent}
666 *    <ul>
667 *       <li class='jm'><c>{@link ResponseContent#asInputStream() asInputStream()} <jk>returns</jk> InputStream</c>
668 *       <li class='jm'><c>{@link ResponseContent#asReader() asReader()} <jk>returns</jk> Reader</c>
669 *       <li class='jm'><c>{@link ResponseContent#asReader(Charset) asReader(Charset)} <jk>returns</jk> Reader</c>
670 *       <li class='jm'><c>{@link ResponseContent#pipeTo(OutputStream) pipeTo(OutputStream)} <jk>returns</jk> {@link RestResponse}</c>
671 *       <li class='jm'><c>{@link ResponseContent#pipeTo(Writer) pipeTo(Writer)} <jk>returns</jk> {@link RestResponse}</c>
672 *       <li class='jm'><c>{@link ResponseContent#as(Type,Type...) as(Type,Type...)} <jk>returns</jk> T</c>
673 *       <li class='jm'><c>{@link ResponseContent#as(Class) as(Class&lt;T&gt;)} <jk>returns</jk> T</c>
674 *       <li class='jm'><c>{@link ResponseContent#asFuture(Class) asFuture(Class&lt;T&gt;)} <jk>returns</jk> Future&lt;T&gt;</c>
675 *       <li class='jm'><c>{@link ResponseContent#asFuture(Type,Type...) asFuture(Type,Type...)} <jk>returns</jk> Future&lt;T&gt;</c>
676 *       <li class='jm'><c>{@link ResponseContent#asString() asString()} <jk>returns</jk> String</c>
677 *       <li class='jm'><c>{@link ResponseContent#asStringFuture() asStringFuture()} <jk>returns</jk> Future&lt;String&gt;</c>
678 *       <li class='jm'><c>{@link ResponseContent#asAbbreviatedString(int) asAbbreviatedString(int)} <jk>returns</jk> String</c>
679 *       <li class='jm'><c>{@link ResponseContent#asObjectRest(Class) asObjectRest(Class&lt;?&gt;)} <jk>returns</jk> {@link ObjectRest}</c>
680 *       <li class='jm'><c>{@link ResponseContent#asObjectRest() asObjectRest()} <jk>returns</jk> {@link ObjectRest}</c>
681 *       <li class='jm'><c>{@link ResponseContent#asMatcher(Pattern) asMatcher(Pattern)} <jk>returns</jk> {@link Matcher}</c>
682 *       <li class='jm'><c>{@link ResponseContent#asMatcher(String) asMatcher(String)} <jk>returns</jk> {@link Matcher}</c>
683 *    </ul>
684 * </ul>
685 *
686 * <br>
687 *
688 * <h5 class='figure'>Examples:</h5>
689 * <p class='bjava'>
690 *    <jc>// Parse into a linked-list of strings.</jc>
691 *    List&lt;String&gt; <jv>list1</jv> = <jv>client</jv>
692 *       .get(<jsf>URI</jsf>)
693 *       .run()
694 *       .getContent().as(LinkedList.<jk>class</jk>, String.<jk>class</jk>);
695 *
696 *    <jc>// Parse into a linked-list of beans.</jc>
697 *    List&lt;MyBean&gt; <jv>list2</jv> = <jv>client</jv>
698 *       .get(<jsf>URI</jsf>)
699 *       .run()
700 *       .getContent().as(LinkedList.<jk>class</jk>, MyBean.<jk>class</jk>);
701 *
702 *    <jc>// Parse into a linked-list of linked-lists of strings.</jc>
703 *    List&lt;List&lt;String&gt;&gt; <jv>list3</jv> = <jv>client</jv>
704 *       .get(<jsf>URI</jsf>)
705 *       .run()
706 *       .getContent().as(LinkedList.<jk>class</jk>, LinkedList.<jk>class</jk>, String.<jk>class</jk>);
707 *
708 *    <jc>// Parse into a map of string keys/values.</jc>
709 *    Map&lt;String,String&gt; <jv>map1</jv> = <jv>client</jv>
710 *       .get(<jsf>URI</jsf>)
711 *       .run()
712 *       .getContent().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
713 *
714 *    <jc>// Parse into a map containing string keys and values of lists containing beans.</jc>
715 *    Map&lt;String,List&lt;MyBean&gt;&gt; <jv>map2</jv> = <jv>client</jv>
716 *       .get(<jsf>URI</jsf>)
717 *       .run()
718 *       .getContent().as(TreeMap.<jk>class</jk>, String.<jk>class</jk>, List.<jk>class</jk>, MyBean.<jk>class</jk>);
719 * </p>
720 *
721 * <p>
722 * The response body can only be consumed once unless it has been cached into memory.  In many cases, the body is
723 * automatically cached when using the assertions methods or methods such as {@link ResponseContent#asString()}.
724 * However, methods that involve reading directly from the input stream cannot be called twice.
725 * In these cases, the {@link RestResponse#cacheContent()} and {@link ResponseContent#cache()} methods are provided
726 * to cache the response body in memory so that you can perform several operations against it.
727 *
728 * <p class='bjava'>
729 *    <jc>// Cache the response body so we can access it twice.</jc>
730 *    InputStream <jv>inputStream</jv> = <jv>client</jv>
731 *       .get(<jsf>URI</jsf>)
732 *       .run()
733 *       .cacheBody()
734 *       .getContent().pipeTo(<jv>someOtherStream</jv>)
735 *       .getContent().asInputStream();
736 * </p>
737 *
738 * <p>
739 * Assertion methods are also provided for fluent-style calls:
740 *
741 * <ul class='javatree'>
742 *    <li class='jc'>{@link ResponseContent}
743 *    <ul>
744 *       <li class='jm'><c>{@link ResponseContent#assertValue() assertValue()} <jk>returns</jk> {@link FluentResponseBodyAssertion}</c>
745 *    </ul>
746 * </ul>
747 *
748 * <br>
749 *
750 * <h5 class='figure'>Example:</h5>
751 * <p class='bjava'>
752 *    <jc>// Assert that the body contains the string "Success".</jc>
753 *    String <jv>body</jv> = <jv>client</jv>
754 *       .get(<jsf>URI</jsf>)
755 *       .run()
756 *       .getContent().assertString().contains(<js>"Success"</js>)
757 *       .getContent().asString();
758 * </p>
759 *
760 * <p>
761 * Object assertions allow you to parse the response body into a POJO and then perform various tests on that resulting
762 * POJO.
763 *
764 * <h5 class='figure'>Example:</h5>
765 * <p class='bjava'>
766 *    <jc>// Parse bean into POJO and then validate that it was parsed correctly.</jc>
767 *    MyBean <jv>bean</jv> = <jv>client</jv>.get(<jsf>URI</jsf>)
768 *       .run()
769 *       .getContent().assertObject(MyBean.<jk>class</jk>).asJson().is(<js>"{foo:'bar'}"</js>)
770 *       .getContent().as(MyBean.<jk>class</jk>);
771 * </p>
772 *
773 *
774 * <h4 class='topic'>Custom Call Handlers</h4>
775 *
776 * <p>
777 * The {@link RestCallHandler} interface provides the ability to provide custom handling of requests.
778 *
779 * <ul class='javatree'>
780 *    <li class='jc'>{@link Builder}
781 *    <ul>
782 *       <li class='jm'>{@link Builder#callHandler() callHandler()}
783 *    </ul>
784 *    <li class='jic'>{@link RestCallHandler}
785 *    <ul>
786 *       <li class='jm'><c>{@link RestCallHandler#run(HttpHost,HttpRequest,HttpContext) run(HttpHost,HttpRequest,HttpContext)} <jk>returns</jk> HttpResponse</c>
787 *    </ul>
788 * </ul>
789 *
790 * <p>
791 * Note that there are other ways of accomplishing this such as extending the {@link RestClient} class and overriding
792 * the {@link #run(HttpHost,HttpRequest,HttpContext)} method
793 * or by defining your own {@link HttpRequestExecutor}.  Using this interface is often simpler though.
794 *
795 *
796 * <h4 class='topic'>Interceptors</h4>
797 *
798 * <p>
799 * The {@link RestCallInterceptor} API provides a quick way of intercepting and manipulating requests and responses beyond
800 * the existing {@link HttpRequestInterceptor} and {@link HttpResponseInterceptor} APIs.
801 *
802 * <ul class='javatree'>
803 *    <li class='jc'>{@link Builder}
804 *    <ul>
805 *       <li class='jm'>{@link Builder#interceptors(Object...) interceptors(Object...)}
806 *    </ul>
807 *    <li class='jc'>{@link RestRequest}
808 *    <ul>
809 *       <li class='jm'>{@link RestRequest#interceptors(RestCallInterceptor...) interceptors(RestCallInterceptor...)}
810 *    </ul>
811 *    <li class='jic'>{@link RestCallInterceptor}
812 *    <ul>
813 *       <li class='jm'>{@link RestCallInterceptor#onInit(RestRequest) onInit(RestRequest)}
814 *       <li class='jm'>{@link RestCallInterceptor#onConnect(RestRequest,RestResponse) onConnect(RestRequest,RestResponse)}
815 *       <li class='jm'>{@link RestCallInterceptor#onClose(RestRequest,RestResponse) onClose(RestRequest,RestResponse)}
816 *    </ul>
817 * </ul>
818 *
819 *
820 * <h4 class='topic'>Logging / Debugging</h4>
821 *
822 * <p>
823 * The following methods provide logging of requests and responses:
824 *
825 * <ul class='javatree'>
826 *    <li class='jc'>{@link Builder}
827 *    <ul>
828 *       <li class='jm'>{@link Builder#logger(Logger) logger(Logger)}
829 *       <li class='jm'>{@link Builder#logToConsole() logToConsole()}
830 *       <li class='jm'>{@link Builder#logRequests(DetailLevel,Level,BiPredicate) logRequests(DetailLevel,Level,BiPredicate)}
831 *    </ul>
832 * </ul>
833 *
834 * <p>
835 * The following example shows the results of logging all requests that end with <c>/bean</c>.
836 *
837 * <h5 class='figure'>Examples:</h5>
838 * <p class='bjava'>
839 *    MyBean <jv>bean</jv> = RestClient
840 *       .<jsm>create</jsm>()
841 *       .json5()
842 *       .logRequests(DetailLevel.<jsf>FULL</jsf>, Level.<jsf>SEVERE</jsf>, (<jv>req</jv>,<jv>res</jv>)-&gt;<jv>req</jv>.getUri().endsWith(<js>"/bean"</js>))
843 *       .logToConsole()
844 *       .build()
845 *       .post(<js>"http://localhost/bean"</js>, <jv>anotherBean</jv>)
846 *       .run()
847 *       .getContent().as(MyBean.<jk>class</jk>);
848 * </p>
849 *
850 * <p>
851 * This produces the following console output:
852 *
853 * <p class='bconsole'>
854 *    === HTTP Call (outgoing) ======================================================
855 *    === REQUEST ===
856 *    POST http://localhost/bean
857 *    ---request headers---
858 *       Accept: application/json5
859 *    ---request entity---
860 *    Content-Type: application/json5
861 *    ---request content---
862 *    {f:1}
863 *    === RESPONSE ===
864 *    HTTP/1.1 200
865 *    ---response headers---
866 *       Content-Type: application/json
867 *    ---response content---
868 *    {f:1}
869 *    === END =======================================================================",
870 * </p>
871 *
872 *
873 * <p class='notes'>
874 * 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
875 * a performance penalty.
876 *
877 * <p>
878 * Additionally, the following method is also provided for enabling debug mode:
879 *
880 * <ul class='javatree'>
881 *    <li class='jc'>{@link Builder}
882 *    <ul>
883 *       <li class='jm'>{@link Builder#debug() debug()}
884 *    </ul>
885 * </ul>
886 *
887 * <p>
888 * Enabling debug mode has the following effects:
889 * <ul>
890 *    <li>{@link org.apache.juneau.Context.Builder#debug()} is enabled.
891 *    <li>{@link Builder#detectLeaks()} is enabled.
892 *    <li>{@link Builder#logToConsole()} is called.
893 * </ul>
894 *
895 *
896 * <h4 class='topic'>REST Proxies</h4>
897 *
898 * <p>
899 * One of the more powerful features of the REST client class is the ability to produce Java interface proxies against
900 * arbitrary remote REST resources.
901 *
902 * <h5 class='figure'>Example:</h5>
903 * <p class='bjava'>
904 *    <jc>// Define a Remote proxy for interacting with a REST interface.</jc>
905 *    <ja>@Remote</ja>(path=<js>"/petstore"</js>)
906 *    <jk>public interface</jk> PetStore {
907 *
908 *       <ja>@RemotePost</ja>(<js>"/pets"</js>)
909 *       Pet addPet(
910 *          <ja>@Content</ja> CreatePet <jv>pet</jv>,
911 *          <ja>@Header</ja>(<js>"E-Tag"</js>) UUID <jv>etag</jv>,
912 *          <ja>@Query</ja>(<js>"debug"</js>) <jk>boolean</jk> <jv>debug</jv>
913 *       );
914 *    }
915 *
916 *    <jc>// Use a RestClient with default JSON 5 support.</jc>
917 *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build())
918 *
919 *    PetStore <jv>store</jv> = <jv>client</jv>.getRemote(PetStore.<jk>class</jk>, <js>"http://localhost:10000"</js>);
920 *    CreatePet <jv>createPet</jv> = <jk>new</jk> CreatePet(<js>"Fluffy"</js>, 9.99);
921 *    Pet <jv>pet</jv> = <jv>store</jv>.addPet(<jv>createPet</jv>, UUID.<jsm>randomUUID</jsm>(), <jk>true</jk>);
922 * </p>
923 *
924 * <p>
925 * The methods to retrieve remote interfaces are:
926 *
927 * <ul class='javatree'>
928 *    <li class='jc'>{@link RestClient}
929 *    <ul>
930 *       <li class='jm'><c>{@link RestClient#getRemote(Class) getRemote(Class&lt;T&gt;)} <jk>returns</jk> T</c>
931 *       <li class='jm'><c>{@link RestClient#getRemote(Class,Object) getRemote(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
932 *       <li class='jm'><c>{@link RestClient#getRemote(Class,Object,Serializer,Parser) getRemote(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
933 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class) getRrpcInterface(Class&lt;T&gt;)} <jk>returns</jk> T</c>
934 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object) getRrpcInterface(Class&lt;T&gt;,Object)} <jk>returns</jk> T</c>
935 *       <li class='jm'><c>{@link RestClient#getRrpcInterface(Class,Object,Serializer,Parser) getRrpcInterface(Class&lt;T&gt;,Object,Serializer,Parser)} <jk>returns</jk> T</c>
936 *    </ul>
937 * </ul>
938 *
939 * <p>
940 * Two basic types of remote interfaces are provided:
941 *
942 * <ul class='spaced-list'>
943 *    <li>{@link Remote @Remote}-annotated interfaces.  These can be defined against arbitrary external REST resources.
944 *    <li>RPC-over-REST interfaces.  These are Java interfaces that allow you to make method calls on server-side POJOs.
945 * </ul>
946 *
947 * <p>
948 * Refer to the following documentation on both flavors:
949 *
950 * <ul class='doctree'>
951 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
952 *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
953 * </ul>
954 *
955 * <br>
956 * <hr>
957 * <h4 class='topic'>Customizing Apache HttpClient</h4>
958 *
959 * <p>
960 * Several methods are provided for customizing the underlying HTTP client and client builder classes:
961 * <ul class='javatree'>
962 *    <li class='jc'>{@link Builder}
963 *    <ul>
964 *       <li class='jm'>{@link Builder#httpClientBuilder(HttpClientBuilder) httpClientBuilder(HttpClientBuilder)} - Set the client builder yourself.
965 *       <li class='jm'>{@link Builder#createHttpClientBuilder() createHttpClientBuilder()} - Override to create the client builder.
966 *       <li class='jm'>{@link Builder#createHttpClient() createHttpClient()} - Override to create the client.
967 *       <li class='jm'>{@link Builder#createConnectionManager() createConnectionManager()} - Override to create the connection management.
968 *    </ul>
969 * </ul>
970 *
971 * <p>
972 * Additionally, all methods on the <c>HttpClientBuilder</c> class have been extended with fluent setters.
973 *
974 * <h5 class='figure'>Example:</h5>
975 * <p class='bjava'>
976 *    <jc>// Create a client with customized HttpClient settings.</jc>
977 *    MyBean <jv>bean</jv> = RestClient
978 *       .<jsm>create</jsm>()
979 *       .disableRedirectHandling()
980 *       .connectionManager(<jv>myConnectionManager</jv>)
981 *       .addInterceptorFirst(<jv>myHttpRequestInterceptor</jv>)
982 *       .build();
983 * </p>
984 *
985 * <p>
986 * Refer to the {@link HttpClientBuilder HTTP Client Builder API} for more information.
987 *
988 *
989 * <h4 class='topic'>Extending RestClient</h4>
990 *
991 * <p>
992 * The <c>RestClient</c> API has been designed to allow for the ability to be easily extended.
993 * The following example that overrides the primary run method shows how this can be done.
994 *
995 * <h5 class='figure'>Example:</h5>
996 * <p class='bjava'>
997 *    <jk>public class</jk> MyRestClient <jk>extends</jk> RestClient {
998 *
999 *       <jc>// Must provide this constructor!</jc>
1000 *       <jk>public</jk> MyRestClient(RestClient.Builder <jv>builder</jv>) {
1001 *          <jk>super</jk>(<jv>builder</jv>);
1002 *       }
1003 *
1004 *       <jd>/** Optionally override to customize builder settings before initialization. </jd>
1005 *       <ja>@Override</ja>
1006 *       <jk>protected void</jk> init(RestClient.Builder) {...}
1007 *
1008 *       <jd>/** Optionally override to provide post-initialization (e.g. setting up SAML handshakes, etc...). </jd>
1009 *       <ja>@Override</ja>
1010 *       <jk>protected void</jk> init() {...}
1011 *
1012 *       <jd>/** Optionally override to customize requests when they're created (e.g. add headers to each request). </jd>
1013 *       <ja>@Override</ja>
1014 *       <jk>protected</jk> RestRequest request(RestOperation) {...}
1015 *
1016 *       <jd>/** Optionally override to implement your own call handling. </jd>
1017 *       <ja>@Override</ja>
1018 *       <jk>protected</jk> HttpResponse run(HttpHost, HttpRequest, HttpContext) {...}
1019 *
1020 *       <jd>/** Optionally override to customize requests before they're executed. </jd>
1021 *       <ja>@Override</ja>
1022 *       <jk>protected void</jk> onCallInit(RestRequest) {...}
1023 *
1024 *       <jd>/** Optionally override to customize responses as soon as a connection is made. </jd>
1025 *       <ja>@Override</ja>
1026 *       <jk>protected void</jk> onCallConnect(RestRequest, RestResponse) {...}
1027 *
1028 *       <jd>/** Optionally override to perform any call cleanup. </jd>
1029 *       <ja>@Override</ja>
1030 *       <jk>protected void</jk> onCallClose(RestRequest, RestResponse) {...}
1031 *    }
1032 *
1033 *    <jc>// Instantiate your client.</jc>
1034 *    MyRestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build(MyRestClient.<jk>class</jk>);
1035 * </p>
1036 *
1037 * <p>
1038 * The {@link RestRequest} and {@link RestResponse} objects can also be extended and integrated by overriding the
1039 * {@link RestClient#createRequest(URI,String,boolean)} and {@link RestClient#createResponse(RestRequest,HttpResponse,Parser)} methods.
1040 *
1041 * <h5 class='section'>Notes:</h5><ul>
1042 *    <li class='note'>This class is thread safe and reusable.
1043 * </ul>
1044 *
1045 * <h5 class='section'>See Also:</h5><ul>
1046 *    <li class='link'><a class="doclink" href="../../../../../index.html#juneau-rest-client">juneau-rest-client</a>
1047 * </ul>
1048 */
1049public class RestClient extends BeanContextable implements HttpClient, Closeable {
1050
1051   //-------------------------------------------------------------------------------------------------------------------
1052   // Static
1053   //-------------------------------------------------------------------------------------------------------------------
1054
1055   private static final RestCallInterceptor[] EMPTY_REST_CALL_INTERCEPTORS = new RestCallInterceptor[0];
1056
1057   /**
1058    * Instantiates a new clean-slate {@link Builder} object.
1059    *
1060    * @return A new {@link Builder} object.
1061    */
1062   public static Builder create() {
1063      return new Builder();
1064   }
1065
1066   //-------------------------------------------------------------------------------------------------------------------
1067   // Builder
1068   //-------------------------------------------------------------------------------------------------------------------
1069
1070   /**
1071    * Builder class.
1072    */
1073   @FluentSetters(ignore={"beanMapPutReturnsOldValue","example","exampleJson","debug","mediaType"})
1074   public static class Builder extends BeanContextable.Builder {
1075
1076      BeanStore beanStore = BeanStore.create().build();
1077
1078      private HttpClientBuilder httpClientBuilder;
1079      private CloseableHttpClient httpClient;
1080
1081      private HeaderList headerData;
1082      private PartList queryData, formData, pathData;
1083      private BeanCreator<RestCallHandler> callHandler;
1084      private SerializerSet.Builder serializers;
1085      private ParserSet.Builder parsers;
1086      private HttpPartSerializer.Creator partSerializer;
1087      private HttpPartParser.Creator partParser;
1088      private UrlEncodingSerializer.Builder urlEncodingSerializer;
1089
1090      private boolean pooled;
1091
1092      String rootUrl;
1093      boolean skipEmptyHeaderData, skipEmptyFormData, skipEmptyQueryData, executorServiceShutdownOnClose, ignoreErrors, keepHttpClientOpen, detectLeaks,
1094         logToConsole;
1095      Logger logger;
1096      DetailLevel logRequests;
1097      Level logRequestsLevel;
1098      BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
1099      Predicate<Integer> errorCodes = x ->  x<=0 || x>=400;
1100      HttpClientConnectionManager connectionManager;
1101      PrintStream console;
1102      ExecutorService executorService;
1103      List<RestCallInterceptor> interceptors;
1104
1105      /**
1106       * Constructor.
1107       */
1108      protected Builder() {
1109         super();
1110      }
1111
1112      @Override /* Context.Builder */
1113      public Builder copy() {
1114         throw new NoSuchMethodError("Not implemented.");
1115      }
1116
1117      @Override /* Context.Builder */
1118      public RestClient build() {
1119         return build(RestClient.class);
1120      }
1121
1122      //------------------------------------------------------------------------------------------------------------------
1123      // Convenience marshalling support methods.
1124      //------------------------------------------------------------------------------------------------------------------
1125
1126      /**
1127       * Convenience method for specifying JSON as the marshalling transmission media type.
1128       *
1129       * <p>
1130       * {@link JsonSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1131       *    <ul>
1132       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1133       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1134       *    </ul>
1135       * <p>
1136       *    {@link JsonParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1137       *    <ul>
1138       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1139       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1140       *    </ul>
1141       * <p>
1142       *    <c>Accept</c> request header will be set to <js>"application/json"</js> unless overridden
1143       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}}.
1144       * <p>
1145       *    <c>Content-Type</c> request header will be set to <js>"application/json"</js> unless overridden
1146       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1147       * <p>
1148       *    Can be combined with other marshaller setters such as {@link #xml()} to provide support for multiple languages.
1149       *    <ul>
1150       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1151       *       last-enabled language if the headers are not set.
1152       *    </ul>
1153       * <p>
1154       *    Identical to calling <c>serializer(JsonSerializer.<jk>class</jk>).parser(JsonParser.<jk>class</jk>)</c>.
1155       *
1156       * <h5 class='section'>Example:</h5>
1157       * <p class='bjava'>
1158       *    <jc>// Construct a client that uses JSON marshalling.</jc>
1159       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json().build();
1160       * </p>
1161       *
1162       * @return This object.
1163       */
1164      @FluentSetter
1165      public Builder json() {
1166         return serializer(JsonSerializer.class).parser(JsonParser.class);
1167      }
1168
1169      /**
1170       * Convenience method for specifying Simplified JSON as the marshalling transmission media type.
1171       *
1172       * <p>
1173       * Simplified JSON is typically useful for automated tests because you can do simple string comparison of results
1174       * without having to escape lots of quotes.
1175       *
1176       * <p>
1177       *    {@link Json5Serializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1178       *    <ul>
1179       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1180       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1181       *    </ul>
1182       * <p>
1183       *    {@link Json5Parser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1184       *    <ul>
1185       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1186       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1187       *    </ul>
1188       * <p>
1189       *    <c>Accept</c> request header will be set to <js>"application/json"</js> unless overridden
1190       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1191       * <p>
1192       *    <c>Content-Type</c> request header will be set to <js>"application/json5"</js> unless overridden
1193       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1194       * <p>
1195       *    Can be combined with other marshaller setters such as {@link #xml()} to provide support for multiple languages.
1196       *    <ul>
1197       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1198       *       last-enabled language if the headers are not set.
1199       *    </ul>
1200       * <p>
1201       *    Identical to calling <c>serializer(Json5Serializer.<jk>class</jk>).parser(Json5Parser.<jk>class</jk>)</c>.
1202       *
1203       * <h5 class='section'>Example:</h5>
1204       * <p class='bjava'>
1205       *    <jc>// Construct a client that uses Simplified JSON marshalling.</jc>
1206       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().json5().build();
1207       * </p>
1208       *
1209       * @return This object.
1210       */
1211      @FluentSetter
1212      public Builder json5() {
1213         return serializer(Json5Serializer.class).parser(Json5Parser.class);
1214      }
1215
1216      /**
1217       * Convenience method for specifying XML as the marshalling transmission media type.
1218       *
1219       * <p>
1220       * {@link XmlSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1221       *    <ul>
1222       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1223       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1224       *    </ul>
1225       * <p>
1226       *    {@link XmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1227       *    <ul>
1228       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1229       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1230       *    </ul>
1231       * <p>
1232       *    <c>Accept</c> request header will be set to <js>"text/xml"</js> unless overridden
1233       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1234       * <p>
1235       *    <c>Content-Type</c> request header will be set to <js>"text/xml"</js> unless overridden
1236       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1237       * <p>
1238       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1239       *    <ul>
1240       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1241       *       last-enabled language if the headers are not set.
1242       *    </ul>
1243       * <p>
1244       *    Identical to calling <c>serializer(XmlSerializer.<jk>class</jk>).parser(XmlParser.<jk>class</jk>)</c>.
1245       *
1246       * <h5 class='section'>Example:</h5>
1247       * <p class='bjava'>
1248       *    <jc>// Construct a client that uses XML marshalling.</jc>
1249       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().xml().build();
1250       * </p>
1251       *
1252       * @return This object.
1253       */
1254      @FluentSetter
1255      public Builder xml() {
1256         return serializer(XmlSerializer.class).parser(XmlParser.class);
1257      }
1258
1259      /**
1260       * Convenience method for specifying HTML as the marshalling transmission media type.
1261       *
1262       * <p>
1263       * POJOs are converted to HTML without any sort of doc wrappers.
1264       *
1265       * <p>
1266       *    {@link HtmlSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1267       *    <ul>
1268       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1269       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1270       *    </ul>
1271       * <p>
1272       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1273       *    <ul>
1274       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1275       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1276       *    </ul>
1277       * <p>
1278       *    <c>Accept</c> request header will be set to <js>"text/html"</js> unless overridden
1279       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1280       * <p>
1281       *    <c>Content-Type</c> request header will be set to <js>"text/html"</js> unless overridden
1282       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1283       * <p>
1284       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1285       *    <ul>
1286       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1287       *       last-enabled language if the headers are not set.
1288       *    </ul>
1289       * <p>
1290       *    Identical to calling <c>serializer(HtmlSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1291       *
1292       * <h5 class='section'>Example:</h5>
1293       * <p class='bjava'>
1294       *    <jc>// Construct a client that uses HTML marshalling.</jc>
1295       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().html().build();
1296       * </p>
1297       *
1298       * @return This object.
1299       */
1300      @FluentSetter
1301      public Builder html() {
1302         return serializer(HtmlSerializer.class).parser(HtmlParser.class);
1303      }
1304
1305      /**
1306       * Convenience method for specifying HTML DOC as the marshalling transmission media type.
1307       *
1308       * <p>
1309       * POJOs are converted to fully renderable HTML pages.
1310       *
1311       * <p>
1312       *    {@link HtmlDocSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1313       *    <ul>
1314       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()} or
1315       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1316       *    </ul>
1317       * <p>
1318       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1319       *    <ul>
1320       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1321       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1322       *    </ul>
1323       * <p>
1324       *    <c>Accept</c> request header will be set to <js>"text/html"</js> unless overridden
1325       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1326       * <p>
1327       *    <c>Content-Type</c> request header will be set to <js>"text/html"</js> unless overridden
1328       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1329       * <p>
1330       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1331       *    <ul>
1332       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1333       *       last-enabled language if the headers are not set.
1334       *    </ul>
1335       * <p>
1336       *    Identical to calling <c>serializer(HtmlDocSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1337       *
1338       * <h5 class='section'>Example:</h5>
1339       * <p class='bjava'>
1340       *    <jc>// Construct a client that uses HTML Doc marshalling.</jc>
1341       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().htmlDoc().build();
1342       * </p>
1343       *
1344       * @return This object.
1345       */
1346      @FluentSetter
1347      public Builder htmlDoc() {
1348         return serializer(HtmlDocSerializer.class).parser(HtmlParser.class);
1349      }
1350
1351      /**
1352       * Convenience method for specifying Stripped HTML DOC as the marshalling transmission media type.
1353       *
1354       * <p>
1355       * Same as {@link #htmlDoc()} but without the header and body tags and page title and description.
1356       *
1357       * <p>
1358       *    {@link HtmlStrippedDocSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1359       *    <ul>
1360       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1361       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1362       *    </ul>
1363       * <p>
1364       *    {@link HtmlParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1365       *    <ul>
1366       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1367       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1368       *    </ul>
1369       * <p>
1370       *    <c>Accept</c> request header will be set to <js>"text/html+stripped"</js> unless overridden
1371       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1372       * <p>
1373       *    <c>Content-Type</c> request header will be set to <js>"text/html+stripped"</js> unless overridden
1374       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1375       * <p>
1376       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1377       *    <ul>
1378       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1379       *       last-enabled language if the headers are not set.
1380       *    </ul>
1381       * <p>
1382       *    Identical to calling <c>serializer(HtmlStrippedDocSerializer.<jk>class</jk>).parser(HtmlParser.<jk>class</jk>)</c>.
1383       *
1384       * <h5 class='section'>Example:</h5>
1385       * <p class='bjava'>
1386       *    <jc>// Construct a client that uses HTML Stripped Doc marshalling.</jc>
1387       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().htmlStrippedDoc().build();
1388       * </p>
1389       *
1390       * @return This object.
1391       */
1392      @FluentSetter
1393      public Builder htmlStrippedDoc() {
1394         return serializer(HtmlStrippedDocSerializer.class).parser(HtmlParser.class);
1395      }
1396
1397      /**
1398       * Convenience method for specifying Plain Text as the marshalling transmission media type.
1399       *
1400       * <p>
1401       * Plain text marshalling typically only works on simple POJOs that can be converted to and from strings using
1402       * swaps, swap methods, etc...
1403       *
1404       * <p>
1405       *    {@link PlainTextSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1406       *    <ul>
1407       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1408       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1409       *    </ul>
1410       * <p>
1411       *    {@link PlainTextParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1412       *    <ul>
1413       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1414       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1415       *    </ul>
1416       * <p>
1417       *    <c>Accept</c> request header will be set to <js>"text/plain"</js> unless overridden
1418       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1419       * <p>
1420       *    <c>Content-Type</c> request header will be set to <js>"text/plain"</js> unless overridden
1421       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1422       * <p>
1423       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1424       *    <ul>
1425       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1426       *       last-enabled language if the headers are not set.
1427       *    </ul>
1428       * <p>
1429       *    Identical to calling <c>serializer(PlainTextSerializer.<jk>class</jk>).parser(PlainTextParser.<jk>class</jk>)</c>.
1430       *
1431       * <h5 class='section'>Example:</h5>
1432       * <p class='bjava'>
1433       *    <jc>// Construct a client that uses Plain Text marshalling.</jc>
1434       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().plainText().build();
1435       * </p>
1436       *
1437       * @return This object.
1438       */
1439      @FluentSetter
1440      public Builder plainText() {
1441         return serializer(PlainTextSerializer.class).parser(PlainTextParser.class);
1442      }
1443
1444      /**
1445       * Convenience method for specifying MessagePack as the marshalling transmission media type.
1446       *
1447       * <p>
1448       * MessagePack is a binary equivalent to JSON that takes up considerably less space than JSON.
1449       *
1450       * <p>
1451       *    {@link MsgPackSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1452       *    <ul>
1453       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1454       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1455       *    </ul>
1456       * <p>
1457       *    {@link MsgPackParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1458       *    <ul>
1459       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1460       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1461       *    </ul>
1462       * <p>
1463       *    <c>Accept</c> request header will be set to <js>"octal/msgpack"</js> unless overridden
1464       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1465       * <p>
1466       *    <c>Content-Type</c> request header will be set to <js>"octal/msgpack"</js> unless overridden
1467       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1468       * <p>
1469       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1470       *    <ul>
1471       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1472       *       last-enabled language if the headers are not set.
1473       *    </ul>
1474       * <p>
1475       *    Identical to calling <c>serializer(MsgPackSerializer.<jk>class</jk>).parser(MsgPackParser.<jk>class</jk>)</c>.
1476       *
1477       * <h5 class='section'>Example:</h5>
1478       * <p class='bjava'>
1479       *    <jc>// Construct a client that uses MessagePack marshalling.</jc>
1480       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().msgPack().build();
1481       * </p>
1482       *
1483       * @return This object.
1484       */
1485      @FluentSetter
1486      public Builder msgPack() {
1487         return serializer(MsgPackSerializer.class).parser(MsgPackParser.class);
1488      }
1489
1490      /**
1491       * Convenience method for specifying UON as the marshalling transmission media type.
1492       *
1493       * <p>
1494       * UON is Url-Encoding Object notation that is equivalent to JSON but suitable for transmission as URL-encoded
1495       * query and form post values.
1496       *
1497       * <p>
1498       *    {@link UonSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1499       *    <ul>
1500       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1501       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1502       *    </ul>
1503       * <p>
1504       *    {@link UonParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1505       *    <ul>
1506       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1507       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1508       *    </ul>
1509       * <p>
1510       *    <c>Accept</c> request header will be set to <js>"text/uon"</js> unless overridden
1511       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1512       * <p>
1513       *    <c>Content-Type</c> request header will be set to <js>"text/uon"</js> unless overridden
1514       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1515       * <p>
1516       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1517       *    <ul>
1518       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1519       *       last-enabled language if the headers are not set.
1520       *    </ul>
1521       * <p>
1522       *    Identical to calling <c>serializer(UonSerializer.<jk>class</jk>).parser(UonParser.<jk>class</jk>)</c>.
1523       *
1524       * <h5 class='section'>Example:</h5>
1525       * <p class='bjava'>
1526       *    <jc>// Construct a client that uses UON marshalling.</jc>
1527       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().uon().build();
1528       * </p>
1529       *
1530       * @return This object.
1531       */
1532      @FluentSetter
1533      public Builder uon() {
1534         return serializer(UonSerializer.class).parser(UonParser.class);
1535      }
1536
1537      /**
1538       * Convenience method for specifying URL-Encoding as the marshalling transmission media type.
1539       *
1540       * <p>
1541       *    {@link UrlEncodingSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1542       *    <ul>
1543       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1544       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1545       *       <li>This serializer is NOT used when using the {@link RestRequest#formData(String, Object)} (and related) methods for constructing
1546       *          the request body.  Instead, the part serializer specified via {@link #partSerializer(Class)} is used.
1547       *    </ul>
1548       * <p>
1549       *    {@link UrlEncodingParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1550       *    <ul>
1551       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1552       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1553       *    </ul>
1554       * <p>
1555       *    <c>Accept</c> request header will be set to <js>"application/x-www-form-urlencoded"</js> unless overridden
1556       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1557       * <p>
1558       *    <c>Content-Type</c> request header will be set to <js>"application/x-www-form-urlencoded"</js> unless overridden
1559       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1560       * <p>
1561       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1562       *    <ul>
1563       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1564       *       last-enabled language if the headers are not set.
1565       *    </ul>
1566       * <p>
1567       *    Identical to calling <c>serializer(UrlEncodingSerializer.<jk>class</jk>).parser(UrlEncodingParser.<jk>class</jk>)</c>.
1568       *
1569       * <h5 class='section'>Example:</h5>
1570       * <p class='bjava'>
1571       *    <jc>// Construct a client that uses URL-Encoded marshalling.</jc>
1572       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().urlEnc().build();
1573       * </p>
1574       *
1575       * @return This object.
1576       */
1577      @FluentSetter
1578      public Builder urlEnc() {
1579         return serializer(UrlEncodingSerializer.class).parser(UrlEncodingParser.class);
1580      }
1581
1582      /**
1583       * Convenience method for specifying OpenAPI as the marshalling transmission media type.
1584       *
1585       * <p>
1586       * OpenAPI is a language that allows serialization to formats that use {@link HttpPartSchema} objects to describe their structure.
1587       *
1588       * <p>
1589       *    {@link OpenApiSerializer} will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1590       *    <ul>
1591       *       <li>The serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1592       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1593       *       <li>Typically the {@link RestRequest#content(Object, HttpPartSchema)} method will be used to specify the body of the request with the
1594       *          schema describing it's structure.
1595       *    </ul>
1596       * <p>
1597       *    {@link OpenApiParser} will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1598       *    <ul>
1599       *       <li>The parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1600       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1601       *       <li>Typically the {@link ResponseContent#schema(HttpPartSchema)} method will be used to specify the structure of the response body.
1602       *    </ul>
1603       * <p>
1604       *    <c>Accept</c> request header will be set to <js>"text/openapi"</js> unless overridden
1605       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1606       * <p>
1607       *    <c>Content-Type</c> request header will be set to <js>"text/openapi"</js> unless overridden
1608       *       via {@link #headers()}, or per-request via {@link RestRequest#header(Header)}.
1609       * <p>
1610       *    Can be combined with other marshaller setters such as {@link #json()} to provide support for multiple languages.
1611       *    <ul>
1612       *       <li>When multiple languages are supported, the <c>Accept</c> and <c>Content-Type</c> headers control which marshallers are used, or uses the
1613       *       last-enabled language if the headers are not set.
1614       *    </ul>
1615       * <p>
1616       *    Identical to calling <c>serializer(OpenApiSerializer.<jk>class</jk>).parser(OpenApiParser.<jk>class</jk>)</c>.
1617       *
1618       * <h5 class='section'>Example:</h5>
1619       * <p class='bjava'>
1620       *    <jc>// Construct a client that uses OpenAPI marshalling.</jc>
1621       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().openApi().build();
1622       * </p>
1623       *
1624       * @return This object.
1625       */
1626      @FluentSetter
1627      public Builder openApi() {
1628         return serializer(OpenApiSerializer.class).parser(OpenApiParser.class);
1629      }
1630
1631      /**
1632       * Convenience method for specifying all available transmission types.
1633       *
1634       * <p>
1635       *    All basic Juneau serializers will be used to serialize POJOs to request bodies unless overridden per request via {@link RestRequest#serializer(Serializer)}.
1636       *    <ul>
1637       *       <li>The serializers can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1638       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1639       *    </ul>
1640       * <p>
1641       *    All basic Juneau parsers will be used to parse POJOs from response bodies unless overridden per request via {@link RestRequest#parser(Parser)}.
1642       *    <ul>
1643       *       <li>The parsers can be configured using any of the parser property setters (e.g. {@link #strict()}) or
1644       *          bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1645       *    </ul>
1646       * <p>
1647       *    <c>Accept</c> request header must be set via {@link #headers()}, or per-request
1648       *       via {@link RestRequest#header(Header)} in order for the correct parser to be selected.
1649       * <p>
1650       *    <c>Content-Type</c> request header must be set via {@link #headers()},
1651       *       or per-request via {@link RestRequest#header(Header)} in order for the correct serializer to be selected.
1652       * <p>
1653       *    Similar to calling <c>json().json5().html().xml().uon().urlEnc().openApi().msgPack().plainText()</c>.
1654       *
1655       * <h5 class='section'>Example:</h5>
1656       * <p class='bjava'>
1657       *    <jc>// Construct a client that uses universal marshalling.</jc>
1658       *    RestClient <jv>client</jv> = RestClient.<jsm>create</jsm>().universal().build();
1659       * </p>
1660       *
1661       * @return This object.
1662       */
1663      @SuppressWarnings("unchecked")
1664      public Builder universal() {
1665         return
1666            serializers(
1667               JsonSerializer.class,
1668               Json5Serializer.class,
1669               HtmlSerializer.class,
1670               XmlSerializer.class,
1671               UonSerializer.class,
1672               UrlEncodingSerializer.class,
1673               OpenApiSerializer.class,
1674               MsgPackSerializer.class,
1675               PlainTextSerializer.class
1676            )
1677            .parsers(
1678               JsonParser.class,
1679               Json5Parser.class,
1680               XmlParser.class,
1681               HtmlParser.class,
1682               UonParser.class,
1683               UrlEncodingParser.class,
1684               OpenApiParser.class,
1685               MsgPackParser.class,
1686               PlainTextParser.class
1687            );
1688      }
1689
1690      //------------------------------------------------------------------------------------------------------------------
1691      // httpClientBuilder
1692      //------------------------------------------------------------------------------------------------------------------
1693
1694      /**
1695       * Returns the HTTP client builder.
1696       *
1697       * @return The HTTP client builder.
1698       */
1699      public final HttpClientBuilder httpClientBuilder() {
1700         if (httpClientBuilder == null)
1701            httpClientBuilder = createHttpClientBuilder();
1702         return httpClientBuilder;
1703      }
1704
1705      /**
1706       * Creates an instance of an {@link HttpClientBuilder} to be used to create the {@link HttpClient}.
1707       *
1708       * <p>
1709       * Subclasses can override this method to provide their own client builder.
1710       * The builder can also be specified using the {@link #httpClientBuilder(HttpClientBuilder)} method.
1711       *
1712       * <h5 class='section'>Example:</h5>
1713       * <p class='bjava'>
1714       *    <jc>// A Builder that provides it's own customized HttpClientBuilder.</jc>
1715       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
1716       *       <ja>@Override</ja>
1717       *       <jk>protected</jk> HttpClientBuilder createHttpClientBuilder() {
1718       *          <jk>return</jk> HttpClientBuilder.<jsm>create</jsm>();
1719       *       }
1720       *    }
1721       *
1722       *    <jc>// Instantiate.</jc>
1723       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
1724       * </p>
1725       *
1726       * @return The HTTP client builder to use to create the HTTP client.
1727       */
1728      protected HttpClientBuilder createHttpClientBuilder() {
1729         return HttpClientBuilder.create();
1730      }
1731
1732      /**
1733       * Sets the {@link HttpClientBuilder} that will be used to create the {@link HttpClient} used by {@link RestClient}.
1734       *
1735       * <p>
1736       * This can be used to bypass the builder created by {@link #createHttpClientBuilder()} method.
1737       *
1738       * <h5 class='section'>Example:</h5>
1739       * <p class='bjava'>
1740       *    <jc>// Construct a client that uses a customized HttpClientBuilder.</jc>
1741       *    RestClient <jv>client</jv> = RestClient
1742       *       .<jsm>create</jsm>()
1743       *       .httpClientBuilder(HttpClientBuilder.<jsm>create</jsm>())
1744       *       .build();
1745       * </p>
1746       *
1747       * @param value The {@link HttpClientBuilder} that will be used to create the {@link HttpClient} used by {@link RestClient}.
1748       * @return This object.
1749       */
1750      @FluentSetter
1751      public Builder httpClientBuilder(HttpClientBuilder value) {
1752         this.httpClientBuilder = value;
1753         return this;
1754      }
1755
1756      //------------------------------------------------------------------------------------------------------------------
1757      // httpClient
1758      //------------------------------------------------------------------------------------------------------------------
1759
1760      /**
1761       * Creates an instance of an {@link HttpClient} to be used to handle all HTTP communications with the target server.
1762       *
1763       * <p>
1764       * This HTTP client is used when the HTTP client is not specified through one of the constructors or the
1765       * {@link #httpClient(CloseableHttpClient)} method.
1766       *
1767       * <p>
1768       * Subclasses can override this method to provide specially-configured HTTP clients to handle stuff such as
1769       * SSL/TLS certificate handling, authentication, etc.
1770       *
1771       * <p>
1772       * The default implementation returns an instance of {@link HttpClient} using the client builder returned by
1773       * {@link #createHttpClientBuilder()}.
1774       *
1775       * <h5 class='section'>Example:</h5>
1776       * <p class='bjava'>
1777       *    <jc>// A Builder that provides it's own customized HttpClient.</jc>
1778       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
1779       *       <ja>@Override</ja>
1780       *       <jk>protected</jk> HttpClientBuilder createHttpClient() {
1781       *          <jk>return</jk> HttpClientBuilder.<jsm>create</jsm>().build();
1782       *       }
1783       *    }
1784       *
1785       *    <jc>// Instantiate.</jc>
1786       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
1787       * </p>
1788       *
1789       * @return The HTTP client to use.
1790       */
1791      protected CloseableHttpClient createHttpClient() {
1792         if (connectionManager == null)
1793            connectionManager = createConnectionManager();
1794         httpClientBuilder().setConnectionManager(connectionManager);
1795         return httpClientBuilder().build();
1796      }
1797
1798      /**
1799       * Sets the {@link HttpClient} to be used to handle all HTTP communications with the target server.
1800       *
1801       * <p>
1802       * This can be used to bypass the client created by {@link #createHttpClient()} method.
1803       *
1804       * <h5 class='section'>Example:</h5>
1805       * <p class='bjava'>
1806       *    <jc>// Construct a client that uses a customized HttpClient.</jc>
1807       *    RestClient <jv>client</jv> = RestClient
1808       *       .<jsm>create</jsm>()
1809       *       .httpClient(HttpClientBuilder.<jsm>create</jsm>().build())
1810       *       .build();
1811       * </p>
1812       *
1813       * @param value The {@link HttpClient} to be used to handle all HTTP communications with the target server.
1814       * @return This object.
1815       */
1816      @FluentSetter
1817      public Builder httpClient(CloseableHttpClient value) {
1818         this.httpClient = value;
1819         return this;
1820      }
1821
1822      final CloseableHttpClient getHttpClient() {
1823         return httpClient != null ? httpClient : createHttpClient();
1824      }
1825
1826      //------------------------------------------------------------------------------------------------------------------
1827      // serializers
1828      //------------------------------------------------------------------------------------------------------------------
1829
1830      /**
1831       * Returns the serializer group sub-builder.
1832       *
1833       * @return The serializer group sub-builder.
1834       */
1835      public final SerializerSet.Builder serializers() {
1836         if (serializers == null)
1837            serializers = createSerializers();
1838         return serializers;
1839      }
1840
1841      /**
1842       * Instantiates the serializer group sub-builder.
1843       *
1844       * @return A new serializer group sub-builder.
1845       */
1846      protected SerializerSet.Builder createSerializers() {
1847         return SerializerSet.create().beanContext(beanContext());
1848      }
1849
1850      /**
1851       * Serializer.
1852       *
1853       * <p>
1854       * Associates the specified {@link Serializer Serializer} with the HTTP client.
1855       *
1856       * <p>
1857       * The serializer is used to serialize POJOs into the HTTP request body.
1858       *
1859       * <h5 class='section'>Notes:</h5><ul>
1860       *    <li class='note'>When using this method that takes in a class, the serializer can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1861       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1862       * </ul>
1863       *
1864       * <h5 class='section'>Example:</h5>
1865       * <p class='bjava'>
1866       *    <jc>// Create a client that uses JSON transport for request bodies.</jc>
1867       *    RestClient <jv>client</jv> = RestClient
1868       *       .<jsm>create</jsm>()
1869       *       .serializer(JsonSerializer.<jk>class</jk>)
1870       *       .sortCollections()  <jc>// Sort any collections being serialized.</jc>
1871       *       .build();
1872       * </p>
1873       *
1874       * @param value
1875       *    The new value for this setting.
1876       *    <br>The default is {@link JsonSerializer}.
1877       * @return This object.
1878       */
1879      @SuppressWarnings("unchecked")
1880      @FluentSetter
1881      public Builder serializer(Class<? extends Serializer> value) {
1882         return serializers(value);
1883      }
1884
1885      /**
1886       * Serializer.
1887       *
1888       * <p>
1889       * Associates the specified {@link Serializer Serializer} with the HTTP client.
1890       *
1891       * <p>
1892       * The serializer is used to serialize POJOs into the HTTP request body.
1893       *
1894       * <h5 class='section'>Notes:</h5><ul>
1895       *    <li class='note'>When using this method that takes in a pre-instantiated serializer, the serializer property setters (e.g. {@link #sortCollections()}) or
1896       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
1897       *    on this builder class have no effect.
1898       * </ul>
1899       *
1900       * <h5 class='section'>Example:</h5>
1901       * <p class='bjava'>
1902       *    <jc>// Create a client that uses a predefined JSON serializer request bodies.</jc>
1903       *    RestClient <jv>client</jv> = RestClient
1904       *       .<jsm>create</jsm>()
1905       *       .serializer(JsonSerializer.<jsf>DEFAULT_READABLE</jsf>)
1906       *       .build();
1907       * </p>
1908       *
1909       * @param value
1910       *    The new value for this setting.
1911       *    <br>The default is {@link JsonSerializer}.
1912       * @return This object.
1913       */
1914      @FluentSetter
1915      public Builder serializer(Serializer value) {
1916         return serializers(value);
1917      }
1918
1919      /**
1920       * Serializers.
1921       *
1922       * <p>
1923       * Associates the specified {@link Serializer Serializers} with the HTTP client.
1924       *
1925       * <p>
1926       * The serializer is used to serialize POJOs into the HTTP request body.
1927       *
1928       * <p>
1929       * The serializer that best matches the <c>Content-Type</c> header will be used to serialize the request body.
1930       * <br>If no <c>Content-Type</c> header is specified, the first serializer in the list will be used.
1931       *
1932       * <h5 class='section'>Notes:</h5><ul>
1933       *    <li class='note'>When using this method that takes in classes, the serializers can be configured using any of the serializer property setters (e.g. {@link #sortCollections()}) or
1934       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
1935       * </ul>
1936       *
1937       * <h5 class='section'>Example:</h5>
1938       * <p class='bjava'>
1939       *    <jc>// Create a client that uses JSON and XML transport for request bodies.</jc>
1940       *    RestClient <jv>client</jv> = RestClient
1941       *       .<jsm>create</jsm>()
1942       *       .serializers(JsonSerializer.<jk>class</jk>, XmlSerializer.<jk>class</jk>)
1943       *       .sortCollections()  <jc>// Sort any collections being serialized.</jc>
1944       *       .build();
1945       * </p>
1946       *
1947       * @param value
1948       *    The new value for this setting.
1949       *    <br>The default is {@link JsonSerializer}.
1950       * @return This object.
1951       */
1952      @SuppressWarnings("unchecked")
1953      @FluentSetter
1954      public Builder serializers(Class<? extends Serializer>...value) {
1955         serializers().add(value);
1956         return this;
1957      }
1958
1959      /**
1960       * Serializers.
1961       *
1962       * <p>
1963       * Associates the specified {@link Serializer Serializers} with the HTTP client.
1964       *
1965       * <p>
1966       * The serializer is used to serialize POJOs into the HTTP request body.
1967       *
1968       * <p>
1969       * The serializer that best matches the <c>Content-Type</c> header will be used to serialize the request body.
1970       * <br>If no <c>Content-Type</c> header is specified, the first serializer in the list will be used.
1971       *
1972       * <h5 class='section'>Notes:</h5><ul>
1973       *    <li class='note'>When using this method that takes in a pre-instantiated serializers, the serializer property setters (e.g. {@link #sortCollections()}) or
1974       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
1975       *    on this builder class have no effect.
1976       * </ul>
1977       *
1978       * <h5 class='section'>Example:</h5>
1979       * <p class='bjava'>
1980       *    <jc>// Create a client that uses predefined JSON and XML serializers for request bodies.</jc>
1981       *    RestClient <jv>client</jv> = RestClient
1982       *       .<jsm>create</jsm>()
1983       *       .serializers(JsonSerializer.<jsf>DEFAULT_READABLE</jsf>, XmlSerializer.<jsf>DEFAULT_READABLE</jsf>)
1984       *       .build();
1985       * </p>
1986       *
1987       * @param value
1988       *    The new value for this setting.
1989       *    <br>The default is {@link JsonSerializer}.
1990       * @return This object.
1991       */
1992      @FluentSetter
1993      public Builder serializers(Serializer...value) {
1994         serializers().add(value);
1995         return this;
1996      }
1997
1998      //------------------------------------------------------------------------------------------------------------------
1999      // parsers
2000      //------------------------------------------------------------------------------------------------------------------
2001
2002      /**
2003       * Returns the parser group sub-builder.
2004       *
2005       * @return The parser group sub-builder.
2006       */
2007      public final ParserSet.Builder parsers() {
2008         if (parsers == null)
2009            parsers = createParsers();
2010         return parsers;
2011      }
2012
2013      /**
2014       * Instantiates the parser group sub-builder.
2015       *
2016       * @return A new parser group sub-builder.
2017       */
2018      protected ParserSet.Builder createParsers() {
2019         return ParserSet.create().beanContext(beanContext());
2020      }
2021
2022      /**
2023       * Parser.
2024       *
2025       * <p>
2026       * Associates the specified {@link Parser Parser} with the HTTP client.
2027       *
2028       * <p>
2029       * The parser is used to parse the HTTP response body into a POJO.
2030       *
2031       * <h5 class='section'>Notes:</h5><ul>
2032       *    <li class='note'>When using this method that takes in a class, the parser can be configured using any of the parser property setters (e.g. {@link #strict()}) or
2033       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
2034       * </ul>
2035       *
2036       * <h5 class='section'>Example:</h5>
2037       * <p class='bjava'>
2038       *    <jc>// Create a client that uses JSON transport for response bodies.</jc>
2039       *    RestClient <jv>client</jv> = RestClient
2040       *       .<jsm>create</jsm>()
2041       *       .parser(JsonParser.<jk>class</jk>)
2042       *       .strict()  <jc>// Enable strict mode on JsonParser.</jc>
2043       *       .build();
2044       * </p>
2045       *
2046       * @param value
2047       *    The new value for this setting.
2048       *    <br>The default value is {@link JsonParser#DEFAULT}.
2049       * @return This object.
2050       */
2051      @SuppressWarnings("unchecked")
2052      @FluentSetter
2053      public Builder parser(Class<? extends Parser> value) {
2054         return parsers(value);
2055      }
2056
2057      /**
2058       * Parser.
2059       *
2060       * <p>
2061       * Associates the specified {@link Parser Parser} with the HTTP client.
2062       *
2063       * <p>
2064       * The parser is used to parse the HTTP response body into a POJO.
2065       *
2066       * <h5 class='section'>Notes:</h5><ul>
2067       *    <li class='note'>When using this method that takes in a pre-instantiated parser, the parser property setters (e.g. {@link #strict()}) or
2068       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
2069       *    on this builder class have no effect.
2070       * </ul>
2071       *
2072       * <h5 class='section'>Example:</h5>
2073       * <p class='bjava'>
2074       *    <jc>// Create a client that uses a predefined JSON parser for response bodies.</jc>
2075       *    RestClient <jv>client</jv> = RestClient
2076       *       .<jsm>create</jsm>()
2077       *       .parser(JsonParser.<jsf>DEFAULT_STRICT</jsf>)
2078       *       .build();
2079       * </p>
2080       *
2081       * @param value
2082       *    The new value for this setting.
2083       *    <br>The default value is {@link JsonParser#DEFAULT}.
2084       * @return This object.
2085       */
2086      @FluentSetter
2087      public Builder parser(Parser value) {
2088         return parsers(value);
2089      }
2090
2091      /**
2092       * Parsers.
2093       *
2094       * <p>
2095       * Associates the specified {@link Parser Parsers} with the HTTP client.
2096       *
2097       * <p>
2098       * The parsers are used to parse the HTTP response body into a POJO.
2099       *
2100       * <p>
2101       * The parser that best matches the <c>Accept</c> header will be used to parse the response body.
2102       * <br>If no <c>Accept</c> header is specified, the first parser in the list will be used.
2103       *
2104       * <h5 class='section'>Notes:</h5><ul>
2105       *    <li class='note'>When using this method that takes in classes, the parsers can be configured using any of the parser property setters (e.g. {@link #strict()}) or
2106       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class.
2107       * </ul>
2108       *
2109       * <h5 class='section'>Example:</h5>
2110       * <p class='bjava'>
2111       *    <jc>// Create a client that uses JSON and XML transport for response bodies.</jc>
2112       *    RestClient <jv>client</jv> = RestClient
2113       *       .<jsm>create</jsm>()
2114       *       .parser(JsonParser.<jk>class</jk>, XmlParser.<jk>class</jk>)
2115       *       .strict()  <jc>// Enable strict mode on parsers.</jc>
2116       *       .build();
2117       * </p>
2118       *
2119       * @param value
2120       *    The new value for this setting.
2121       *    <br>The default value is {@link JsonParser#DEFAULT}.
2122       * @return This object.
2123       */
2124      @SuppressWarnings("unchecked")
2125      @FluentSetter
2126      public Builder parsers(Class<? extends Parser>...value) {
2127         parsers().add(value);
2128         return this;
2129      }
2130
2131      /**
2132       * Parsers.
2133       *
2134       * <p>
2135       * Associates the specified {@link Parser Parsers} with the HTTP client.
2136       *
2137       * <p>
2138       * The parsers are used to parse the HTTP response body into a POJO.
2139       *
2140       * <p>
2141       * The parser that best matches the <c>Accept</c> header will be used to parse the response body.
2142       * <br>If no <c>Accept</c> header is specified, the first parser in the list will be used.
2143       *
2144       * <h5 class='section'>Notes:</h5><ul>
2145       *    <li class='note'>When using this method that takes in pre-instantiated parsers, the parser property setters (e.g. {@link #strict()}) or
2146       *    bean context property setters (e.g. {@link #swaps(Class...)}) defined
2147       *    on this builder class have no effect.
2148       * </ul>
2149       *
2150       * <h5 class='section'>Example:</h5>
2151       * <p class='bjava'>
2152       *    <jc>// Create a client that uses JSON and XML transport for response bodies.</jc>
2153       *    RestClient <jv>client</jv> = RestClient
2154       *       .<jsm>create</jsm>()
2155       *       .parser(JsonParser.<jsf>DEFAULT_STRICT</jsf>, XmlParser.<jsf>DEFAULT</jsf>)
2156       *       .build();
2157       * </p>
2158       *
2159       * @param value
2160       *    The new value for this setting.
2161       *    <br>The default value is {@link JsonParser#DEFAULT}.
2162       * @return This object.
2163       */
2164      @FluentSetter
2165      public Builder parsers(Parser...value) {
2166         parsers().add(value);
2167         return this;
2168      }
2169
2170      //------------------------------------------------------------------------------------------------------------------
2171      // partSerializer
2172      //------------------------------------------------------------------------------------------------------------------
2173
2174      /**
2175       * Returns the part serializer sub-builder.
2176       *
2177       * @return The part serializer sub-builder.
2178       */
2179      public final HttpPartSerializer.Creator partSerializer() {
2180         if (partSerializer == null)
2181            partSerializer = createPartSerializer();
2182         return partSerializer;
2183      }
2184
2185      /**
2186       * Instantiates the part serializer sub-builder.
2187       *
2188       * @return A new part serializer sub-builder.
2189       */
2190      protected HttpPartSerializer.Creator createPartSerializer() {
2191         return HttpPartSerializer.creator().type(OpenApiSerializer.class).beanContext(beanContext());
2192      }
2193
2194      /**
2195       * Part serializer.
2196       *
2197       * <p>
2198       * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
2199       *
2200       * <p>
2201       * The default part serializer is {@link OpenApiSerializer} which allows for schema-driven marshalling.
2202       *
2203       * <h5 class='section'>Example:</h5>
2204       * <p class='bjava'>
2205       *    <jc>// Create a client that uses UON format by default for outgoing HTTP parts.</jc>
2206       *    RestClient <jv>client</jv> = RestClient
2207       *       .<jsm>create</jsm>()
2208       *       .partSerializer(UonSerializer.<jk>class</jk>)
2209       *       .build();
2210       * </p>
2211       *
2212       * @param value
2213       *    The new value for this setting.
2214       *    <br>The default value is {@link OpenApiSerializer}.
2215       * @return This object.
2216       */
2217      @FluentSetter
2218      public Builder partSerializer(Class<? extends HttpPartSerializer> value) {
2219         partSerializer().type(value);
2220         return this;
2221      }
2222
2223      /**
2224       * Part serializer.
2225       *
2226       * <p>
2227       * The serializer to use for serializing POJOs in form data, query parameters, headers, and path variables.
2228       *
2229       * <p>
2230       * The default part serializer is {@link OpenApiSerializer} which allows for schema-driven marshalling.
2231       *
2232       * <h5 class='section'>Example:</h5>
2233       * <p class='bjava'>
2234       *    <jc>// Create a client that uses UON format by default for outgoing HTTP parts.</jc>
2235       *    RestClient <jv>client</jv> = RestClient
2236       *       .<jsm>create</jsm>()
2237       *       .partSerializer(UonSerializer.<jsf>DEFAULT</jsf>)
2238       *       .build();
2239       * </p>
2240       *
2241       * @param value
2242       *    The new value for this setting.
2243       *    <br>The default value is {@link OpenApiSerializer}.
2244       * @return This object.
2245       */
2246      @FluentSetter
2247      public Builder partSerializer(HttpPartSerializer value) {
2248         partSerializer().impl(value);
2249         return this;
2250      }
2251
2252      //------------------------------------------------------------------------------------------------------------------
2253      // partParser
2254      //------------------------------------------------------------------------------------------------------------------
2255
2256      /**
2257       * Returns the part parser sub-builder.
2258       *
2259       * @return The part parser sub-builder.
2260       */
2261      public final HttpPartParser.Creator partParser() {
2262         if (partParser == null)
2263            partParser = createPartParser();
2264         return partParser;
2265      }
2266
2267      /**
2268       * Instantiates the part parser sub-builder.
2269       *
2270       * @return A new part parser sub-builder.
2271       */
2272      protected HttpPartParser.Creator createPartParser() {
2273         return HttpPartParser.creator().type(OpenApiParser.class).beanContext(beanContext());
2274      }
2275
2276      /**
2277       * Part parser.
2278       *
2279       * <p>
2280       * The parser to use for parsing POJOs from form data, query parameters, headers, and path variables.
2281       *
2282       * <p>
2283       * The default part parser is {@link OpenApiParser} which allows for schema-driven marshalling.
2284       *
2285       * <h5 class='section'>Example:</h5>
2286       * <p class='bjava'>
2287       *    <jc>// Create a client that uses UON format by default for incoming HTTP parts.</jc>
2288       *    RestClient <jv>client</jv> = RestClient
2289       *       .<jsm>create</jsm>()
2290       *       .partParser(UonParser.<jk>class</jk>)
2291       *       .build();
2292       * </p>
2293       *
2294       * @param value
2295       *    The new value for this setting.
2296       *    <br>The default value is {@link OpenApiParser}.
2297       * @return This object.
2298       */
2299      @FluentSetter
2300      public Builder partParser(Class<? extends HttpPartParser> value) {
2301         partParser().type(value);
2302         return this;
2303      }
2304
2305      /**
2306       * Part parser.
2307       *
2308       * <p>
2309       * The parser to use for parsing POJOs from form data, query parameters, headers, and path variables.
2310       *
2311       * <p>
2312       * The default part parser is {@link OpenApiParser} which allows for schema-driven marshalling.
2313       *
2314       * <h5 class='section'>Example:</h5>
2315       * <p class='bjava'>
2316       *    <jc>// Create a client that uses UON format by default for incoming HTTP parts.</jc>
2317       *    RestClient <jv>client</jv> = RestClient
2318       *       .<jsm>create</jsm>()
2319       *       .partParser(UonParser.<jsf>DEFAULT</jsf>)
2320       *       .build();
2321       * </p>
2322       *
2323       * @param value
2324       *    The new value for this setting.
2325       *    <br>The default value is {@link OpenApiParser}.
2326       * @return This object.
2327       */
2328      @FluentSetter
2329      public Builder partParser(HttpPartParser value) {
2330         partParser().impl(value);
2331         return this;
2332      }
2333
2334      //------------------------------------------------------------------------------------------------------------------
2335      // urlEncodingSerializer
2336      //------------------------------------------------------------------------------------------------------------------
2337
2338      /**
2339       * Returns the URL-encoding serializer sub-builder.
2340       *
2341       * @return The URL-encoding serializer sub-builder.
2342       */
2343      public final UrlEncodingSerializer.Builder urlEncodingSerializer() {
2344         if (urlEncodingSerializer == null)
2345            urlEncodingSerializer = createUrlEncodingSerializer();
2346         return urlEncodingSerializer;
2347      }
2348
2349      /**
2350       * Instantiates the URL-encoding serializer sub-builder.
2351       *
2352       * @return A new URL-encoding serializer sub-builder.
2353       */
2354      protected UrlEncodingSerializer.Builder createUrlEncodingSerializer() {
2355         return UrlEncodingSerializer.create().beanContext(beanContext());
2356      }
2357
2358      //------------------------------------------------------------------------------------------------------------------
2359      // headerData
2360      //------------------------------------------------------------------------------------------------------------------
2361
2362      /**
2363       * Returns the builder for the list of headers that get applied to all requests created by this builder.
2364       *
2365       * <p>
2366       * This is the primary method for accessing the request header list.
2367       * On first call, the builder is created via the method {@link #createHeaderData()}.
2368       *
2369       * <h5 class='section'>Example:</h5>
2370       * <p class='bjava'>
2371       *    <jc>// Create a client that adds a "Foo: bar" header on every request.</jc>
2372       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2373       *    <jv>builder</jv>.headerData().setDefault(<js>"Foo"</js>, <js>"bar"</js>));
2374       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2375       * </p>
2376       *
2377       * <p>
2378       * The following convenience methods are also provided for updating the headers:
2379       * <ul>
2380       *    <li class='jm'>{@link #headers(Header...)}
2381       *    <li class='jm'>{@link #headersDefault(Header...)}
2382       *    <li class='jm'>{@link #header(String,String)}
2383       *    <li class='jm'>{@link #header(String,Supplier)}
2384       *    <li class='jm'>{@link #mediaType(String)}
2385       *    <li class='jm'>{@link #mediaType(MediaType)}
2386       *    <li class='jm'>{@link #accept(String)}
2387       *    <li class='jm'>{@link #acceptCharset(String)}
2388       *    <li class='jm'>{@link #clientVersion(String)}
2389       *    <li class='jm'>{@link #contentType(String)}
2390       *    <li class='jm'>{@link #debug()}
2391       *    <li class='jm'>{@link #noTrace()}
2392       * </ul>
2393       *
2394       * @return The header list builder.
2395       */
2396      public final HeaderList headers() {
2397         if (headerData == null)
2398            headerData = createHeaderData();
2399         return headerData;
2400      }
2401
2402      /**
2403       * Creates the builder for the header list.
2404       *
2405       * <p>
2406       * Subclasses can override this method to provide their own implementation.
2407       *
2408       * <p>
2409       * The default behavior creates an empty builder.
2410       *
2411       * @return The header list builder.
2412       * @see #headers()
2413       */
2414      protected HeaderList createHeaderData() {
2415         return HeaderList.create();
2416      }
2417
2418      /**
2419       * Appends multiple headers to all requests.
2420       *
2421       * <h5 class='section'>Example:</h5>
2422       * <p class='bjava'>
2423       *    <jk>import static</jk> org.apache.juneau.http.HttpHeaders.*;
2424       *
2425       *    RestClient <jv>client</jv> = RestClient
2426       *       .<jsm>create</jsm>()
2427       *       .headers(
2428       *          <jsf>ACCEPT_TEXT_XML</jsf>,
2429       *          <jsm>stringHeader</jsm>(<js>"Foo"</js>, <js>"bar"</js>)
2430       *       )
2431       *       .build();
2432       * </p>
2433       *
2434       * <p>
2435       * This is a shortcut for calling <c>headerData().append(<jv>parts</jv>)</c>.
2436       *
2437       * @param parts
2438       *    The header to set.
2439       * @return This object.
2440       * @see #headers()
2441       */
2442      @FluentSetter
2443      public Builder headers(Header...parts) {
2444         headers().append(parts);
2445         return this;
2446      }
2447
2448      /**
2449       * Sets default header values.
2450       *
2451       * <p>
2452       * Uses default values for specified headers if not otherwise specified on the outgoing requests.
2453       *
2454       * <h5 class='section'>Example:</h5>
2455       * <p class='bjava'>
2456       *    RestClient <jv>client</jv> = RestClient
2457       *       .<jsm>create</jsm>()
2458       *       .headersDefault(<jsm>stringHeader</jsm>(<js>"Foo"</js>, ()-&gt;<js>"bar"</js>));
2459       *       .build();
2460       * </p>
2461       *
2462       * <p>
2463       * This is a shortcut for calling <c>headerData().setDefault(<jv>parts</jv>)</c>.
2464       *
2465       * @param parts The header values.
2466       * @return This object.
2467       * @see #headers()
2468       */
2469      public Builder headersDefault(Header...parts) {
2470         headers().setDefault(parts);
2471         return this;
2472      }
2473
2474      /**
2475       * Appends a header to all requests.
2476       *
2477       * <h5 class='section'>Example:</h5>
2478       * <p class='bjava'>
2479       *    RestClient <jv>client</jv> = RestClient
2480       *       .<jsm>create</jsm>()
2481       *       .header(<js>"Foo"</js>, <js>"bar"</js>);
2482       *       .build();
2483       * </p>
2484       *
2485       * <p>
2486       * This is a shortcut for calling <c>headerData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2487       *
2488       * @param name The header name.
2489       * @param value The header value.
2490       * @return This object.
2491       * @see #headers()
2492       */
2493      @FluentSetter
2494      public Builder header(String name, String value) {
2495         headers().append(name, value);
2496         return this;
2497      }
2498
2499      /**
2500       * Appends a header to all requests using a dynamic value.
2501       *
2502       * <h5 class='section'>Example:</h5>
2503       * <p class='bjava'>
2504       *    RestClient <jv>client</jv> = RestClient
2505       *       .<jsm>create</jsm>()
2506       *       .header(<js>"Foo"</js>, ()-&gt;<js>"bar"</js>);
2507       *       .build();
2508       * </p>
2509       *
2510       * <p>
2511       * This is a shortcut for calling <c>headerData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2512       *
2513       * @param name The header name.
2514       * @param value The header value supplier.
2515       * @return This object.
2516       * @see #headers()
2517       */
2518      @FluentSetter
2519      public Builder header(String name, Supplier<String> value) {
2520         headers().append(name, value);
2521         return this;
2522      }
2523
2524      /**
2525       * Appends the <c>Accept</c> and <c>Content-Type</c> headers on all requests made by this client.
2526       *
2527       * <p>
2528       * Headers are appended to the end of the current header list.
2529       *
2530       * <p>
2531       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>), ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2532       *
2533       * @param value The new header values.
2534       * @return This object.
2535       * @see #headers()
2536       */
2537      @FluentSetter
2538      public Builder mediaType(String value) {
2539         super.mediaType(MediaType.of(value));
2540         return headers(Accept.of(value), ContentType.of(value));
2541      }
2542
2543      /**
2544       * Appends the <c>Accept</c> and <c>Content-Type</c> headers on all requests made by this client.
2545       *
2546       * <p>
2547       * Headers are appended to the end of the current header list.
2548       *
2549       * <p>
2550       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>), ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2551       *
2552       * @param value The new header values.
2553       * @return This object.
2554       * @see #headers()
2555       */
2556      @Override
2557      @FluentSetter
2558      public Builder mediaType(MediaType value) {
2559         super.mediaType(value);
2560         return headers(Accept.of(value), ContentType.of(value));
2561      }
2562
2563      /**
2564       * Appends an <c>Accept</c> header on this request.
2565       *
2566       * <p>
2567       * This is a shortcut for calling <c>headerData().append(Accept.<jsm>of</jsm>(<jv>value</jv>))</c>.
2568       *
2569       * @param value
2570       *    The new header value.
2571       * @return This object.
2572       * @see #headers()
2573       */
2574      @FluentSetter
2575      public Builder accept(String value) {
2576         return headers(Accept.of(value));
2577      }
2578
2579      /**
2580       * Sets the value for the <c>Accept-Charset</c> request header on all requests.
2581       *
2582       * <p>
2583       * This is a shortcut for calling <c>headerData().append(AcceptCharset.<jsm>of</jsm>(<jv>value</jv>))</c>.
2584       *
2585       * @param value The new header value.
2586       * @return This object.
2587       * @see #headers()
2588       */
2589      @FluentSetter
2590      public Builder acceptCharset(String value) {
2591         return headers(AcceptCharset.of(value));
2592      }
2593
2594      /**
2595       * Sets the client version by setting the value for the <js>"Client-Version"</js> header.
2596       *
2597       * <p>
2598       * This is a shortcut for calling <c>headerData().append(ClientVersion.<jsm>of</jsm>(<jv>value</jv>))</c>.
2599       *
2600       * @param value The version string (e.g. <js>"1.2.3"</js>)
2601       * @return This object.
2602       * @see #headers()
2603       */
2604      @FluentSetter
2605      public Builder clientVersion(String value) {
2606         return headers(ClientVersion.of(value));
2607      }
2608
2609      /**
2610       * Sets the value for the <c>Content-Type</c> request header on all requests.
2611       *
2612       * <p>
2613       * This is a shortcut for calling <c>headerData().append(ContentType.<jsm>of</jsm>(<jv>value</jv>))</c>.
2614       *
2615       * <p>
2616       * This overrides the media type specified on the serializer.
2617       *
2618       * @param value The new header value.
2619       * @return This object.
2620       * @see #headers()
2621       */
2622      @FluentSetter
2623      public Builder contentType(String value) {
2624         return headers(ContentType.of(value));
2625      }
2626
2627      /**
2628       * Sets the value for the <c>Debug</c> request header on all requests.
2629       *
2630       * <p>
2631       * This is a shortcut for calling <c>headerData().append(Debug.<jsm>of</jsm>(<jv>value</jv>))</c>.
2632       *
2633       * @return This object.
2634       * @see #headers()
2635       */
2636      @Override
2637      @FluentSetter
2638      public Builder debug() {
2639         super.debug();
2640         serializers().forEach(x -> x.debug());
2641         return headers(Debug.TRUE);
2642      }
2643
2644      /**
2645       * When called, <c>No-Trace: true</c> is added to requests.
2646       *
2647       * <p>
2648       * This gives the opportunity for the servlet to not log errors on invalid requests.
2649       * This is useful for testing purposes when you don't want your log file to show lots of errors that are simply the
2650       * results of testing.
2651       *
2652       * <p>
2653       * It's up to the server to decide whether to allow for this.
2654       * The <c>BasicTestRestLogger</c> class watches for this header and prevents logging of status 400+ responses to
2655       * prevent needless logging of test scenarios.
2656       *
2657       * @return This object.
2658       * @see #headers()
2659       */
2660      @FluentSetter
2661      public Builder noTrace() {
2662         return headers(NoTrace.of(true));
2663      }
2664
2665      //------------------------------------------------------------------------------------------------------------------
2666      // queryData
2667      //------------------------------------------------------------------------------------------------------------------
2668
2669      /**
2670       * Returns the builder for the list of query parameters that get applied to all requests created by this builder.
2671       *
2672       * <p>
2673       * This is the primary method for accessing the query parameter list.
2674       * On first call, the builder is created via the method {@link #createQueryData()}.
2675       *
2676       * <h5 class='section'>Example:</h5>
2677       * <p class='bjava'>
2678       *    <jc>// Create a client that adds a "foo=bar" query parameter on every request.</jc>
2679       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2680       *    <jv>builder</jv>.queryData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2681       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2682       * </p>
2683       *
2684       * <p>
2685       * The following convenience methods are also provided for updating the parameters:
2686       * <ul>
2687       *    <li class='jm'>{@link #queryData(NameValuePair...)}
2688       *    <li class='jm'>{@link #queryDataDefault(NameValuePair...)}
2689       *    <li class='jm'>{@link #queryData(String,String)}
2690       *    <li class='jm'>{@link #queryData(String,Supplier)}
2691       * </ul>
2692       *
2693       * @return The query data list builder.
2694       */
2695      public final PartList queryData() {
2696         if (queryData == null)
2697            queryData = createQueryData();
2698         return queryData;
2699      }
2700
2701      /**
2702       * Creates the builder for the query data list.
2703       *
2704       * <p>
2705       * Subclasses can override this method to provide their own implementation.
2706       *
2707       * <p>
2708       * The default behavior creates an empty builder.
2709       *
2710       * @return The query data list builder.
2711       * @see #queryData()
2712       */
2713      protected PartList createQueryData() {
2714         return PartList.create();
2715      }
2716
2717      /**
2718       * Appends multiple query parameters to the URI of all requests.
2719       *
2720       * <h5 class='section'>Example:</h5>
2721       * <p class='bjava'>
2722       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
2723       *
2724       *    RestClient <jv>client</jv> = RestClient
2725       *       .<jsm>create</jsm>()
2726       *       .queryData(
2727       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
2728       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
2729       *       )
2730       *       .build();
2731       * </p>
2732       *
2733       * <p>
2734       * This is a shortcut for calling <c>queryData().append(<jv>parts</jv>)</c>.
2735       *
2736       * @param parts
2737       *    The query parameters.
2738       * @return This object.
2739       * @see #queryData()
2740       */
2741      @FluentSetter
2742      public Builder queryData(NameValuePair...parts) {
2743         queryData().append(parts);
2744         return this;
2745      }
2746
2747      /**
2748       * Sets default query parameter values.
2749       *
2750       * <p>
2751       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
2752       *
2753       * <h5 class='section'>Example:</h5>
2754       * <p class='bjava'>
2755       *    RestClient <jv>client</jv> = RestClient
2756       *       .<jsm>create</jsm>()
2757       *       .queryDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
2758       *       .build();
2759       * </p>
2760       *
2761       * <p>
2762       * This is a shortcut for calling <c>queryData().setDefault(<jv>parts</jv>)</c>.
2763       *
2764       * @param parts The parts.
2765       * @return This object.
2766       * @see #queryData()
2767       */
2768      public Builder queryDataDefault(NameValuePair...parts) {
2769         queryData().setDefault(parts);
2770         return this;
2771      }
2772
2773      /**
2774       * Appends a query parameter to the URI.
2775       *
2776       * <h5 class='section'>Example:</h5>
2777       * <p class='bjava'>
2778       *    RestClient <jv>client</jv> = RestClient
2779       *       .<jsm>create</jsm>()
2780       *       .queryData(<js>"foo"</js>, <js>"bar"</js>)
2781       *       .build();
2782       * </p>
2783       *
2784       * <p>
2785       * This is a shortcut for calling <c>queryData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2786       *
2787       * @param name The parameter name.
2788       * @param value The parameter value.
2789       * @return This object.
2790       * @see #queryData()
2791       */
2792      @FluentSetter
2793      public Builder queryData(String name, String value) {
2794         queryData().append(name, value);
2795         return this;
2796      }
2797
2798      /**
2799       * Appends a query parameter with a dynamic value to the URI.
2800       *
2801       * <h5 class='section'>Example:</h5>
2802       * <p class='bjava'>
2803       *    RestClient <jv>client</jv> = RestClient
2804       *       .<jsm>create</jsm>()
2805       *       .queryData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
2806       *       .build();
2807       * </p>
2808       *
2809       * <p>
2810       * This is a shortcut for calling <c>queryData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2811       *
2812       * @param name The parameter name.
2813       * @param value The parameter value supplier.
2814       * @return This object.
2815       * @see #queryData()
2816       */
2817      @FluentSetter
2818      public Builder queryData(String name, Supplier<String> value) {
2819         queryData().append(name, value);
2820         return this;
2821      }
2822
2823      //------------------------------------------------------------------------------------------------------------------
2824      // formData
2825      //------------------------------------------------------------------------------------------------------------------
2826
2827      /**
2828       * Returns the builder for the list of form data parameters that get applied to all requests created by this builder.
2829       *
2830       * <p>
2831       * This is the primary method for accessing the form data parameter list.
2832       * On first call, the builder is created via the method {@link #createFormData()}.
2833       *
2834       * <h5 class='section'>Example:</h5>
2835       * <p class='bjava'>
2836       *    <jc>// Create a client that adds a "foo=bar" form-data parameter on every request.</jc>
2837       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2838       *    <jv>builder</jv>.formData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2839       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2840       * </p>
2841       *
2842       * <p>
2843       * The following convenience methods are also provided for updating the parameters:
2844       * <ul>
2845       *    <li class='jm'>{@link #formData(NameValuePair...)}
2846       *    <li class='jm'>{@link #formDataDefault(NameValuePair...)}
2847       *    <li class='jm'>{@link #formData(String,String)}
2848       *    <li class='jm'>{@link #formData(String,Supplier)}
2849       * </ul>
2850       *
2851       * @return The form data list builder.
2852       */
2853      public final PartList formData() {
2854         if (formData == null)
2855            formData = createFormData();
2856         return formData;
2857      }
2858
2859      /**
2860       * Creates the builder for the form data list.
2861       *
2862       * <p>
2863       * Subclasses can override this method to provide their own implementation.
2864       *
2865       * <p>
2866       * The default behavior creates an empty builder.
2867       *
2868       * @return The query data list builder.
2869       * @see #formData()
2870       */
2871      protected PartList createFormData() {
2872         return PartList.create();
2873      }
2874
2875      /**
2876       * Appends multiple form-data parameters to the request bodies of all URL-encoded form posts.
2877       *
2878       * <h5 class='section'>Example:</h5>
2879       * <p class='bjava'>
2880       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
2881       *
2882       *    RestClient <jv>client</jv> = RestClient
2883       *       .<jsm>create</jsm>()
2884       *       .formData(
2885       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
2886       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
2887       *       )
2888       *       .build();
2889       * </p>
2890       *
2891       * <p>
2892       * This is a shortcut for calling <c>formData().append(<jv>parts</jv>)</c>.
2893       *
2894       * @param parts
2895       *    The form-data parameters.
2896       * @return This object.
2897       * @see #formData()
2898       */
2899      @FluentSetter
2900      public Builder formData(NameValuePair...parts) {
2901         formData().append(parts);
2902         return this;
2903      }
2904
2905      /**
2906       * Sets default form-data parameter values.
2907       *
2908       * <p>
2909       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
2910       *
2911       * <h5 class='section'>Example:</h5>
2912       * <p class='bjava'>
2913       *    RestClient <jv>client</jv> = RestClient
2914       *       .<jsm>create</jsm>()
2915       *       .formDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
2916       *       .build();
2917       * </p>
2918       *
2919       * <p>
2920       * This is a shortcut for calling <c>formData().setDefault(<jv>parts</jv>)</c>.
2921       *
2922       * @param parts The parts.
2923       * @return This object.
2924       * @see #formData()
2925       */
2926      public Builder formDataDefault(NameValuePair...parts) {
2927         formData().setDefault(parts);
2928         return this;
2929      }
2930
2931      /**
2932       * Appends a form-data parameter to all request bodies.
2933       *
2934       * <h5 class='section'>Example:</h5>
2935       * <p class='bjava'>
2936       *    RestClient <jv>client</jv> = RestClient
2937       *       .<jsm>create</jsm>()
2938       *       .formData(<js>"foo"</js>, <js>"bar"</js>)
2939       *       .build();
2940       * </p>
2941       *
2942       * <p>
2943       * This is a shortcut for calling <c>formData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2944       *
2945       * @param name The parameter name.
2946       * @param value The parameter value.
2947       * @return This object.
2948       * @see #formData()
2949       */
2950      @FluentSetter
2951      public Builder formData(String name, String value) {
2952         formData().append(name, value);
2953         return this;
2954      }
2955
2956      /**
2957       * Appends a form-data parameter with a dynamic value to all request bodies.
2958       *
2959       * <h5 class='section'>Example:</h5>
2960       * <p class='bjava'>
2961       *    RestClient <jv>client</jv> = RestClient
2962       *       .<jsm>create</jsm>()
2963       *       .formData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
2964       *       .build();
2965       * </p>
2966       *
2967       * <p>
2968       * This is a shortcut for calling <c>formData().append(<jv>name</jv>,<jv>value</jv>)</c>.
2969       *
2970       * @param name The parameter name.
2971       * @param value The parameter value supplier.
2972       * @return This object.
2973       * @see #formData()
2974       */
2975      @FluentSetter
2976      public Builder formData(String name, Supplier<String> value) {
2977         formData().append(name, value);
2978         return this;
2979      }
2980
2981      //------------------------------------------------------------------------------------------------------------------
2982      // pathData
2983      //------------------------------------------------------------------------------------------------------------------
2984
2985      /**
2986       * Returns the builder for the list of path data parameters that get applied to all requests created by this builder.
2987       *
2988       * <p>
2989       * This is the primary method for accessing the path data parameter list.
2990       * On first call, the builder is created via the method {@link #createFormData()}.
2991       *
2992       * <h5 class='section'>Example:</h5>
2993       * <p class='bjava'>
2994       *    <jc>// Create a client that uses "bar" for the "{foo}" path variable on every request.</jc>
2995       *    RestClient.Builder <jv>builder</jv> = RestClient.<jsm>create</jsm>();
2996       *    <jv>builder</jv>.pathData().setDefault(<js>"foo"</js>, <js>"bar"</js>));
2997       *    RestClient <jv>client</jv> = <jv>builder</jv>.build();
2998       * </p>
2999       *
3000       * <p>
3001       * The following convenience methods are also provided for updating the parameters:
3002       * <ul>
3003       *    <li class='jm'>{@link #pathData(NameValuePair...)}
3004       *    <li class='jm'>{@link #pathDataDefault(NameValuePair...)}
3005       *    <li class='jm'>{@link #pathData(String,String)}
3006       *    <li class='jm'>{@link #pathData(String,Supplier)}
3007       * </ul>
3008       *
3009       * @return The form data list builder.
3010       */
3011      public final PartList pathData() {
3012         if (pathData == null)
3013            pathData = createPathData();
3014         return pathData;
3015      }
3016
3017      /**
3018       * Creates the builder for the path data list.
3019       *
3020       * <p>
3021       * Subclasses can override this method to provide their own implementation.
3022       *
3023       * <p>
3024       * The default behavior creates an empty builder.
3025       *
3026       * @return The query data list builder.
3027       * @see #pathData()
3028       */
3029      protected PartList createPathData() {
3030         return PartList.create();
3031      }
3032
3033      /**
3034       * Sets multiple path parameters on all requests.
3035       *
3036       * <h5 class='section'>Example:</h5>
3037       * <p class='bjava'>
3038       *    <jk>import static</jk> org.apache.juneau.http.HttpParts.*;
3039       *
3040       *    RestClient <jv>client</jv> = RestClient
3041       *       .<jsm>create</jsm>()
3042       *       .pathData(
3043       *          <jsm>stringPart</jsm>(<js>"foo"</js>, <js>"bar"</js>),
3044       *          <jsm>booleanPart</jsm>(<js>"baz"</js>, <jk>true</jk>)
3045       *       )
3046       *       .build();
3047       * </p>
3048       *
3049       * <p>
3050       * This is a shortcut for calling <c>pathData().append(<jv>parts</jv>)</c>.
3051       *
3052       * @param parts
3053       *    The path parameters.
3054       * @return This object.
3055       * @see #pathData()
3056       */
3057      @FluentSetter
3058      public Builder pathData(NameValuePair...parts) {
3059         pathData().append(parts);
3060         return this;
3061      }
3062
3063      /**
3064       * Sets default path parameter values.
3065       *
3066       * <p>
3067       * Uses default values for specified parameters if not otherwise specified on the outgoing requests.
3068       *
3069       * <h5 class='section'>Example:</h5>
3070       * <p class='bjava'>
3071       *    RestClient <jv>client</jv> = RestClient
3072       *       .<jsm>create</jsm>()
3073       *       .pathDataDefault(<jsm>stringPart</jsm>(<js>"foo"</js>, ()-&gt;<js>"bar"</js>));
3074       *       .build();
3075       * </p>
3076       *
3077       * <p>
3078       * This is a shortcut for calling <c>pathData().setDefault(<jv>parts</jv>)</c>.
3079       *
3080       * @param parts The parts.
3081       * @return This object.
3082       * @see #pathData()
3083       */
3084      public Builder pathDataDefault(NameValuePair...parts) {
3085         pathData().setDefault(parts);
3086         return this;
3087      }
3088
3089      /**
3090       * Appends a path parameter to all request bodies.
3091       *
3092       * <h5 class='section'>Example:</h5>
3093       * <p class='bjava'>
3094       *    RestClient <jv>client</jv> = RestClient
3095       *       .<jsm>create</jsm>()
3096       *       .pathData(<js>"foo"</js>, <js>"bar"</js>)
3097       *       .build();
3098       * </p>
3099       *
3100       * <p>
3101       * This is a shortcut for calling <c>pathData().append(<jv>name</jv>,<jv>value</jv>)</c>.
3102       *
3103       * @param name The parameter name.
3104       * @param value The parameter value.
3105       * @return This object.
3106       * @see #pathData()
3107       */
3108      @FluentSetter
3109      public Builder pathData(String name, String value) {
3110         pathData().append(name, value);
3111         return this;
3112      }
3113
3114      /**
3115       * Sets a path parameter with a dynamic value to all request bodies.
3116       *
3117       * <h5 class='section'>Example:</h5>
3118       * <p class='bjava'>
3119       *    RestClient <jv>client</jv> = RestClient
3120       *       .<jsm>create</jsm>()
3121       *       .pathData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
3122       *       .build();
3123       * </p>
3124       *
3125       * <p>
3126       * This is a shortcut for calling <c>pathData().append(<jv>name</jv>,<jv>value</jv>)</c>.
3127       *
3128       * @param name The parameter name.
3129       * @param value The parameter value supplier.
3130       * @return This object.
3131       * @see #pathData()
3132       */
3133      @FluentSetter
3134      public Builder pathData(String name, Supplier<String> value) {
3135         pathData().set(name, value);
3136         return this;
3137      }
3138
3139      //------------------------------------------------------------------------------------------------------------------
3140      // callHandler
3141      //------------------------------------------------------------------------------------------------------------------
3142
3143      /**
3144       * Returns the creator for the rest call handler.
3145       *
3146       * <p>
3147       * Allows you to provide a custom handler for making HTTP calls.
3148       *
3149       * <h5 class='section'>Example:</h5>
3150       * <p class='bjava'>
3151       *    <jc>// Create a client that handles processing of requests using a custom handler.</jc>
3152       *    <jk>public class</jk> MyRestCallHandler <jk>implements</jk> RestCallHandler {
3153       *
3154       *       <ja>@Override</ja>
3155       *       <jk>public</jk> HttpResponse run(HttpHost <jv>target</jv>, HttpRequest <jv>request</jv>, HttpContext <jv>context</jv>) <jk>throws</jk> IOException {
3156       *          <jc>// Custom handle requests.</jc>
3157       *       }
3158       *    }
3159       *
3160       *    RestClient <jv>client</jv> = RestClient
3161       *       .<jsm>create</jsm>()
3162       *       .callHandler(MyRestCallHandler.<jk>class</jk>)
3163       *       .build();
3164       * </p>
3165       *
3166       * <h5 class='section'>Notes:</h5><ul>
3167       *    <li class='note'>
3168       *       The {@link RestClient#run(HttpHost, HttpRequest, HttpContext)} method can also be overridden to produce the same results.
3169       *    <li class='note'>
3170       *       Use {@link BeanCreator#impl(Object)} to specify an already instantiated instance.
3171       *    <li class='note'>
3172       *       Use {@link BeanCreator#type(Class)} to specify a subtype to instantiate.
3173       *       <br>Subclass must have a public constructor that takes in any args available
3174       *       in the bean store of this builder (including {@link RestClient} itself).
3175       * </ul>
3176       *
3177       * <h5 class='section'>See Also:</h5><ul>
3178       *    <li class='jic'>{@link RestCallHandler}
3179       * </ul>
3180       *
3181       * @return The creator for the rest call handler.
3182       */
3183      public final BeanCreator<RestCallHandler> callHandler() {
3184         if (callHandler == null)
3185            callHandler = createCallHandler();
3186         return callHandler;
3187      }
3188
3189      /**
3190       * Creates the creator for the rest call handler.
3191       *
3192       * <p>
3193       * Subclasses can override this method to provide their own implementation.
3194       *
3195       * <p>
3196       * The default behavior creates a bean creator initialized to return a {@link BasicRestCallHandler}.
3197       *
3198       * @return The creator for the rest call handler.
3199       * @see #callHandler()
3200       */
3201      protected BeanCreator<RestCallHandler> createCallHandler() {
3202         return beanStore.createBean(RestCallHandler.class).type(BasicRestCallHandler.class);
3203      }
3204
3205      /**
3206       * REST call handler class.
3207       *
3208       * <p>
3209       * Specifies a custom handler for making HTTP calls.
3210       *
3211       * <p>
3212       * This is a shortcut for <c>callHandler().type(<jv>value</jv>)</c>.
3213       *
3214       * @param value
3215       *    The new value for this setting.
3216       * @return This object.
3217       * @see #callHandler()
3218       */
3219      @FluentSetter
3220      public Builder callHandler(Class<? extends RestCallHandler> value) {
3221         callHandler().type(value);
3222         return this;
3223      }
3224
3225      //------------------------------------------------------------------------------------------------------------------
3226      // errorCodes
3227      //------------------------------------------------------------------------------------------------------------------
3228
3229      /**
3230       * Errors codes predicate.
3231       *
3232       * <p>
3233       * Defines a predicate to test for error codes.
3234       *
3235       * <h5 class='section'>Example:</h5>
3236       * <p class='bjava'>
3237       *    <jc>// Create a client that considers any 300+ responses to be errors.</jc>
3238       *    RestClient <jv>client</jv> = RestClient
3239       *       .<jsm>create</jsm>()
3240       *       .errorCodes(<jv>x</jv> -&gt; <jv>x</jv>&gt;=300)
3241       *       .build();
3242       * </p>
3243       *
3244       * @param value
3245       *    The new value for this setting.
3246       *    <br>The default value is <code>x -&gt; x &gt;= 400</code>.
3247       * @return This object.
3248       */
3249      @FluentSetter
3250      public Builder errorCodes(Predicate<Integer> value) {
3251         errorCodes = assertArgNotNull("value", value);
3252         return this;
3253      }
3254
3255      //------------------------------------------------------------------------------------------------------------------
3256      // Logging.
3257      //------------------------------------------------------------------------------------------------------------------
3258
3259      /**
3260       * Logger.
3261       *
3262       * <p>
3263       * Specifies the logger to use for logging.
3264       *
3265       * <p>
3266       * If not specified, uses the following logger:
3267       * <p class='bjava'>
3268       *    Logger.<jsm>getLogger</jsm>(RestClient.<jk>class</jk>.getName());
3269       * </p>
3270       *
3271       * <h5 class='section'>Example:</h5>
3272       * <p class='bjava'>
3273       *    <jc>// Construct a client that logs messages to a special logger.</jc>
3274       *    RestClient <jv>client</jv> = RestClient
3275       *       .<jsm>create</jsm>()
3276       *       .logger(Logger.<jsm>getLogger</jsm>(<js>"MyLogger"</js>))  <jc>// Log to MyLogger logger.</jc>
3277       *       .logToConsole()  <jc>// Also log to console.</jc>
3278       *       .logRequests(<jsf>FULL</jsf>, <jsf>WARNING</jsf>)  <jc>// Log requests with full detail at WARNING level.</jc>
3279       *       .build();
3280       * </p>
3281       *
3282       * @param value The logger to use for logging.
3283       * @return This object.
3284       */
3285      @FluentSetter
3286      public Builder logger(Logger value) {
3287         logger = value;
3288         return this;
3289      }
3290
3291      /**
3292       * Log to console.
3293       *
3294       * <p>
3295       * Specifies to log messages to the console.
3296       *
3297       * <h5 class='section'>Example:</h5>
3298       * <p class='bjava'>
3299       *    <jc>// Construct a client that logs messages to a special logger.</jc>
3300       *    RestClient <jv>client</jv> = RestClient
3301       *       .<jsm>create</jsm>()
3302       *       .logToConsole()
3303       *       .logRequests(<jsf>FULL</jsf>, <jsf>INFO</jsf>)  <jc>// Level is ignored when logging to console.</jc>
3304       *       .build();
3305       * </p>
3306       *
3307       * @return This object.
3308       */
3309      @FluentSetter
3310      public Builder logToConsole() {
3311         logToConsole = true;
3312         return this;
3313      }
3314
3315      /**
3316       * Log requests.
3317       *
3318       * <p>
3319       * Causes requests/responses to be logged at the specified log level at the end of the request.
3320       *
3321       * <p>
3322       * <jsf>SIMPLE</jsf> detail produces a log message like the following:
3323       * <p class='bconsole'>
3324       *    POST http://localhost:10000/testUrl, HTTP/1.1 200 OK
3325       * </p>
3326       *
3327       * <p>
3328       * <jsf>FULL</jsf> detail produces a log message like the following:
3329       * <p class='bconsole'>
3330       *    === HTTP Call (outgoing) =======================================================
3331       *    === REQUEST ===
3332       *    POST http://localhost:10000/testUrl
3333       *    ---request headers---
3334       *       Debug: true
3335       *       No-Trace: true
3336       *       Accept: application/json
3337       *    ---request entity---
3338       *       Content-Type: application/json
3339       *    ---request content---
3340       *    {"foo":"bar","baz":123}
3341       *    === RESPONSE ===
3342       *    HTTP/1.1 200 OK
3343       *    ---response headers---
3344       *       Content-Type: application/json;charset=utf-8
3345       *       Content-Length: 21
3346       *       Server: Jetty(8.1.0.v20120127)
3347       *    ---response content---
3348       *    {"message":"OK then"}
3349       *    === END ========================================================================
3350       * </p>
3351       *
3352       * <p>
3353       * By default, the message is logged to the default logger.  It can be logged to a different logger via the
3354       * {@link #logger(Logger)} method or logged to the console using the
3355       * {@link #logToConsole()} method.
3356       *
3357       * @param detail The detail level of logging.
3358       * @param level The log level.
3359       * @param test A predicate to use per-request to see if the request should be logged.  If <jk>null</jk>, always logs.
3360       * @return This object.
3361       */
3362      @FluentSetter
3363      public Builder logRequests(DetailLevel detail, Level level, BiPredicate<RestRequest,RestResponse> test) {
3364         logRequests = detail;
3365         logRequestsLevel = level;
3366         logRequestsPredicate = test;
3367         return this;
3368      }
3369
3370      //------------------------------------------------------------------------------------------------------------------
3371      // HttpClientConnectionManager methods.
3372      //------------------------------------------------------------------------------------------------------------------
3373
3374      /**
3375       * Creates the {@link HttpClientConnectionManager} returned by {@link #createConnectionManager()}.
3376       *
3377       * <p>
3378       * Subclasses can override this method to provide their own connection manager.
3379       *
3380       * <p>
3381       * The default implementation returns an instance of a {@link PoolingHttpClientConnectionManager} if {@link #pooled()}
3382       * was called or {@link BasicHttpClientConnectionManager} if not..
3383       *
3384       * <h5 class='section'>Example:</h5>
3385       * <p class='bjava'>
3386       *    <jc>// A Builder that provides it's own customized HttpClientConnectionManager.</jc>
3387       *    <jk>public class</jk> MyBuilder <jk>extends</jk> Builder {
3388       *       <ja>@Override</ja>
3389       *       <jk>protected</jk> HttpClientConnectionManager createConnectionManager() {
3390       *          <jk>return new</jk> PoolingHttpClientConnectionManager();
3391       *       }
3392       *    }
3393       *
3394       *    <jc>// Instantiate.</jc>
3395       *    RestClient <jv>client</jv> = <jk>new</jk> MyBuilder().build();
3396       * </p>
3397       *
3398       * @return The HTTP client builder to use to create the HTTP client.
3399       */
3400      protected HttpClientConnectionManager createConnectionManager() {
3401         return (pooled ? new PoolingHttpClientConnectionManager() : new BasicHttpClientConnectionManager());
3402      }
3403
3404      /**
3405       * When called, the {@link #createConnectionManager()} method will return a {@link PoolingHttpClientConnectionManager}
3406       * instead of a {@link BasicHttpClientConnectionManager}.
3407       *
3408       * <h5 class='section'>Example:</h5>
3409       * <p class='bjava'>
3410       *    <jc>// Construct a client that uses pooled connections.</jc>
3411       *    RestClient <jv>client</jv> = RestClient
3412       *       .<jsm>create</jsm>()
3413       *       .pooled()
3414       *       .build();
3415       * </p>
3416       *
3417       * @return This object.
3418       */
3419      @FluentSetter
3420      public Builder pooled() {
3421         this.pooled = true;
3422         return this;
3423      }
3424
3425      /**
3426       * Assigns {@link HttpClientConnectionManager} instance.
3427       *
3428       * @param value New property value.
3429       * @return This object.
3430       * @see HttpClientBuilder#setConnectionManager(HttpClientConnectionManager)
3431       */
3432      @FluentSetter
3433      public Builder connectionManager(HttpClientConnectionManager value) {
3434         connectionManager = value;
3435         httpClientBuilder().setConnectionManager(value);
3436         return this;
3437      }
3438
3439      /**
3440       * Defines the connection manager is to be shared by multiple client instances.
3441       *
3442       * <h5 class='section'>Notes:</h5><ul>
3443       *    <li class='note'>If the connection manager is shared its life-cycle is expected to be managed by the caller and it will not be shut down if the client is closed.
3444       * </ul>
3445       *
3446       * @param shared New property value.
3447       * @return This object.
3448       * @see HttpClientBuilder#setConnectionManagerShared(boolean)
3449       */
3450      @FluentSetter
3451      public Builder connectionManagerShared(boolean shared) {
3452         httpClientBuilder().setConnectionManagerShared(shared);
3453         return this;
3454      }
3455
3456      /**
3457       * Set up this client to use BASIC auth.
3458       *
3459       * <h5 class='section'>Example:</h5>
3460       * <p class='bjava'>
3461       *    <jc>// Construct a client that uses BASIC authentication.</jc>
3462       *    RestClient <jv>client</jv> = RestClient
3463       *       .<jsm>create</jsm>()
3464       *       .basicAuth(<js>"http://localhost"</js>, 80, <js>"me"</js>, <js>"mypassword"</js>)
3465       *       .build();
3466       * </p>
3467       *
3468       * @param host The auth scope hostname.
3469       * @param port The auth scope port.
3470       * @param user The username.
3471       * @param pw The password.
3472       * @return This object.
3473       */
3474      @FluentSetter
3475      public Builder basicAuth(String host, int port, String user, String pw) {
3476         AuthScope scope = new AuthScope(host, port);
3477         Credentials up = new UsernamePasswordCredentials(user, pw);
3478         CredentialsProvider p = new BasicCredentialsProvider();
3479         p.setCredentials(scope, up);
3480         defaultCredentialsProvider(p);
3481         return this;
3482      }
3483
3484      //-----------------------------------------------------------------------------------------------------------------
3485      // Properties
3486      //-----------------------------------------------------------------------------------------------------------------
3487
3488      /**
3489       * Console print stream
3490       *
3491       * <p>
3492       * Allows you to redirect the console output to a different print stream.
3493       *
3494       * @param value
3495       *    The new value for this setting.
3496       * @return This object.
3497       */
3498      @FluentSetter
3499      public Builder console(PrintStream value) {
3500         console = value;
3501         return this;
3502      }
3503
3504      /**
3505       * <i><l>RestClient</l> configuration property:&emsp;</i>  Executor service.
3506       *
3507       * <p>
3508       * Defines the executor service to use when calling future methods on the {@link RestRequest} class.
3509       *
3510       * <p>
3511       * This executor service is used to create {@link Future} objects on the following methods:
3512       * <ul>
3513       *    <li class='jm'>{@link RestRequest#runFuture()}
3514       *    <li class='jm'>{@link RestRequest#completeFuture()}
3515       *    <li class='jm'>{@link ResponseContent#asFuture(Class)} (and similar methods)
3516       * </ul>
3517       *
3518       * <p>
3519       * The default executor service is a single-threaded {@link ThreadPoolExecutor} with a 30 second timeout
3520       * and a queue size of 10.
3521       *
3522       * <h5 class='section'>Example:</h5>
3523       * <p class='bjava'>
3524       *    <jc>// Create a client with a customized executor service.</jc>
3525       *    RestClient <jv>client</jv> = RestClient
3526       *       .<jsm>create</jsm>()
3527       *       .executorService(<jk>new</jk> ThreadPoolExecutor(1, 1, 30, TimeUnit.<jsf>SECONDS</jsf>, <jk>new</jk> ArrayBlockingQueue&lt;Runnable&gt;(10)), <jk>true</jk>)
3528       *       .build();
3529       *
3530       *    <jc>// Use it to asynchronously run a request.</jc>
3531       *    Future&lt;RestResponse&gt; <jv>responseFuture</jv> = <jv>client</jv>.get(<jsf>URI</jsf>).runFuture();
3532       *
3533       *    <jc>// Do some other stuff.</jc>
3534       *
3535       *    <jc>// Now read the response.</jc>
3536       *    String <jv>body</jv> = <jv>responseFuture</jv>.get().getContent().asString();
3537       *
3538       *    <jc>// Use it to asynchronously retrieve a response.</jc>
3539       *    Future&lt;MyBean&gt; <jv>myBeanFuture</jv> = <jv>client</jv>
3540       *       .get(<jsf>URI</jsf>)
3541       *       .run()
3542       *       .getContent().asFuture(MyBean.<jk>class</jk>);
3543       *
3544       *    <jc>// Do some other stuff.</jc>
3545       *
3546       *    <jc>// Now read the response.</jc>
3547       *    MyBean <jv>bean</jv> = <jv>myBeanFuture</jv>.get();
3548       * </p>
3549       *
3550       * @param executorService The executor service.
3551       * @param shutdownOnClose Call {@link ExecutorService#shutdown()} when {@link RestClient#close()} is called.
3552       * @return This object.
3553       */
3554      @FluentSetter
3555      public Builder executorService(ExecutorService executorService, boolean shutdownOnClose) {
3556         this.executorService = executorService;
3557         this.executorServiceShutdownOnClose = shutdownOnClose;
3558         return this;
3559      }
3560
3561      /**
3562       * <i><l>RestClient</l> configuration property:&emsp;</i>  Keep HttpClient open.
3563       *
3564       * <p>
3565       * Don't close this client when the {@link RestClient#close()} method is called.
3566       *
3567       * <h5 class='section'>Example:</h5>
3568       * <p class='bjava'>
3569       *    <jc>// Create a client with a customized client and don't close the client  service.</jc>
3570       *    RestClient <jv>client</jv> = RestClient
3571       *       .<jsm>create</jsm>()
3572       *       .httpClient(<jv>myHttpClient</jv>)
3573       *       .keepHttpClientOpen()
3574       *       .build();
3575       *
3576       *    <jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
3577       * </p>
3578       *
3579       * @return This object.
3580       */
3581      @FluentSetter
3582      public Builder keepHttpClientOpen() {
3583         keepHttpClientOpen = true;
3584         return this;
3585      }
3586
3587      /**
3588       * Ignore errors.
3589       *
3590       * <p>
3591       * When enabled, HTTP error response codes (e.g. <l>&gt;=400</l>) will not cause a {@link RestCallException} to
3592       * be thrown.
3593       * <p>
3594       * Note that this is equivalent to <c>builder.errorCodes(x -&gt; <jk>false</jk>);</c>
3595       *
3596       * <h5 class='section'>Example:</h5>
3597       * <p class='bjava'>
3598       *    <jc>// Create a client that doesn't throws a RestCallException when a 500 error occurs.</jc>
3599       *    RestClient
3600       *       .<jsm>create</jsm>()
3601       *       .ignoreErrors()
3602       *       .build()
3603       *       .get(<js>"/error"</js>)  <jc>// Throws a 500 error</jc>
3604       *       .run()
3605       *       .assertStatus().is(500);
3606       * </p>
3607       *
3608       * @return This object.
3609       */
3610      @FluentSetter
3611      public Builder ignoreErrors() {
3612         ignoreErrors = true;
3613         return this;
3614      }
3615
3616      /**
3617       * <i><l>RestClient</l> configuration property:&emsp;</i>  Call interceptors.
3618       *
3619       * <p>
3620       * Adds an interceptor that can be called to hook into specified events in the lifecycle of a single request.
3621       *
3622       * <h5 class='section'>Example:</h5>
3623       * <p class='bjava'>
3624       *   <jc>// Customized interceptor (note you can also extend from BasicRestCallInterceptor as well.</jc>
3625       *    <jk>public class</jk> MyRestCallInterceptor <jk>implements</jk> RestCallInterceptor {
3626       *
3627       *       <ja>@Override</ja>
3628       *       <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
3629       *       <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
3630       *       // set on the request from the client.</jc>
3631       *    }
3632       *
3633       *    <ja>@Override</ja>
3634       *    <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3635       *       <jc>// Intercept immediately after an HTTP response has been received.</jc>
3636       *    }
3637       *
3638       *    <ja>@Override</ja>
3639       *    <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3640       *          <jc>// Intercept when the response body is consumed.</jc>
3641       *       }
3642       *    }
3643       *
3644       *    <jc>// Create a client with a customized interceptor.</jc>
3645       *    RestClient <jv>client</jv> = RestClient
3646       *       .<jsm>create</jsm>()
3647       *       .interceptors(MyRestCallInterceptor.<jk>class</jk>)
3648       *       .build();
3649       * </p>
3650       *
3651       * <h5 class='section'>Notes:</h5><ul>
3652       *    <li class='note'>The {@link RestClient#onCallInit(RestRequest)}, {@link RestClient#onCallConnect(RestRequest,RestResponse)}, and
3653       * {@link RestClient#onCallClose(RestRequest,RestResponse)} methods can also be overridden to produce the same results.
3654       * </ul>
3655       *
3656       * @param values
3657       *    The values to add to this setting.
3658       *    <br>Can be implementations of any of the following:
3659       *    <ul>
3660       *       <li class='jic'>{@link RestCallInterceptor}
3661       *       <li class='jic'>{@link HttpRequestInterceptor}
3662       *       <li class='jic'>{@link HttpResponseInterceptor}
3663       *    </ul>
3664       * @return This object.
3665       * @throws Exception If one or more interceptors could not be created.
3666       */
3667      @FluentSetter
3668      public Builder interceptors(Class<?>...values) throws Exception {
3669         for (Class<?> c : values) {
3670            ClassInfo ci = ClassInfo.of(c);
3671            if (ci != null) {
3672               if (ci.isChildOfAny(RestCallInterceptor.class, HttpRequestInterceptor.class, HttpResponseInterceptor.class))
3673                  interceptors(ci.newInstance());
3674               else
3675                  throw new ConfigException("Invalid class of type ''{0}'' passed to interceptors().", ci.getName());
3676            }
3677         }
3678         return this;
3679      }
3680
3681      /**
3682       * Call interceptors.
3683       *
3684       * <p>
3685       * Adds an interceptor that gets called immediately after a connection is made.
3686       *
3687       * <h5 class='section'>Example:</h5>
3688       * <p class='bjava'>
3689       *    <jc>// Create a client with a customized interceptor.</jc>
3690       *    RestClient <jv>client</jv> = RestClient
3691       *       .<jsm>create</jsm>()
3692       *       .interceptors(
3693       *          <jk>new</jk> RestCallInterceptor() {
3694       *
3695       *             <ja>@Override</ja>
3696       *             <jk>public void</jk> onInit(RestRequest <jv>req</jv>) <jk>throws</jk> Exception {
3697       *             <jc>// Intercept immediately after RestRequest object is created and all headers/query/form-data has been
3698       *             // set on the request from the client.</jc>
3699       *          }
3700       *
3701       *          <ja>@Override</ja>
3702       *          <jk>public void</jk> onConnect(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3703       *             <jc>// Intercept immediately after an HTTP response has been received.</jc>
3704       *          }
3705       *
3706       *          <ja>@Override</ja>
3707       *          <jk>public void</jk> onClose(RestRequest <jv>req</jv>, RestResponse <jv>res</jv>) <jk>throws</jk> Exception {
3708       *                <jc>// Intercept when the response body is consumed.</jc>
3709       *             }
3710       *          }
3711       *       )
3712       *       .build();
3713       * </p>
3714       *
3715       * <h5 class='section'>Notes:</h5><ul>
3716       *    <li class='note'>The {@link RestClient#onCallInit(RestRequest)}, {@link RestClient#onCallConnect(RestRequest,RestResponse)}, and
3717       * {@link RestClient#onCallClose(RestRequest,RestResponse)} methods can also be overridden to produce the same results.
3718       * </ul>
3719       *
3720       * @param value
3721       *    The values to add to this setting.
3722       *    <br>Can be implementations of any of the following:
3723       *    <ul>
3724       *       <li class='jic'>{@link RestCallInterceptor}
3725       *       <li class='jic'>{@link HttpRequestInterceptor}
3726       *       <li class='jic'>{@link HttpResponseInterceptor}
3727       *    </ul>
3728       * @return This object.
3729       */
3730      @FluentSetter
3731      public Builder interceptors(Object...value) {
3732         List<RestCallInterceptor> l = list();
3733         for (Object o : value) {
3734            ClassInfo ci = ClassInfo.of(o);
3735            if (ci != null) {
3736               if (! ci.isChildOfAny(HttpRequestInterceptor.class, HttpResponseInterceptor.class, RestCallInterceptor.class))
3737                  throw new ConfigException("Invalid object of type ''{0}'' passed to interceptors().", ci.getName());
3738               if (o instanceof HttpRequestInterceptor)
3739                  addInterceptorLast((HttpRequestInterceptor)o);
3740               if (o instanceof HttpResponseInterceptor)
3741                  addInterceptorLast((HttpResponseInterceptor)o);
3742               if (o instanceof RestCallInterceptor)
3743                  l.add((RestCallInterceptor)o);
3744            }
3745         }
3746         if (interceptors == null)
3747            interceptors = l;
3748         else
3749            interceptors.addAll(0, l);
3750         return this;
3751      }
3752
3753      /**
3754       * <i><l>RestClient</l> configuration property:&emsp;</i>  Enable leak detection.
3755       *
3756       * <p>
3757       * Enable client and request/response leak detection.
3758       *
3759       * <p>
3760       * Causes messages to be logged to the console if clients or request/response objects are not properly closed
3761       * when the <c>finalize</c> methods are invoked.
3762       *
3763       * <p>
3764       * Automatically enabled with {@link org.apache.juneau.Context.Builder#debug()}.
3765       *
3766       * <h5 class='section'>Example:</h5>
3767       * <p class='bjava'>
3768       *    <jc>// Create a client that logs a message if </jc>
3769       *    RestClient <jv>client</jv> = RestClient
3770       *       .<jsm>create</jsm>()
3771       *       .detectLeaks()
3772       *       .logToConsole()  <jc>// Also log the error message to System.err</jc>
3773       *       .build();
3774       *
3775       *    <jv>client</jv>.closeQuietly();  <jc>// Customized HttpClient won't be closed.</jc>
3776       * </p>
3777       *
3778       * @return This object.
3779       */
3780      @FluentSetter
3781      public Builder detectLeaks() {
3782         detectLeaks = true;
3783         return this;
3784      }
3785
3786      /**
3787       * <i><l>RestClient</l> configuration property:&emsp;</i>  Marshaller
3788       *
3789       * <p>
3790       * Shortcut for specifying the serializers and parsers
3791       * using the serializer and parser defined in a marshaller.
3792       *
3793       * <h5 class='section'>Notes:</h5><ul>
3794       *    <li class='note'>When using this method that takes in a pre-instantiated serializers and parsers, the serializer property setters (e.g. {@link #sortCollections()}),
3795       *    parser property setters (e.g. {@link #strict()}), or bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class have no effect.
3796       * </ul>
3797       *
3798       * <h5 class='section'>Example:</h5>
3799       * <p class='bjava'>
3800       *    <jc>// Create a client that uses Simplified-JSON transport using an existing marshaller.</jc>
3801       *    RestClient <jv>client</jv> = RestClient
3802       *       .<jsm>create</jsm>()
3803       *       .marshaller(Json5.<jsf>DEFAULT_READABLE</jsf>)
3804       *       .build();
3805       * </p>
3806       *
3807       * @param value The values to add to this setting.
3808       * @return This object.
3809       */
3810      @FluentSetter
3811      public Builder marshaller(Marshaller value) {
3812         if (value != null)
3813            serializer(value.getSerializer()).parser(value.getParser());
3814         return this;
3815      }
3816
3817      /**
3818       * <i><l>RestClient</l> configuration property:&emsp;</i>  Marshalls
3819       *
3820       * <p>
3821       * Shortcut for specifying the serializers and parsers
3822       * using the serializer and parser defined in a marshaller.
3823       *
3824       * <h5 class='section'>Notes:</h5><ul>
3825       *    <li class='note'>When using this method that takes in a pre-instantiated serializers and parsers, the serializer property setters (e.g. {@link #sortCollections()}),
3826       *    parser property setters (e.g. {@link #strict()}), or bean context property setters (e.g. {@link #swaps(Class...)}) defined on this builder class have no effect.
3827       * </ul>
3828       *
3829       * <h5 class='section'>Example:</h5>
3830       * <p class='bjava'>
3831       *    <jc>// Create a client that uses JSON and XML transport using existing marshalls.</jc>
3832       *    RestClient <jv>client</jv> = RestClient
3833       *       .<jsm>create</jsm>()
3834       *       .marshaller(Json.<jsf>DEFAULT_READABLE</jsf>, Xml.<jsf>DEFAULT_READABLE</jsf>)
3835       *       .build();
3836       * </p>
3837       *
3838       * @param value The values to add to this setting.
3839       * @return This object.
3840       */
3841      @FluentSetter
3842      public Builder marshallers(Marshaller...value) {
3843         for (Marshaller m : value)
3844            if (m != null)
3845               serializer(m.getSerializer()).parser(m.getParser());
3846         return this;
3847      }
3848
3849      /**
3850       * <i><l>RestClient</l> configuration property:&emsp;</i>  Root URI.
3851       *
3852       * <p>
3853       * When set, relative URI strings passed in through the various rest call methods (e.g. {@link RestClient#get(Object)}
3854       * will be prefixed with the specified root.
3855       * <br>This root URI is ignored on those methods if you pass in a {@link URL}, {@link URI}, or an absolute URI string.
3856       *
3857       * <h5 class='section'>Example:</h5>
3858       * <p class='bjava'>
3859       *    <jc>// Create a client that uses UON format by default for HTTP parts.</jc>
3860       *    RestClient <jv>client</jv> = RestClient
3861       *       .<jsm>create</jsm>()
3862       *       .rootUrl(<js>"http://localhost:10000/foo"</js>)
3863       *       .build();
3864       *
3865       *    Bar <jv>bar</jv> = <jv>client</jv>
3866       *       .get(<js>"/bar"</js>)  <jc>// Relative to http://localhost:10000/foo</jc>
3867       *       .run()
3868       *       .getContent().as(Bar.<jk>class</jk>);
3869       * </p>
3870       *
3871       * @param value
3872       *    The root URI to prefix to relative URI strings.
3873       *    <br>Trailing slashes are trimmed.
3874       *    <br>Usually a <c>String</c> but you can also pass in <c>URI</c> and <c>URL</c> objects as well.
3875       * @return This object.
3876       */
3877      @FluentSetter
3878      public Builder rootUrl(Object value) {
3879         String s = stringify(value);
3880         if (! isEmpty(s))
3881            s = s.replaceAll("\\/$", "");
3882         if (isEmpty(s))
3883            rootUrl = null;
3884         else if (s.indexOf("://") == -1)
3885            throw new BasicRuntimeException("Invalid rootUrl value: ''{0}''.  Must be a valid absolute URL.", value);
3886         else
3887            rootUrl = s;
3888         return this;
3889      }
3890
3891      /**
3892       * Returns the root URI defined for this client.
3893       *
3894       * <p>
3895       * Returns <jk>null</jk> in leu of an empty string.
3896       * Trailing slashes are trimmed.
3897       *
3898       * @return The root URI defined for this client.
3899       */
3900      public String getRootUri() {
3901         return rootUrl;
3902      }
3903
3904      /**
3905       * Skip empty form data.
3906       *
3907       * <p>
3908       * When enabled, form data consisting of empty strings will be skipped on requests.
3909       * Note that <jk>null</jk> values are already skipped.
3910       *
3911       * <p>
3912       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3913       *
3914       * @param value
3915       *    The new value for this setting.
3916       *    <br>The default is <jk>false</jk>.
3917       * @return This object.
3918       */
3919      @FluentSetter
3920      public Builder skipEmptyFormData(boolean value) {
3921         skipEmptyFormData = true;
3922         return this;
3923      }
3924
3925      /**
3926       * Skip empty form data.
3927       *
3928       * <p>
3929       * When enabled, form data consisting of empty strings will be skipped on requests.
3930       * Note that <jk>null</jk> values are already skipped.
3931       *
3932       * <p>
3933       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3934       *
3935       * @return This object.
3936       */
3937      @FluentSetter
3938      public Builder skipEmptyFormData() {
3939         return skipEmptyFormData(true);
3940      }
3941
3942      /**
3943       * Skip empty header data.
3944       *
3945       * <p>
3946       * When enabled, headers consisting of empty strings will be skipped on requests.
3947       * Note that <jk>null</jk> values are already skipped.
3948       *
3949       * <p>
3950       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3951       *
3952       * @param value
3953       *    The new value for this setting.
3954       *    <br>The default is <jk>false</jk>.
3955       * @return This object.
3956       */
3957      @FluentSetter
3958      public Builder skipEmptyHeaderData(boolean value) {
3959         skipEmptyHeaderData = true;
3960         return this;
3961      }
3962
3963      /**
3964       * Skip empty header data.
3965       *
3966       * <p>
3967       * When enabled, headers consisting of empty strings will be skipped on requests.
3968       * Note that <jk>null</jk> values are already skipped.
3969       *
3970       * <p>
3971       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3972       *
3973       * @return This object.
3974       */
3975      @FluentSetter
3976      public Builder skipEmptyHeaderData() {
3977         return skipEmptyHeaderData(true);
3978      }
3979
3980      /**
3981       * Skip empty query data.
3982       *
3983       * <p>
3984       * When enabled, query parameters consisting of empty strings will be skipped on requests.
3985       * Note that <jk>null</jk> values are already skipped.
3986       *
3987       * <p>
3988       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
3989       *
3990       * @param value
3991       *    The new value for this setting.
3992       *    <br>The default is <jk>false</jk>.
3993       * @return This object.
3994       */
3995      @FluentSetter
3996      public Builder skipEmptyQueryData(boolean value) {
3997         skipEmptyQueryData = true;
3998         return this;
3999      }
4000
4001      /**
4002       * Skip empty query data.
4003       *
4004       * <p>
4005       * When enabled, query parameters consisting of empty strings will be skipped on requests.
4006       * Note that <jk>null</jk> values are already skipped.
4007       *
4008       * <p>
4009       * The {@link Schema#skipIfEmpty()} annotation overrides this setting.
4010       *
4011       * @return This object.
4012       */
4013      @FluentSetter
4014      public Builder skipEmptyQueryData() {
4015         return skipEmptyQueryData(true);
4016      }
4017
4018      //-----------------------------------------------------------------------------------------------------------------
4019      // BeanTraverse Properties
4020      //-----------------------------------------------------------------------------------------------------------------
4021
4022      /**
4023       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Automatically detect POJO recursions.
4024       *
4025       * <p>
4026       * When enabled, specifies that recursions should be checked for during traversal.
4027       *
4028       * <p>
4029       * Recursions can occur when traversing models that aren't true trees but rather contain loops.
4030       * <br>In general, unchecked recursions cause stack-overflow-errors.
4031       * <br>These show up as {@link BeanRecursionException BeanRecursionException} with the message <js>"Depth too deep.  Stack overflow occurred."</js>.
4032       *
4033       * <h5 class='section'>Notes:</h5><ul>
4034       *    <li class='note'>
4035       *       Checking for recursion can cause a small performance penalty.
4036       * </ul>
4037       *
4038       * <h5 class='section'>Example:</h5>
4039       * <p class='bjava'>
4040       *    <jc>// Create a JSON client that automatically checks for recursions.</jc>
4041       *    RestClient <jv>client</jv> = RestClient
4042       *       .<jsm>create</jsm>()
4043       *       .json()
4044       *       .detectRecursions()
4045       *       .build();
4046       *
4047       *    <jc>// Create a POJO model with a recursive loop.</jc>
4048       *    <jk>public class</jk> A {
4049       *       <jk>public</jk> Object <jf>f</jf>;
4050       *    }
4051       *    A <jv>a</jv> = <jk>new</jk> A();
4052       *    <jv>a</jv>.<jf>f</jf> = <jv>a</jv>;
4053       *
4054       * <jk>try</jk> {
4055       *       <jc>// Throws a RestCallException with an inner SerializeException and not a StackOverflowError</jc>
4056       *       <jv>client</jv>
4057       *          .post(<js>"http://localhost:10000/foo"</js>, <jv>a</jv>)
4058       *          .run();
4059       * } <jk>catch</jk> (RestCallException <jv>e</jv>} {
4060       *    <jc>// Handle exception.</jc>
4061       * }
4062       * </p>
4063       *
4064       * <h5 class='section'>See Also:</h5><ul>
4065       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#detectRecursions()}
4066       * </ul>
4067       *
4068       * @return This object.
4069       */
4070      @FluentSetter
4071      public Builder detectRecursions() {
4072         serializers().forEach(x -> x.detectRecursions());
4073         return this;
4074      }
4075
4076      /**
4077       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Ignore recursion errors.
4078       *
4079       * <p>
4080       * When enabled, when we encounter the same object when traversing a tree, we set the value to <jk>null</jk>.
4081       *
4082       * <p>
4083       * For example, if a model contains the links A-&gt;B-&gt;C-&gt;A, then the JSON generated will look like
4084       *    the following when <jsf>BEANTRAVERSE_ignoreRecursions</jsf> is <jk>true</jk>...
4085       *
4086       * <p class='bjson'>
4087       *    {A:{B:{C:<jk>null</jk>}}}
4088       * </p>
4089       *
4090       * <h5 class='section'>Notes:</h5><ul>
4091       *    <li class='note'>
4092       *       Checking for recursion can cause a small performance penalty.
4093       * </ul>
4094       *
4095       * <h5 class='section'>Example:</h5>
4096       * <p class='bjava'>
4097       *    <jc>// Create a JSON client that ignores recursions.</jc>
4098       *    RestClient <jv>client</jv> = RestClient
4099       *       .<jsm>create</jsm>()
4100       *       .json()
4101       *       .ignoreRecursions()
4102       *       .build();
4103       *
4104       *    <jc>// Create a POJO model with a recursive loop.</jc>
4105       *    <jk>public class</jk> A {
4106       *       <jk>public</jk> Object <jf>f</jf>;
4107       *    }
4108       *    A <jv>a</jv> = <jk>new</jk> A();
4109       *    <jv>a</jv>.<jf>f</jf> = <jv>a</jv>;
4110       *
4111       *    <jc>// Produces request body "{f:null}"</jc>
4112       *    <jv>client</jv>
4113       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>a</jv>)
4114       *       .run();
4115       * </p>
4116       *
4117       * <h5 class='section'>See Also:</h5><ul>
4118       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#ignoreRecursions()}
4119       * </ul>
4120       *
4121       * @return This object.
4122       */
4123      @FluentSetter
4124      public Builder ignoreRecursions() {
4125         serializers().forEach(x -> x.ignoreRecursions());
4126         return this;
4127      }
4128
4129      /**
4130       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Initial depth.
4131       *
4132       * <p>
4133       * The initial indentation level at the root.
4134       *
4135       * <p>
4136       * Useful when constructing document fragments that need to be indented at a certain level when whitespace is enabled.
4137       *
4138       * <h5 class='section'>Example:</h5>
4139       * <p class='bjava'>
4140       *    <jc>// Create a REST client with JSON serializer with whitespace enabled and an initial depth of 2.</jc>
4141       *    RestClient <jv>client</jv> = RestClient
4142       *       .<jsm>create</jsm>()
4143       *       .json()
4144       *       .ws()
4145       *       .initialDepth(2)
4146       *       .build();
4147       *
4148       *    <jc>// Our bean to serialize.</jc>
4149       *    <jk>public class</jk> MyBean {
4150       *       <jk>public</jk> String <jf>foo</jf> = <jk>null</jk>;
4151       *    }
4152       *
4153       *    <jc>// Produces request body "\t\t{\n\t\t\t'foo':'bar'\n\t\t}\n"</jc>
4154       *    <jv>client</jv>
4155       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4156       *       .run();
4157       * </p>
4158       *
4159       * <h5 class='section'>See Also:</h5><ul>
4160       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#initialDepth(int)}
4161       * </ul>
4162       *
4163       * @param value
4164       *    The new value for this property.
4165       *    <br>The default is <c>0</c>.
4166       * @return This object.
4167       */
4168      @FluentSetter
4169      public Builder initialDepth(int value) {
4170         serializers().forEach(x -> x.initialDepth(value));
4171         return this;
4172      }
4173
4174      /**
4175       * <i><l>BeanTraverse</l> configuration property:&emsp;</i>  Max serialization depth.
4176       *
4177       * <p>
4178       * When enabled, abort traversal if specified depth is reached in the POJO tree.
4179       *
4180       * <p>
4181       * If this depth is exceeded, an exception is thrown.
4182       *
4183       * <p>
4184       * This prevents stack overflows from occurring when trying to traverse models with recursive references.
4185       *
4186       * <h5 class='section'>Example:</h5>
4187       * <p class='bjava'>
4188       *    <jc>// Create a REST client with JSON serializer that throws an exception if the depth reaches greater than 20.</jc>
4189       *    RestClient <jv>client</jv> = RestClient
4190       *       .<jsm>create</jsm>()
4191       *       .json()
4192       *       .maxDepth(20)
4193       *       .build();
4194       * </p>
4195       *
4196       * <h5 class='section'>See Also:</h5><ul>
4197       *    <li class='jm'>{@link org.apache.juneau.BeanTraverseContext.Builder#maxDepth(int)}
4198       * </ul>
4199       *
4200       * @param value
4201       *    The new value for this property.
4202       *    <br>The default is <c>100</c>.
4203       * @return This object.
4204       */
4205      @FluentSetter
4206      public Builder maxDepth(int value) {
4207         serializers().forEach(x -> x.maxDepth(value));
4208         return this;
4209      }
4210
4211      //-----------------------------------------------------------------------------------------------------------------
4212      // Serializer Properties
4213      //-----------------------------------------------------------------------------------------------------------------
4214
4215      /**
4216       * <i><l>Serializer</l> configuration property:&emsp;</i>  Add <js>"_type"</js> properties when needed.
4217       *
4218       * <p>
4219       * When enabled, <js>"_type"</js> properties will be added to beans if their type cannot be inferred
4220       * through reflection.
4221       *
4222       * <p>
4223       * This is used to recreate the correct objects during parsing if the object types cannot be inferred.
4224       * <br>For example, when serializing a <c>Map&lt;String,Object&gt;</c> field where the bean class cannot be determined from
4225       * the type of the values.
4226       *
4227       * <p>
4228       * Note the differences between the following settings:
4229       * <ul class='javatree'>
4230       *    <li class='jf'>{@link #addRootType()} - Affects whether <js>'_type'</js> is added to root node.
4231       *    <li class='jf'>{@link #addBeanTypes()} - Affects whether <js>'_type'</js> is added to any nodes.
4232       * </ul>
4233       *
4234       * <h5 class='section'>Example:</h5>
4235       * <p class='bjava'>
4236       *    <jc>// Create a JSON client that adds _type to nodes in the request body.</jc>
4237       *    RestClient <jv>client</jv> = RestClient
4238       *       .<jsm>create</jsm>()
4239       *       .json()
4240       *       .addBeanTypes()
4241       *       .build();
4242       *
4243       *    <jc>// Our map of beans to serialize.</jc>
4244       *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
4245       *    <jk>public class</jk> MyBean {
4246       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4247       *    }
4248       *
4249       *    AMap <jv>map</jv> = AMap.of(<js>"foo"</js>, <jk>new</jk> MyBean());
4250       *
4251       *    <jc>// Request body will contain:  {"foo":{"_type":"mybean","foo":"bar"}}</jc>
4252       *    <jv>client</jv>
4253       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4254       *       .run();
4255       * </p>
4256       *
4257       * <h5 class='section'>See Also:</h5><ul>
4258       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#addBeanTypes()}
4259       * </ul>
4260       *
4261       * @return This object.
4262       */
4263      @FluentSetter
4264      public Builder addBeanTypes() {
4265         serializers().forEach(x -> x.addBeanTypes());
4266         return this;
4267      }
4268
4269      /**
4270       * <i><l>Serializer</l> configuration property:&emsp;</i>  Add type attribute to root nodes.
4271       *
4272       * <p>
4273       * When enabled, <js>"_type"</js> properties will be added to top-level beans.
4274       *
4275       * <p>
4276       * When disabled, it is assumed that the parser knows the exact Java POJO type being parsed, and therefore top-level
4277       * type information that might normally be included to determine the data type will not be serialized.
4278       *
4279       * <p>
4280       * For example, when serializing a top-level POJO with a {@link Bean#typeName() @Bean(typeName)} value, a
4281       * <js>'_type'</js> attribute will only be added when this setting is enabled.
4282       *
4283       * <p>
4284       * Note the differences between the following settings:
4285       * <ul class='javatree'>
4286       *    <li class='jf'>{@link #addRootType()} - Affects whether <js>'_type'</js> is added to root node.
4287       *    <li class='jf'>{@link #addBeanTypes()} - Affects whether <js>'_type'</js> is added to any nodes.
4288       * </ul>
4289       *
4290       * <h5 class='section'>Example:</h5>
4291       * <p class='bjava'>
4292       *    <jc>// Create a JSON client that adds _type to root node.</jc>
4293       *    RestClient <jv>client</jv> = RestClient
4294       *       .<jsm>create</jsm>()
4295       *       .json()
4296       *       .addRootType()
4297       *       .build();
4298       *
4299       *    <jc>// Our bean to serialize.</jc>
4300       *    <ja>@Bean</ja>(typeName=<js>"mybean"</js>)
4301       *    <jk>public class</jk> MyBean {
4302       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4303       *    }
4304       *
4305       *    <jc>// Request body will contain:  {"_type":"mybean","foo":"bar"}</jc>
4306       *    <jv>client</jv>
4307       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4308       *       .run();
4309       * </p>
4310       *
4311       * <h5 class='section'>See Also:</h5><ul>
4312       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#addRootType()}
4313       * </ul>
4314       *
4315       * @return This object.
4316       */
4317      @FluentSetter
4318      public Builder addRootType() {
4319         serializers().forEach(x -> x.addRootType());
4320         return this;
4321      }
4322
4323      /**
4324       * <i><l>Serializer</l> configuration property:&emsp;</i>  Don't trim null bean property values.
4325       *
4326       * <p>
4327       * When enabled, null bean values will be serialized to the output.
4328       *
4329       * <h5 class='section'>Notes:</h5><ul>
4330       *    <li class='note'>Not enabling this setting will cause <c>Map</c>s with <jk>null</jk> values to be lost during parsing.
4331       * </ul>
4332       *
4333       * <h5 class='section'>Example:</h5>
4334       * <p class='bjava'>
4335       *    <jc>// Create a REST client with JSON serializer that serializes null properties.</jc>
4336       *    RestClient <jv>client</jv> = RestClient
4337       *       .<jsm>create</jsm>()
4338       *       .json()
4339       *       .keepNullProperties()
4340       *       .build();
4341       *
4342       *    <jc>// Our bean to serialize.</jc>
4343       *    <jk>public class</jk> MyBean {
4344       *       <jk>public</jk> String <jf>foo</jf> = <jk>null</jk>;
4345       *    }
4346       *
4347       *    <jc>// Request body will contain:  {foo:null}</jc>
4348       *    <jv>client</jv>
4349       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4350       *       .run();
4351       * </p>
4352       *
4353       * <h5 class='section'>See Also:</h5><ul>
4354       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#keepNullProperties()}
4355       * </ul>
4356       *
4357       * @return This object.
4358       */
4359      @FluentSetter
4360      public Builder keepNullProperties() {
4361         serializers().forEach(x -> x.keepNullProperties());
4362         return this;
4363      }
4364
4365      /**
4366       * <i><l>Serializer</l> configuration property:&emsp;</i>  Sort arrays and collections alphabetically.
4367       *
4368       * <p>
4369       * When enabled, copies and sorts the contents of arrays and collections before serializing them.
4370       *
4371       * <p>
4372       * Note that this introduces a performance penalty since it requires copying the existing collection.
4373       *
4374       * <h5 class='section'>Example:</h5>
4375       * <p class='bjava'>
4376       *    <jc>// Create a REST client with JSON serializer that sorts arrays and collections before serialization.</jc>
4377       *    RestClient <jv>client</jv> = RestClient
4378       *       .<jsm>create</jsm>()
4379       *       .json()
4380       *       .sortCollections()
4381       *       .build();
4382       *
4383       *    <jc>// An unsorted array</jc>
4384       *    String[] <jv>array</jv> = {<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>}
4385       *
4386       *    <jc>// Request body will contain:  ["bar","baz","foo"]</jc>
4387       *    <jv>client</jv>
4388       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>array</jv>)
4389       *       .run();
4390       * </p>
4391       *
4392       * <h5 class='section'>See Also:</h5><ul>
4393       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#sortCollections()}
4394       * </ul>
4395       *
4396       * @return This object.
4397       */
4398      @FluentSetter
4399      public Builder sortCollections() {
4400         serializers().forEach(x -> x.sortCollections());
4401         return this;
4402      }
4403
4404      /**
4405       * <i><l>Serializer</l> configuration property:&emsp;</i>  Sort maps alphabetically.
4406       *
4407       * <p>
4408       * When enabled, copies and sorts the contents of maps by their keys before serializing them.
4409       *
4410       * <p>
4411       * Note that this introduces a performance penalty.
4412       *
4413       * <h5 class='section'>Example:</h5>
4414       * <p class='bjava'>
4415       *    <jc>// Create a REST client with JSON serializer that sorts maps before serialization.</jc>
4416       *    RestClient <jv>client</jv> = RestClient
4417       *       .<jsm>create</jsm>()
4418       *       .json()
4419       *       .sortMaps()
4420       *       .build();
4421       *
4422       *    <jc>// An unsorted map.</jc>
4423       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(<js>"foo"</js>,1,<js>"bar"</js>,2,<js>"baz"</js>,3);
4424       *
4425       *    <jc>// Request body will contain:  {"bar":2,"baz":3,"foo":1}</jc>
4426       *    <jv>client</jv>
4427       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4428       *       .run();
4429       * </p>
4430       *
4431       * <h5 class='section'>See Also:</h5><ul>
4432       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#sortMaps()}
4433       * </ul>
4434       *
4435       * @return This object.
4436       */
4437      @FluentSetter
4438      public Builder sortMaps() {
4439         serializers().forEach(x -> x.sortMaps());
4440         return this;
4441      }
4442
4443      /**
4444       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim empty lists and arrays.
4445       *
4446       * <p>
4447       * When enabled, empty lists and arrays will not be serialized.
4448       *
4449       * <p>
4450       * Note that enabling this setting has the following effects on parsing:
4451       * <ul class='spaced-list'>
4452       *    <li>
4453       *       Map entries with empty list values will be lost.
4454       *    <li>
4455       *       Bean properties with empty list values will not be set.
4456       * </ul>
4457       *
4458       * <h5 class='section'>Example:</h5>
4459       * <p class='bjava'>
4460       *    <jc>// Create a serializer that skips empty arrays and collections.</jc>
4461       *    WriterSerializer <jv>serializer</jv> = JsonSerializer
4462       *       .<jsm>create</jsm>()
4463       *       .trimEmptyCollections()
4464       *       .build();
4465       *
4466       *    <jc>// A bean with a field with an empty array.</jc>
4467       *    <jk>public class</jk> MyBean {
4468       *       <jk>public</jk> String[] <jf>foo</jf> = {};
4469       *    }
4470       *
4471       *    <jc>// Request body will contain:  {}</jc>
4472       *    <jv>client</jv>
4473       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4474       *       .run();
4475       * </p>
4476       *
4477       * <h5 class='section'>See Also:</h5><ul>
4478       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimEmptyCollections()}
4479       * </ul>
4480       *
4481       * @return This object.
4482       */
4483      @FluentSetter
4484      public Builder trimEmptyCollections() {
4485         serializers().forEach(x -> x.trimEmptyCollections());
4486         return this;
4487      }
4488
4489      /**
4490       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim empty maps.
4491       *
4492       * <p>
4493       * When enabled, empty map values will not be serialized to the output.
4494       *
4495       * <p>
4496       * Note that enabling this setting has the following effects on parsing:
4497       * <ul class='spaced-list'>
4498       *    <li>
4499       *       Bean properties with empty map values will not be set.
4500       * </ul>
4501       *
4502       * <h5 class='section'>Example:</h5>
4503       * <p class='bjava'>
4504       *    <jc>// Create a REST client with JSON serializer that skips empty maps.</jc>
4505       *    RestClient <jv>client</jv> = RestClient
4506       *       .<jsm>create</jsm>()
4507       *       .json()
4508       *       .trimEmptyMaps()
4509       *       .build();
4510       *
4511       *    <jc>// A bean with a field with an empty map.</jc>
4512       *    <jk>public class</jk> MyBean {
4513       *       <jk>public</jk> AMap <jf>foo</jf> = AMap.<jsm>of</jsm>();
4514       *    }
4515       *
4516       *    <jc>// Request body will contain:  {}</jc>
4517       *    <jv>client</jv>
4518       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4519       *       .run();
4520       * </p>
4521       *
4522       * <h5 class='section'>See Also:</h5><ul>
4523       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimEmptyMaps()}
4524       * </ul>
4525       *
4526       * @return This object.
4527       */
4528      @FluentSetter
4529      public Builder trimEmptyMaps() {
4530         serializers().forEach(x -> x.trimEmptyMaps());
4531         return this;
4532      }
4533
4534      /**
4535       * <i><l>Serializer</l> configuration property:&emsp;</i>  Trim strings.
4536       *
4537       * <p>
4538       * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being serialized.
4539       *
4540       * <h5 class='section'>Example:</h5>
4541       * <p class='bjava'>
4542       *    <jc>// Create a REST client with JSON serializer that trims strings before serialization.</jc>
4543       *    RestClient <jv>client</jv> = RestClient
4544       *       .<jsm>create</jsm>()
4545       *       .json()
4546       *       .trimStrings()
4547       *       .build();
4548       *
4549       * <jc>// A map with space-padded keys/values</jc>
4550       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(<js>" foo "</js>, <js>" bar "</js>);
4551       *
4552       *    <jc>// Request body will contain:  {"foo":"bar"}</jc>
4553       *    <jv>client</jv>
4554       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>map</jv>)
4555       *       .run();
4556       * </p>
4557       *
4558       * <h5 class='section'>See Also:</h5><ul>
4559       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#trimStrings()}
4560       * </ul>
4561       *
4562       * @return This object.
4563       */
4564      @FluentSetter
4565      public Builder trimStringsOnWrite() {
4566         serializers().forEach(x -> x.trimStrings());
4567         return this;
4568      }
4569
4570      /**
4571       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI context bean.
4572       *
4573       * <p>
4574       * Bean used for resolution of URIs to absolute or root-relative form.
4575       *
4576       * <h5 class='section'>Example:</h5>
4577       * <p class='bjava'>
4578       *    <jc>// Our URI contextual information.</jc>
4579       *    String <jv>authority</jv> = <js>"http://localhost:10000"</js>;
4580       *    String <jv>contextRoot</jv> = <js>"/myContext"</js>;
4581       *    String <jv>servletPath</jv> = <js>"/myServlet"</js>;
4582       *    String <jv>pathInfo</jv> = <js>"/foo"</js>;
4583       *
4584       *    <jc>// Create a UriContext object.</jc>
4585       *    UriContext <jv>uriContext</jv> = <jk>new</jk> UriContext(<jv>authority</jv>, <jv>contextRoot</jv>, <jv>servletPath</jv>, <jv>pathInfo</jv>);
4586       *
4587       *    <jc>// Create a REST client with JSON serializer and associate our context.</jc>
4588       *    RestClient <jv>client</jv> = RestClient
4589       *       .<jsm>create</jsm>()
4590       *       .json()
4591       *       .uriContext(<jv>uriContext</jv>)
4592       *       .uriRelativity(<jsf>RESOURCE</jsf>)  <jc>// Assume relative paths are relative to servlet.</jc>
4593       *       .uriResolution(<jsf>ABSOLUTE</jsf>)  <jc>// Serialize URIs as absolute paths.</jc>
4594       *       .build();
4595       *
4596       *    <jc>// A relative URI</jc>
4597       *    URI <jv>uri</jv> = <jk>new</jk> URI(<js>"bar"</js>);
4598       *
4599       *    <jc>// Request body will contain:  "http://localhost:10000/myContext/myServlet/foo/bar"</jc>
4600       *    <jv>client</jv>
4601       *       .post(<js>"http://localhost:10000/foo"</js>, <jv>uri</jv>)
4602       *       .run();
4603       * </p>
4604       *
4605       * <h5 class='section'>See Also:</h5><ul>
4606       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriContext(UriContext)}
4607       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4608       * </ul>
4609       *
4610       * @param value The new value for this property.
4611       * @return This object.
4612       */
4613      @FluentSetter
4614      public Builder uriContext(UriContext value) {
4615         serializers().forEach(x -> x.uriContext(value));
4616         return this;
4617      }
4618
4619      /**
4620       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI relativity.
4621       *
4622       * <p>
4623       * Defines what relative URIs are relative to when serializing any of the following:
4624       * <ul>
4625       *    <li>{@link java.net.URI}
4626       *    <li>{@link java.net.URL}
4627       *    <li>Properties and classes annotated with {@link Uri @Uri}
4628       * </ul>
4629       *
4630       * <p>
4631       * See {@link #uriContext(UriContext)} for examples.
4632       *
4633       * <ul class='values javatree'>
4634       *    <li class='jf'>{@link org.apache.juneau.UriRelativity#RESOURCE}
4635       *       - Relative URIs should be considered relative to the servlet URI.
4636       *    <li class='jf'>{@link org.apache.juneau.UriRelativity#PATH_INFO}
4637       *       - Relative URIs should be considered relative to the request URI.
4638       * </ul>
4639       *
4640       * <h5 class='section'>See Also:</h5><ul>
4641       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriRelativity(UriRelativity)}
4642       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4643       * </ul>
4644       *
4645       * @param value
4646       *    The new value for this property.
4647       *    <br>The default is {@link UriRelativity#RESOURCE}
4648       * @return This object.
4649       */
4650      @FluentSetter
4651      public Builder uriRelativity(UriRelativity value) {
4652         serializers().forEach(x -> x.uriRelativity(value));
4653         return this;
4654      }
4655
4656      /**
4657       * <i><l>Serializer</l> configuration property:&emsp;</i>  URI resolution.
4658       *
4659       * <p>
4660       * Defines the resolution level for URIs when serializing any of the following:
4661       * <ul>
4662       *    <li>{@link java.net.URI}
4663       *    <li>{@link java.net.URL}
4664       *    <li>Properties and classes annotated with {@link Uri @Uri}
4665       * </ul>
4666       *
4667       * <p>
4668       * See {@link #uriContext(UriContext)} for examples.
4669       *
4670       * <ul class='values'>
4671       *    <li class='jf'>{@link UriResolution#ABSOLUTE}
4672       *       - Resolve to an absolute URI (e.g. <js>"http://host:port/context-root/servlet-path/path-info"</js>).
4673       *    <li class='jf'>{@link UriResolution#ROOT_RELATIVE}
4674       *       - Resolve to a root-relative URI (e.g. <js>"/context-root/servlet-path/path-info"</js>).
4675       *    <li class='jf'>{@link UriResolution#NONE}
4676       *       - Don't do any URI resolution.
4677       * </ul>
4678       *
4679       * <h5 class='section'>See Also:</h5><ul>
4680       *    <li class='jm'>{@link org.apache.juneau.serializer.Serializer.Builder#uriResolution(UriResolution)}
4681       *    <li class='link'><a class="doclink" href="../../../../../index.html#jm.MarshallingUris">URIs</a>
4682       * </ul>
4683       *
4684       * @param value
4685       *    The new value for this property.
4686       *    <br>The default is {@link UriResolution#NONE}
4687       * @return This object.
4688       */
4689      @FluentSetter
4690      public Builder uriResolution(UriResolution value) {
4691         serializers().forEach(x -> x.uriResolution(value));
4692         return this;
4693      }
4694
4695      //-----------------------------------------------------------------------------------------------------------------
4696      // WriterSerializer Properties
4697      //-----------------------------------------------------------------------------------------------------------------
4698
4699      /**
4700       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Maximum indentation.
4701       *
4702       * <p>
4703       * Specifies the maximum indentation level in the serialized document.
4704       *
4705       * <h5 class='section'>Notes:</h5><ul>
4706       *    <li class='note'>This setting does not apply to the RDF serializers.
4707       * </ul>
4708       *
4709       * <h5 class='section'>Example:</h5>
4710       * <p class='bjava'>
4711       *    <jc>// Create a REST client with JSON serializer that indents a maximum of 20 tabs.</jc>
4712       *    RestClient <jv>client</jv> = RestClient
4713       *       .<jsm>create</jsm>()
4714       *       .json()
4715       *       .ws()  <jc>// Enable whitespace</jc>
4716       *       .maxIndent(20)
4717       *       .build();
4718       * </p>
4719       *
4720       * <h5 class='section'>See Also:</h5><ul>
4721       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#maxIndent(int)}
4722       * </ul>
4723       *
4724       * @param value
4725       *    The new value for this property.
4726       *    <br>The default is <c>100</c>.
4727       * @return This object.
4728       */
4729      @FluentSetter
4730      public Builder maxIndent(int value) {
4731         serializers().forEachWS(x -> x.maxIndent(value));
4732         return this;
4733      }
4734
4735      /**
4736       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Quote character.
4737       *
4738       * <p>
4739       * Specifies the character to use for quoting attributes and values.
4740       *
4741       * <h5 class='section'>Notes:</h5><ul>
4742       *    <li class='note'>This setting does not apply to the RDF serializers.
4743       * </ul>
4744       *
4745       * <h5 class='section'>Example:</h5>
4746       * <p class='bjava'>
4747       *    <jc>// Create a REST client with JSON serializer that uses single quotes.</jc>
4748       *    RestClient <jv>client</jv> = RestClient
4749       *       .<jsm>create</jsm>()
4750       *       .json()
4751       *       .quoteChar(<js>'\''</js>)
4752       *       .build();
4753       *
4754       *    <jc>// A bean with a single property</jc>
4755       *    <jk>public class</jk> MyBean {
4756       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4757       *    }
4758       *
4759       *    <jc>// Request body will contain:  {'foo':'bar'}</jc>
4760       *    <jv>client</jv>
4761       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4762       *       .run();
4763       * </p>
4764       *
4765       * <h5 class='section'>See Also:</h5><ul>
4766       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#quoteChar(char)}
4767       * </ul>
4768       *
4769       * @param value
4770       *    The new value for this property.
4771       *    <br>The default is <js>'"'</js>.
4772       * @return This object.
4773       */
4774      @FluentSetter
4775      public Builder quoteChar(char value) {
4776         serializers().forEachWS(x -> x.quoteChar(value));
4777         return this;
4778      }
4779
4780      /**
4781       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Quote character.
4782       *
4783       * <p>
4784       * Specifies to use single quotes for quoting attributes and values.
4785       *
4786       * <h5 class='section'>Notes:</h5><ul>
4787       *    <li class='note'>This setting does not apply to the RDF serializers.
4788       * </ul>
4789       *
4790       * <h5 class='section'>Example:</h5>
4791       * <p class='bjava'>
4792       *    <jc>// Create a REST client with JSON serializer that uses single quotes.</jc>
4793       *    RestClient <jv>client</jv> = RestClient
4794       *       .<jsm>create</jsm>()
4795       *       .json()
4796       *       .sq()
4797       *       .build();
4798       *
4799       *    <jc>// A bean with a single property</jc>
4800       *    <jk>public class</jk> MyBean {
4801       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4802       *    }
4803       *
4804       *    <jc>// Request body will contain:  {'foo':'bar'}</jc>
4805       *    <jv>client</jv>
4806       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4807       *       .run();
4808       * </p>
4809       *
4810       * <h5 class='section'>See Also:</h5><ul>
4811       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#quoteChar(char)}
4812       * </ul>
4813       *
4814       * @return This object.
4815       */
4816      @FluentSetter
4817      public Builder sq() {
4818         serializers().forEachWS(x -> x.sq());
4819         return this;
4820      }
4821
4822      /**
4823       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Use whitespace.
4824       *
4825       * <p>
4826       * When enabled, whitespace is added to the output to improve readability.
4827       *
4828       * <h5 class='section'>Example:</h5>
4829       * <p class='bjava'>
4830       *    <jc>// Create a REST client with JSON serializer with whitespace enabled.</jc>
4831       *    RestClient <jv>client</jv> = RestClient
4832       *       .<jsm>create</jsm>()
4833       *       .json()
4834       *       .useWhitespace()
4835       *       .build();
4836       *
4837       *    <jc>// A bean with a single property</jc>
4838       *    <jk>public class</jk> MyBean {
4839       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4840       *    }
4841       *
4842       *    <jc>// Request body will contain:  {\n\t"foo": "bar"\n\}\n</jc>
4843       *    <jv>client</jv>
4844       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4845       *       .run();
4846       * </p>
4847       *
4848       * <h5 class='section'>See Also:</h5><ul>
4849       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#useWhitespace()}
4850       * </ul>
4851       * @return This object.
4852       */
4853      @FluentSetter
4854      public Builder useWhitespace() {
4855         serializers().forEachWS(x -> x.useWhitespace());
4856         return this;
4857      }
4858
4859      /**
4860       * <i><l>WriterSerializer</l> configuration property:&emsp;</i>  Use whitespace.
4861       *
4862       * <p>
4863       * When enabled, whitespace is added to the output to improve readability.
4864       *
4865       * <h5 class='section'>Example:</h5>
4866       * <p class='bjava'>
4867       *    <jc>// Create a REST client with JSON serializer with whitespace enabled.</jc>
4868       *    RestClient <jv>client</jv> = RestClient
4869       *       .<jsm>create</jsm>()
4870       *       .json()
4871       *       .ws()
4872       *       .build();
4873       *
4874       *    <jc>// A bean with a single property</jc>
4875       *    <jk>public class</jk> MyBean {
4876       *       <jk>public</jk> String <jf>foo</jf> = <js>"bar"</js>;
4877       *    }
4878       *
4879       *    <jc>// Request body will contain:  {\n\t"foo": "bar"\n\}\n</jc>
4880       *    <jv>client</jv>
4881       *       .post(<js>"http://localhost:10000/foo"</js>, <jk>new</jk> MyBean())
4882       *       .run();
4883       * </p>
4884       *
4885       * <h5 class='section'>See Also:</h5><ul>
4886       *    <li class='jm'>{@link org.apache.juneau.serializer.WriterSerializer.Builder#useWhitespace()}
4887       * </ul>
4888       *
4889       * @return This object.
4890       */
4891      @FluentSetter
4892      public Builder ws() {
4893         serializers().forEachWS(x -> x.ws());
4894         return this;
4895      }
4896
4897      //-----------------------------------------------------------------------------------------------------------------
4898      // OutputStreamSerializer Properties
4899      //-----------------------------------------------------------------------------------------------------------------
4900
4901      //-----------------------------------------------------------------------------------------------------------------
4902      // Parser Properties
4903      //-----------------------------------------------------------------------------------------------------------------
4904
4905      /**
4906       * <i><l>Parser</l> configuration property:&emsp;</i>  Debug output lines.
4907       *
4908       * <p>
4909       * When parse errors occur, this specifies the number of lines of input before and after the
4910       * error location to be printed as part of the exception message.
4911       *
4912       * <h5 class='section'>Example:</h5>
4913       * <p class='bjava'>
4914       *    <jc>// Create a parser whose exceptions print out 100 lines before and after the parse error location.</jc>
4915       *    RestClient <jv>client</jv> = RestClient
4916       *       .<jsm>create</jsm>()
4917       *       .json()
4918       *       .debug()  <jc>// Enable debug mode to capture Reader contents as strings.</jc>
4919       *       .debugOuputLines(100)
4920       *       .build();
4921       *
4922       *    <jc>// Try to parse some bad JSON.</jc>
4923       *    <jk>try</jk> {
4924       *       <jv>client</jv>
4925       *          .get(<js>"/pathToBadJson"</js>)
4926       *          .run()
4927       *          .getContent().as(Object.<jk>class</jk>);  <jc>// Try to parse it.</jc>
4928       *    } <jk>catch</jk> (RestCallException <jv>e</jv>) {
4929       *       System.<jsf>err</jsf>.println(<jv>e</jv>.getMessage());  <jc>// Will display 200 lines of the output.</jc>
4930       *    }
4931       * </p>
4932       *
4933       * <h5 class='section'>See Also:</h5><ul>
4934       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#debugOutputLines(int)}
4935       * </ul>
4936       *
4937       * @param value
4938       *    The new value for this property.
4939       *    <br>The default value is <c>5</c>.
4940       * @return This object.
4941       */
4942      @FluentSetter
4943      public Builder debugOutputLines(int value) {
4944         parsers().forEach(x -> x.debugOutputLines(value));
4945         return this;
4946      }
4947
4948      /**
4949       * <i><l>Parser</l> configuration property:&emsp;</i>  Strict mode.
4950       *
4951       * <p>
4952       * When enabled, strict mode for the parser is enabled.
4953       *
4954       * <p>
4955       * Strict mode can mean different things for different parsers.
4956       *
4957       * <table class='styled'>
4958       *    <tr><th>Parser class</th><th>Strict behavior</th></tr>
4959       *    <tr>
4960       *       <td>All reader-based parsers</td>
4961       *       <td>
4962       *          When enabled, throws {@link ParseException ParseExceptions} on malformed charset input.
4963       *          Otherwise, malformed input is ignored.
4964       *       </td>
4965       *    </tr>
4966       *    <tr>
4967       *       <td>{@link JsonParser}</td>
4968       *       <td>
4969       *          When enabled, throws exceptions on the following invalid JSON syntax:
4970       *          <ul>
4971       *             <li>Unquoted attributes.
4972       *             <li>Missing attribute values.
4973       *             <li>Concatenated strings.
4974       *             <li>Javascript comments.
4975       *             <li>Numbers and booleans when Strings are expected.
4976       *             <li>Numbers valid in Java but not JSON (e.g. octal notation, etc...)
4977       *          </ul>
4978       *       </td>
4979       *    </tr>
4980       * </table>
4981       *
4982       * <h5 class='section'>Example:</h5>
4983       * <p class='bjava'>
4984       *    <jc>// Create a REST client with JSON parser using strict mode.</jc>
4985       *    RestClient <jv>client</jv> = RestClient
4986       *       .<jsm>create</jsm>()
4987       *       .json()
4988       *       .strict()
4989       *       .build();
4990       *
4991       *    <jc>// Try to parse some bad JSON.</jc>
4992       *    <jk>try</jk> {
4993       *       <jv>client</jv>
4994       *          .get(<js>"/pathToBadJson"</js>)
4995       *          .run()
4996       *          .getContent().as(Object.<jk>class</jk>);  <jc>// Try to parse it.</jc>
4997       *    } <jk>catch</jk> (RestCallException <jv>e</jv>) {
4998       *       <jc>// Handle exception.</jc>
4999       *    }
5000       * </p>
5001       *
5002       * <h5 class='section'>See Also:</h5><ul>
5003       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#strict()}
5004       * </ul>
5005       *
5006       * @return This object.
5007       */
5008      @FluentSetter
5009      public Builder strict() {
5010         parsers().forEach(x -> x.strict());
5011         return this;
5012      }
5013
5014      /**
5015       * <i><l>Parser</l> configuration property:&emsp;</i>  Trim parsed strings.
5016       *
5017       * <p>
5018       * When enabled, string values will be trimmed of whitespace using {@link String#trim()} before being added to
5019       * the POJO.
5020       *
5021       * <h5 class='section'>Example:</h5>
5022       * <p class='bjava'>
5023       *    <jc>// Create a REST client with JSON parser with trim-strings enabled.</jc>
5024       *    RestClient <jv>client</jv> = RestClient
5025       *       .<jsm>create</jsm>()
5026       *       .json()
5027       *       .trimStringsOnRead()
5028       *       .build();
5029       *
5030       *    <jc>// Try to parse JSON containing {" foo ":" bar "}.</jc>
5031       *    Map&lt;String,String&gt; <jv>map</jv> = <jv>client</jv>
5032       *       .get(<js>"/pathToJson"</js>)
5033       *       .run()
5034       *       .getContent().as(HashMap.<jk>class</jk>, String.<jk>class</jk>, String.<jk>class</jk>);
5035       *
5036       *    <jc>// Make sure strings are trimmed.</jc>
5037       *    <jsm>assertEquals</jsm>(<js>"bar"</js>, <jv>map</jv>.get(<js>"foo"</js>));
5038       * </p>
5039       *
5040       * <h5 class='section'>See Also:</h5><ul>
5041       *    <li class='jm'>{@link org.apache.juneau.parser.Parser.Builder#trimStrings()}
5042       * </ul>
5043       *
5044       * @return This object.
5045       */
5046      @FluentSetter
5047      public Builder trimStringsOnRead() {
5048         parsers().forEach(x -> x.trimStrings());
5049         return this;
5050      }
5051
5052      //-----------------------------------------------------------------------------------------------------------------
5053      // ReaderParser Properties
5054      //-----------------------------------------------------------------------------------------------------------------
5055
5056      //-----------------------------------------------------------------------------------------------------------------
5057      // InputStreamParser Properties
5058      //-----------------------------------------------------------------------------------------------------------------
5059
5060      //-----------------------------------------------------------------------------------------------------------------
5061      // OpenApi Properties
5062      //-----------------------------------------------------------------------------------------------------------------
5063
5064      /**
5065       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default OpenAPI format for HTTP parts.
5066       *
5067       * <p>
5068       * Specifies the format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#format()} for
5069       * the OpenAPI serializer and parser on this client.
5070       *
5071       * <h5 class='section'>Example:</h5>
5072       * <p class='bjava'>
5073       *    <jc>// Create a REST client with UON part serialization and parsing.</jc>
5074       *    RestClient <jv>client</jv>  = RestClient
5075       *       .<jsm>create</jsm>()
5076       *       .oapiFormat(<jsf>UON</jsf>)
5077       *       .build();
5078       *
5079       *    <jc>// Set a header with a value in UON format.</jc>
5080       *    <jv>client</jv>
5081       *       .get(<js>"/uri"</js>)
5082       *       .header(<js>"Foo"</js>, <js>"bar baz"</js>)  <jc>// Will be serialized as:  'bar baz'</jc>
5083       *       .run();
5084       * </p>
5085       *
5086       * <ul class='values javatree'>
5087       *    <li class='jc'>{@link org.apache.juneau.httppart.HttpPartFormat}
5088       *    <ul>
5089       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#UON UON} - UON notation (e.g. <js>"'foo bar'"</js>).
5090       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT32 INT32} - Signed 32 bits.
5091       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#INT64 INT64} - Signed 64 bits.
5092       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#FLOAT FLOAT} - 32-bit floating point number.
5093       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DOUBLE DOUBLE} - 64-bit floating point number.
5094       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BYTE BYTE} - BASE-64 encoded characters.
5095       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY BINARY} - Hexadecimal encoded octets (e.g. <js>"00FF"</js>).
5096       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#BINARY_SPACED BINARY_SPACED} - Spaced-separated hexadecimal encoded octets (e.g. <js>"00 FF"</js>).
5097       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE DATE} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 full-date</a>.
5098       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#DATE_TIME DATE_TIME} - An <a href='http://xml2rfc.ietf.org/public/rfc/html/rfc3339.html#anchor14'>RFC3339 date-time</a>.
5099       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#PASSWORD PASSWORD} - Used to hint UIs the input needs to be obscured.
5100       *       <li class='jf'>{@link org.apache.juneau.httppart.HttpPartFormat#NO_FORMAT NO_FORMAT} - (default) Not specified.
5101       *    </ul>
5102       * </ul>
5103       *
5104       * <h5 class='section'>See Also:</h5><ul>
5105       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiSerializer.Builder#format(HttpPartFormat)}
5106       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiParser.Builder#format(HttpPartFormat)}
5107       * </ul>
5108       *
5109       * @param value
5110       *    The new value for this property.
5111       *    <br>The default value is {@link HttpPartFormat#NO_FORMAT}.
5112       * @return This object.
5113       */
5114      @FluentSetter
5115      public Builder oapiFormat(HttpPartFormat value) {
5116         serializers().forEach(OpenApiSerializer.Builder.class, x -> x.format(value));
5117         parsers().forEach(OpenApiParser.Builder.class, x -> x.format(value));
5118         partSerializer().builder(OpenApiSerializer.Builder.class).ifPresent(x -> x.format(value));
5119         partParser().builder(OpenApiParser.Builder.class).ifPresent(x -> x.format(value));
5120         return this;
5121      }
5122
5123      /**
5124       * <i><l>OpenApiCommon</l> configuration property:&emsp;</i>  Default collection format for HTTP parts.
5125       *
5126       * <p>
5127       * Specifies the collection format to use for HTTP parts when not otherwise specified via {@link org.apache.juneau.annotation.Schema#collectionFormat()} for the
5128       * OpenAPI serializer and parser on this client.
5129       *
5130       * <h5 class='section'>Example:</h5>
5131       * <p class='bjava'>
5132       *    <jc>// Create a REST client with CSV format for http parts.</jc>
5133       *    RestClient <jv>client</jv> = RestClient
5134       *       .<jsm>create</jsm>()
5135       *       .collectionFormat(<jsf>CSV</jsf>)
5136       *       .build();
5137       *
5138       *    <jc>// An arbitrary data structure.</jc>
5139       *    AList <jv>list</jv> = AList.<jsm>of</jsm>(
5140       *       <js>"foo"</js>,
5141       *       <js>"bar"</js>,
5142       *       AMap.<jsm>of</jsm>(
5143       *          <js>"baz"</js>, AList.<jsm>of</jsm>(<js>"qux"</js>,<js>"true"</js>,<js>"123"</js>)
5144       *    )
5145       * );
5146       *
5147       *    <jc>// Set a header with a comma-separated list.</jc>
5148       *    <jv>client</jv>
5149       *       .get(<js>"/uri"</js>)
5150       *       .header(<js>"Foo"</js>, <jv>list</jv>)  <jc>// Will be serialized as: foo=bar,baz=qux\,true\,123</jc>
5151       *       .run();
5152       * </p>
5153       *
5154       * <ul class='values javatree'>
5155       *    <li class='jc'>{@link HttpPartCollectionFormat}
5156       *    <ul>
5157       *       <li class='jf'>{@link HttpPartCollectionFormat#CSV CSV} - (default) Comma-separated values (e.g. <js>"foo,bar"</js>).
5158       *       <li class='jf'>{@link HttpPartCollectionFormat#SSV SSV} - Space-separated values (e.g. <js>"foo bar"</js>).
5159       *       <li class='jf'>{@link HttpPartCollectionFormat#TSV TSV} - Tab-separated values (e.g. <js>"foo\tbar"</js>).
5160       *       <li class='jf'>{@link HttpPartCollectionFormat#PIPES PIPES} - Pipe-separated values (e.g. <js>"foo|bar"</js>).
5161       *       <li class='jf'>{@link HttpPartCollectionFormat#MULTI MULTI} - Corresponds to multiple parameter instances instead of multiple values for a single instance (e.g. <js>"foo=bar&amp;foo=baz"</js>).
5162       *       <li class='jf'>{@link HttpPartCollectionFormat#UONC UONC} - UON collection notation (e.g. <js>"@(foo,bar)"</js>).
5163       *    </ul>
5164       * </ul>
5165       *
5166       * <h5 class='section'>See Also:</h5><ul>
5167       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiSerializer.Builder#collectionFormat(HttpPartCollectionFormat)}
5168       *    <li class='jm'>{@link org.apache.juneau.oapi.OpenApiParser.Builder#collectionFormat(HttpPartCollectionFormat)}
5169       * </ul>
5170       *
5171       * @param value
5172       *    The new value for this property.
5173       *    <br>The default value is {@link HttpPartCollectionFormat#NO_COLLECTION_FORMAT}.
5174       * @return This object.
5175       */
5176      @FluentSetter
5177      public Builder oapiCollectionFormat(HttpPartCollectionFormat value) {
5178         serializers().forEach(OpenApiSerializer.Builder.class, x -> x.collectionFormat(value));
5179         parsers().forEach(OpenApiParser.Builder.class, x -> x.collectionFormat(value));
5180         partSerializer().builder(OpenApiSerializer.Builder.class, x -> x.collectionFormat(value));
5181         partParser().builder(OpenApiParser.Builder.class, x -> x.collectionFormat(value));
5182         return this;
5183      }
5184
5185      //-----------------------------------------------------------------------------------------------------------------
5186      // UON Properties
5187      //-----------------------------------------------------------------------------------------------------------------
5188
5189      /**
5190       * <i><l>UonSerializer</l> configuration property:&emsp;</i>  Parameter format.
5191       *
5192       * <p>
5193       * Specifies the format of parameters when using the {@link UrlEncodingSerializer} to serialize Form Posts.
5194       *
5195       * <p>
5196       * Specifies the format to use for GET parameter keys and values.
5197       *
5198       * <h5 class='section'>Example:</h5>
5199       * <p class='bjava'>
5200       *    <jc>// Create a REST client with URL-Encoded serializer that serializes values in plain-text format.</jc>
5201       *    RestClient <jv>client</jv> = RestClient
5202       *       .<jsm>create</jsm>()
5203       *       .urlEnc()
5204       *       .paramFormat(<jsf>PLAINTEXT</jsf>)
5205       *       .build();
5206       *
5207       *    <jc>// An arbitrary data structure.</jc>
5208       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(
5209       *       <js>"foo"</js>, <js>"bar"</js>,
5210       *       <js>"baz"</js>, <jk>new</jk> String[]{<js>"qux"</js>, <js>"true"</js>, <js>"123"</js>}
5211       *    );
5212       *
5213       *    <jc>// Request body will be serialized as:  foo=bar,baz=qux,true,123</jc>
5214       *    <jv>client</jv>
5215       *       .post(<js>"/uri"</js>, <jv>map</jv>)
5216       *       .run();
5217       * </p>
5218       *
5219       * <ul class='values javatree'>
5220       *    <li class='jf'>{@link ParamFormat#UON} (default) - Use UON notation for parameters.
5221       *    <li class='jf'>{@link ParamFormat#PLAINTEXT} - Use plain text for parameters.
5222       * </ul>
5223       *
5224       * <h5 class='section'>See Also:</h5><ul>
5225       *    <li class='jm'>{@link org.apache.juneau.uon.UonSerializer.Builder#paramFormat(ParamFormat)}
5226       * </ul>
5227       *
5228       * @param value The new value for this property.
5229       * @return This object.
5230       */
5231      @FluentSetter
5232      public Builder paramFormat(ParamFormat value) {
5233         serializers().forEach(UonSerializer.Builder.class, x -> x.paramFormat(value));
5234         return this;
5235      }
5236
5237      /**
5238       * <i><l>UonSerializer</l> configuration property:&emsp;</i>  Parameter format.
5239       *
5240       * <p>
5241       * Specifies the format of parameters when using the {@link UrlEncodingSerializer} to serialize Form Posts.
5242       *
5243       * <p>
5244       * Specifies plaintext as the format to use for GET parameter keys and values.
5245       *
5246       * <h5 class='section'>Example:</h5>
5247       * <p class='bjava'>
5248       *    <jc>// Create a REST client with URL-Encoded serializer that serializes values in plain-text format.</jc>
5249       *    RestClient <jv>client</jv> = RestClient
5250       *       .<jsm>create</jsm>()
5251       *       .urlEnc()
5252       *       .build();
5253       *
5254       *    <jc>// An arbitrary data structure.</jc>
5255       *    AMap <jv>map</jv> = AMap.<jsm>of</jsm>(
5256       *       <js>"foo"</js>, <js>"bar"</js>,
5257       *       <js>"baz"</js>, <jk>new</jk> String[]{<js>"qux"</js>, <js>"true"</js>, <js>"123"</js>}
5258       *    );
5259       *
5260       *    <jc>// Request body will be serialized as:  foo=bar,baz=qux,true,123</jc>
5261       *    <jv>client</jv>
5262       *       .post(<js>"/uri"</js>, <jv>map</jv>)
5263       *       .run();
5264       * </p>
5265       *
5266       * <h5 class='section'>See Also:</h5><ul>
5267       *    <li class='jm'>{@link org.apache.juneau.uon.UonSerializer.Builder#paramFormatPlain()}
5268       * </ul>
5269       *
5270       * @return This object.
5271       */
5272      @FluentSetter
5273      public Builder paramFormatPlain() {
5274         serializers().forEach(UonSerializer.Builder.class, x -> x.paramFormatPlain());
5275         return this;
5276      }
5277
5278      // <FluentSetters>
5279
5280      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5281      public Builder annotations(Annotation...values) {
5282         super.annotations(values);
5283         return this;
5284      }
5285
5286      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5287      public Builder apply(AnnotationWorkList work) {
5288         super.apply(work);
5289         return this;
5290      }
5291
5292      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5293      public Builder applyAnnotations(java.lang.Class<?>...fromClasses) {
5294         super.applyAnnotations(fromClasses);
5295         return this;
5296      }
5297
5298      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5299      public Builder applyAnnotations(Method...fromMethods) {
5300         super.applyAnnotations(fromMethods);
5301         return this;
5302      }
5303
5304      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5305      public Builder cache(Cache<HashKey,? extends org.apache.juneau.Context> value) {
5306         super.cache(value);
5307         return this;
5308      }
5309
5310      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5311      public Builder impl(Context value) {
5312         super.impl(value);
5313         return this;
5314      }
5315
5316      @Override /* GENERATED - org.apache.juneau.Context.Builder */
5317      public Builder type(Class<? extends org.apache.juneau.Context> value) {
5318         super.type(value);
5319         return this;
5320      }
5321
5322      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5323      public Builder beanClassVisibility(Visibility value) {
5324         super.beanClassVisibility(value);
5325         return this;
5326      }
5327
5328      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5329      public Builder beanConstructorVisibility(Visibility value) {
5330         super.beanConstructorVisibility(value);
5331         return this;
5332      }
5333
5334      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5335      public Builder beanContext(BeanContext value) {
5336         super.beanContext(value);
5337         return this;
5338      }
5339
5340      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5341      public Builder beanContext(BeanContext.Builder value) {
5342         super.beanContext(value);
5343         return this;
5344      }
5345
5346      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5347      public Builder beanDictionary(java.lang.Class<?>...values) {
5348         super.beanDictionary(values);
5349         return this;
5350      }
5351
5352      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5353      public Builder beanFieldVisibility(Visibility value) {
5354         super.beanFieldVisibility(value);
5355         return this;
5356      }
5357
5358      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5359      public Builder beanInterceptor(Class<?> on, Class<? extends org.apache.juneau.swap.BeanInterceptor<?>> value) {
5360         super.beanInterceptor(on, value);
5361         return this;
5362      }
5363
5364      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5365      public Builder beanMethodVisibility(Visibility value) {
5366         super.beanMethodVisibility(value);
5367         return this;
5368      }
5369
5370      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5371      public Builder beanProperties(Map<String,Object> values) {
5372         super.beanProperties(values);
5373         return this;
5374      }
5375
5376      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5377      public Builder beanProperties(Class<?> beanClass, String properties) {
5378         super.beanProperties(beanClass, properties);
5379         return this;
5380      }
5381
5382      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5383      public Builder beanProperties(String beanClassName, String properties) {
5384         super.beanProperties(beanClassName, properties);
5385         return this;
5386      }
5387
5388      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5389      public Builder beanPropertiesExcludes(Map<String,Object> values) {
5390         super.beanPropertiesExcludes(values);
5391         return this;
5392      }
5393
5394      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5395      public Builder beanPropertiesExcludes(Class<?> beanClass, String properties) {
5396         super.beanPropertiesExcludes(beanClass, properties);
5397         return this;
5398      }
5399
5400      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5401      public Builder beanPropertiesExcludes(String beanClassName, String properties) {
5402         super.beanPropertiesExcludes(beanClassName, properties);
5403         return this;
5404      }
5405
5406      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5407      public Builder beanPropertiesReadOnly(Map<String,Object> values) {
5408         super.beanPropertiesReadOnly(values);
5409         return this;
5410      }
5411
5412      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5413      public Builder beanPropertiesReadOnly(Class<?> beanClass, String properties) {
5414         super.beanPropertiesReadOnly(beanClass, properties);
5415         return this;
5416      }
5417
5418      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5419      public Builder beanPropertiesReadOnly(String beanClassName, String properties) {
5420         super.beanPropertiesReadOnly(beanClassName, properties);
5421         return this;
5422      }
5423
5424      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5425      public Builder beanPropertiesWriteOnly(Map<String,Object> values) {
5426         super.beanPropertiesWriteOnly(values);
5427         return this;
5428      }
5429
5430      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5431      public Builder beanPropertiesWriteOnly(Class<?> beanClass, String properties) {
5432         super.beanPropertiesWriteOnly(beanClass, properties);
5433         return this;
5434      }
5435
5436      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5437      public Builder beanPropertiesWriteOnly(String beanClassName, String properties) {
5438         super.beanPropertiesWriteOnly(beanClassName, properties);
5439         return this;
5440      }
5441
5442      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5443      public Builder beansRequireDefaultConstructor() {
5444         super.beansRequireDefaultConstructor();
5445         return this;
5446      }
5447
5448      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5449      public Builder beansRequireSerializable() {
5450         super.beansRequireSerializable();
5451         return this;
5452      }
5453
5454      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5455      public Builder beansRequireSettersForGetters() {
5456         super.beansRequireSettersForGetters();
5457         return this;
5458      }
5459
5460      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5461      public Builder dictionaryOn(Class<?> on, java.lang.Class<?>...values) {
5462         super.dictionaryOn(on, values);
5463         return this;
5464      }
5465
5466      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5467      public Builder disableBeansRequireSomeProperties() {
5468         super.disableBeansRequireSomeProperties();
5469         return this;
5470      }
5471
5472      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5473      public Builder disableIgnoreMissingSetters() {
5474         super.disableIgnoreMissingSetters();
5475         return this;
5476      }
5477
5478      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5479      public Builder disableIgnoreTransientFields() {
5480         super.disableIgnoreTransientFields();
5481         return this;
5482      }
5483
5484      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5485      public Builder disableIgnoreUnknownNullBeanProperties() {
5486         super.disableIgnoreUnknownNullBeanProperties();
5487         return this;
5488      }
5489
5490      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5491      public Builder disableInterfaceProxies() {
5492         super.disableInterfaceProxies();
5493         return this;
5494      }
5495
5496      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5497      public Builder findFluentSetters() {
5498         super.findFluentSetters();
5499         return this;
5500      }
5501
5502      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5503      public Builder findFluentSetters(Class<?> on) {
5504         super.findFluentSetters(on);
5505         return this;
5506      }
5507
5508      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5509      public Builder ignoreInvocationExceptionsOnGetters() {
5510         super.ignoreInvocationExceptionsOnGetters();
5511         return this;
5512      }
5513
5514      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5515      public Builder ignoreInvocationExceptionsOnSetters() {
5516         super.ignoreInvocationExceptionsOnSetters();
5517         return this;
5518      }
5519
5520      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5521      public Builder ignoreUnknownBeanProperties() {
5522         super.ignoreUnknownBeanProperties();
5523         return this;
5524      }
5525
5526      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5527      public Builder ignoreUnknownEnumValues() {
5528         super.ignoreUnknownEnumValues();
5529         return this;
5530      }
5531
5532      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5533      public Builder implClass(Class<?> interfaceClass, Class<?> implClass) {
5534         super.implClass(interfaceClass, implClass);
5535         return this;
5536      }
5537
5538      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5539      public Builder implClasses(Map<Class<?>,Class<?>> values) {
5540         super.implClasses(values);
5541         return this;
5542      }
5543
5544      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5545      public Builder interfaceClass(Class<?> on, Class<?> value) {
5546         super.interfaceClass(on, value);
5547         return this;
5548      }
5549
5550      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5551      public Builder interfaces(java.lang.Class<?>...value) {
5552         super.interfaces(value);
5553         return this;
5554      }
5555
5556      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5557      public Builder locale(Locale value) {
5558         super.locale(value);
5559         return this;
5560      }
5561
5562      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5563      public Builder notBeanClasses(java.lang.Class<?>...values) {
5564         super.notBeanClasses(values);
5565         return this;
5566      }
5567
5568      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5569      public Builder notBeanPackages(String...values) {
5570         super.notBeanPackages(values);
5571         return this;
5572      }
5573
5574      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5575      public Builder propertyNamer(Class<? extends org.apache.juneau.PropertyNamer> value) {
5576         super.propertyNamer(value);
5577         return this;
5578      }
5579
5580      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5581      public Builder propertyNamer(Class<?> on, Class<? extends org.apache.juneau.PropertyNamer> value) {
5582         super.propertyNamer(on, value);
5583         return this;
5584      }
5585
5586      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5587      public Builder sortProperties() {
5588         super.sortProperties();
5589         return this;
5590      }
5591
5592      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5593      public Builder sortProperties(java.lang.Class<?>...on) {
5594         super.sortProperties(on);
5595         return this;
5596      }
5597
5598      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5599      public Builder stopClass(Class<?> on, Class<?> value) {
5600         super.stopClass(on, value);
5601         return this;
5602      }
5603
5604      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5605      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction) {
5606         super.swap(normalClass, swappedClass, swapFunction);
5607         return this;
5608      }
5609
5610      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5611      public <T, S> Builder swap(Class<T> normalClass, Class<S> swappedClass, ThrowingFunction<T,S> swapFunction, ThrowingFunction<S,T> unswapFunction) {
5612         super.swap(normalClass, swappedClass, swapFunction, unswapFunction);
5613         return this;
5614      }
5615
5616      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5617      public Builder swaps(java.lang.Class<?>...values) {
5618         super.swaps(values);
5619         return this;
5620      }
5621
5622      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5623      public Builder timeZone(TimeZone value) {
5624         super.timeZone(value);
5625         return this;
5626      }
5627
5628      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5629      public Builder typeName(Class<?> on, String value) {
5630         super.typeName(on, value);
5631         return this;
5632      }
5633
5634      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5635      public Builder typePropertyName(String value) {
5636         super.typePropertyName(value);
5637         return this;
5638      }
5639
5640      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5641      public Builder typePropertyName(Class<?> on, String value) {
5642         super.typePropertyName(on, value);
5643         return this;
5644      }
5645
5646      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5647      public Builder useEnumNames() {
5648         super.useEnumNames();
5649         return this;
5650      }
5651
5652      @Override /* GENERATED - org.apache.juneau.BeanContextable.Builder */
5653      public Builder useJavaBeanIntrospector() {
5654         super.useJavaBeanIntrospector();
5655         return this;
5656      }
5657
5658      // </FluentSetters>
5659
5660      //------------------------------------------------------------------------------------------------
5661      // Passthrough methods for HttpClientBuilder.
5662      //------------------------------------------------------------------------------------------------
5663
5664      /**
5665       * Disables automatic redirect handling.
5666       *
5667       * @return This object.
5668       * @see HttpClientBuilder#disableRedirectHandling()
5669       */
5670      @FluentSetter
5671      public Builder disableRedirectHandling() {
5672         httpClientBuilder().disableRedirectHandling();
5673         return this;
5674      }
5675
5676      /**
5677       * Assigns {@link RedirectStrategy} instance.
5678       *
5679       * <h5 class='section'>Notes:</h5><ul>
5680       *    <li class='note'>This value can be overridden by the {@link #disableRedirectHandling()} method.
5681       * </ul>
5682       *
5683       * @param redirectStrategy New property value.
5684       * @return This object.
5685       * @see HttpClientBuilder#setRedirectStrategy(RedirectStrategy)
5686       */
5687      @FluentSetter
5688      public Builder redirectStrategy(RedirectStrategy redirectStrategy) {
5689         httpClientBuilder().setRedirectStrategy(redirectStrategy);
5690         return this;
5691      }
5692
5693      /**
5694       * Assigns default {@link CookieSpec} registry which will be used for request execution if not explicitly set in the client execution context.
5695       *
5696       * @param cookieSpecRegistry New property value.
5697       * @return This object.
5698       * @see HttpClientBuilder#setDefaultCookieSpecRegistry(Lookup)
5699       */
5700      @FluentSetter
5701      public Builder defaultCookieSpecRegistry(Lookup<CookieSpecProvider> cookieSpecRegistry) {
5702         httpClientBuilder().setDefaultCookieSpecRegistry(cookieSpecRegistry);
5703         return this;
5704      }
5705
5706      /**
5707       * Assigns {@link HttpRequestExecutor} instance.
5708       *
5709       * @param requestExec New property value.
5710       * @return This object.
5711       * @see HttpClientBuilder#setRequestExecutor(HttpRequestExecutor)
5712       */
5713      @FluentSetter
5714      public Builder requestExecutor(HttpRequestExecutor requestExec) {
5715         httpClientBuilder().setRequestExecutor(requestExec);
5716         return this;
5717      }
5718
5719      /**
5720       * Assigns {@link javax.net.ssl.HostnameVerifier} instance.
5721       *
5722       * <h5 class='section'>Notes:</h5><ul>
5723       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)}
5724       *       and the {@link #sslSocketFactory(LayeredConnectionSocketFactory)} methods.
5725       * </ul>
5726       *
5727       * @param hostnameVerifier New property value.
5728       * @return This object.
5729       * @see HttpClientBuilder#setSSLHostnameVerifier(HostnameVerifier)
5730       */
5731      @FluentSetter
5732      public Builder sslHostnameVerifier(HostnameVerifier hostnameVerifier) {
5733         httpClientBuilder().setSSLHostnameVerifier(hostnameVerifier);
5734         return this;
5735      }
5736
5737      /**
5738       * Assigns file containing public suffix matcher.
5739       *
5740       * <h5 class='section'>Notes:</h5><ul>
5741       *    <li class='note'>Instances of this class can be created with {@link PublicSuffixMatcherLoader}.
5742       * </ul>
5743       *
5744       * @param publicSuffixMatcher New property value.
5745       * @return This object.
5746       * @see HttpClientBuilder#setPublicSuffixMatcher(PublicSuffixMatcher)
5747       */
5748      @FluentSetter
5749      public Builder publicSuffixMatcher(PublicSuffixMatcher publicSuffixMatcher) {
5750         httpClientBuilder().setPublicSuffixMatcher(publicSuffixMatcher);
5751         return this;
5752      }
5753
5754      /**
5755       * Assigns {@link SSLContext} instance.
5756       *
5757       * <h5 class='section'>Notes:</h5><ul>
5758       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)}
5759       *    and the {@link #sslSocketFactory(LayeredConnectionSocketFactory)} methods.
5760       * </ul>
5761       *
5762       * @param sslContext New property value.
5763       * @return This object.
5764       * @see HttpClientBuilder#setSSLContext(SSLContext)
5765       */
5766      @FluentSetter
5767      public Builder sslContext(SSLContext sslContext) {
5768         httpClientBuilder().setSSLContext(sslContext);
5769         return this;
5770      }
5771
5772      /**
5773       * Assigns {@link LayeredConnectionSocketFactory} instance.
5774       *
5775       * <h5 class='section'>Notes:</h5><ul>
5776       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5777       * </ul>
5778       *
5779       * @param sslSocketFactory New property value.
5780       * @return This object.
5781       * @see HttpClientBuilder#setSSLSocketFactory(LayeredConnectionSocketFactory)
5782       */
5783      @FluentSetter
5784      public Builder sslSocketFactory(LayeredConnectionSocketFactory sslSocketFactory) {
5785         httpClientBuilder().setSSLSocketFactory(sslSocketFactory);
5786         return this;
5787      }
5788
5789      /**
5790       * Assigns maximum total connection value.
5791       *
5792       * <h5 class='section'>Notes:</h5><ul>
5793       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5794       * </ul>
5795       *
5796       * @param maxConnTotal New property value.
5797       * @return This object.
5798       * @see HttpClientBuilder#setMaxConnTotal(int)
5799       */
5800      @FluentSetter
5801      public Builder maxConnTotal(int maxConnTotal) {
5802         httpClientBuilder().setMaxConnTotal(maxConnTotal);
5803         return this;
5804      }
5805
5806      /**
5807       * Assigns maximum connection per route value.
5808       *
5809       * <h5 class='section'>Notes:</h5><ul>
5810       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5811       * </ul>
5812       *
5813       * @param maxConnPerRoute New property value.
5814       * @return This object.
5815       * @see HttpClientBuilder#setMaxConnPerRoute(int)
5816       */
5817      @FluentSetter
5818      public Builder maxConnPerRoute(int maxConnPerRoute) {
5819         httpClientBuilder().setMaxConnPerRoute(maxConnPerRoute);
5820         return this;
5821      }
5822
5823      /**
5824       * Assigns default {@link SocketConfig}.
5825       *
5826       * <h5 class='section'>Notes:</h5><ul>
5827       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5828       * </ul>
5829       *
5830       * @param config New property value.
5831       * @return This object.
5832       * @see HttpClientBuilder#setDefaultSocketConfig(SocketConfig)
5833       */
5834      @FluentSetter
5835      public Builder defaultSocketConfig(SocketConfig config) {
5836         httpClientBuilder().setDefaultSocketConfig(config);
5837         return this;
5838      }
5839
5840      /**
5841       * Assigns default {@link ConnectionConfig}.
5842       *
5843       * <h5 class='section'>Notes:</h5><ul>
5844       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5845       * </ul>
5846       *
5847       * @param config New property value.
5848       * @return This object.
5849       * @see HttpClientBuilder#setDefaultConnectionConfig(ConnectionConfig)
5850       */
5851      @FluentSetter
5852      public Builder defaultConnectionConfig(ConnectionConfig config) {
5853         httpClientBuilder().setDefaultConnectionConfig(config);
5854         return this;
5855      }
5856
5857      /**
5858       * Sets maximum time to live for persistent connections.
5859       *
5860       * <h5 class='section'>Notes:</h5><ul>
5861       *    <li class='note'>This value can be overridden by the {@link #connectionManager(HttpClientConnectionManager)} method.
5862       * </ul>
5863       *
5864       * @param connTimeToLive New property value.
5865       * @param connTimeToLiveTimeUnit New property value.
5866       * @return This object.
5867       * @see HttpClientBuilder#setConnectionTimeToLive(long,TimeUnit)
5868       */
5869      @FluentSetter
5870      public Builder connectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit) {
5871         httpClientBuilder().setConnectionTimeToLive(connTimeToLive, connTimeToLiveTimeUnit);
5872         return this;
5873      }
5874
5875      /**
5876       * Assigns {@link ConnectionReuseStrategy} instance.
5877       *
5878       * @param reuseStrategy New property value.
5879       * @return This object.
5880       * @see HttpClientBuilder#setConnectionReuseStrategy(ConnectionReuseStrategy)
5881       */
5882      @FluentSetter
5883      public Builder connectionReuseStrategy(ConnectionReuseStrategy reuseStrategy) {
5884         httpClientBuilder().setConnectionReuseStrategy(reuseStrategy);
5885         return this;
5886      }
5887
5888      /**
5889       * Assigns {@link ConnectionKeepAliveStrategy} instance.
5890       *
5891       * @param keepAliveStrategy New property value.
5892       * @return This object.
5893       * @see HttpClientBuilder#setKeepAliveStrategy(ConnectionKeepAliveStrategy)
5894       */
5895      @FluentSetter
5896      public Builder keepAliveStrategy(ConnectionKeepAliveStrategy keepAliveStrategy) {
5897         httpClientBuilder().setKeepAliveStrategy(keepAliveStrategy);
5898         return this;
5899      }
5900
5901      /**
5902       * Assigns {@link AuthenticationStrategy} instance for target host authentication.
5903       *
5904       * @param targetAuthStrategy New property value.
5905       * @return This object.
5906       * @see HttpClientBuilder#setTargetAuthenticationStrategy(AuthenticationStrategy)
5907       */
5908      @FluentSetter
5909      public Builder targetAuthenticationStrategy(AuthenticationStrategy targetAuthStrategy) {
5910         httpClientBuilder().setTargetAuthenticationStrategy(targetAuthStrategy);
5911         return this;
5912      }
5913
5914      /**
5915       * Assigns {@link AuthenticationStrategy} instance for proxy authentication.
5916       *
5917       * @param proxyAuthStrategy New property value.
5918       * @return This object.
5919       * @see HttpClientBuilder#setProxyAuthenticationStrategy(AuthenticationStrategy)
5920       */
5921      @FluentSetter
5922      public Builder proxyAuthenticationStrategy(AuthenticationStrategy proxyAuthStrategy) {
5923         httpClientBuilder().setProxyAuthenticationStrategy(proxyAuthStrategy);
5924         return this;
5925      }
5926
5927      /**
5928       * Assigns {@link UserTokenHandler} instance.
5929       *
5930       * <h5 class='section'>Notes:</h5><ul>
5931       *    <li class='note'>This value can be overridden by the {@link #disableConnectionState()} method.
5932       * </ul>
5933       *
5934       * @param userTokenHandler New property value.
5935       * @return This object.
5936       * @see HttpClientBuilder#setUserTokenHandler(UserTokenHandler)
5937       */
5938      @FluentSetter
5939      public Builder userTokenHandler(UserTokenHandler userTokenHandler) {
5940         httpClientBuilder().setUserTokenHandler(userTokenHandler);
5941         return this;
5942      }
5943
5944      /**
5945       * Disables connection state tracking.
5946       *
5947       * @return This object.
5948       * @see HttpClientBuilder#disableConnectionState()
5949       */
5950      @FluentSetter
5951      public Builder disableConnectionState() {
5952         httpClientBuilder().disableConnectionState();
5953         return this;
5954      }
5955
5956      /**
5957       * Assigns {@link SchemePortResolver} instance.
5958       *
5959       * @param schemePortResolver New property value.
5960       * @return This object.
5961       * @see HttpClientBuilder#setSchemePortResolver(SchemePortResolver)
5962       */
5963      @FluentSetter
5964      public Builder schemePortResolver(SchemePortResolver schemePortResolver) {
5965         httpClientBuilder().setSchemePortResolver(schemePortResolver);
5966         return this;
5967      }
5968
5969      /**
5970       * Adds this protocol interceptor to the head of the protocol processing list.
5971       *
5972       * <h5 class='section'>Notes:</h5><ul>
5973       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
5974       * </ul>
5975       *
5976       * @param itcp New property value.
5977       * @return This object.
5978       * @see HttpClientBuilder#addInterceptorFirst(HttpResponseInterceptor)
5979       */
5980      @FluentSetter
5981      public Builder addInterceptorFirst(HttpResponseInterceptor itcp) {
5982         httpClientBuilder().addInterceptorFirst(itcp);
5983         return this;
5984      }
5985
5986      /**
5987       * Adds this protocol interceptor to the tail of the protocol processing list.
5988       *
5989       * <h5 class='section'>Notes:</h5><ul>
5990       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
5991       * </ul>
5992       *
5993       * @param itcp New property value.
5994       * @return This object.
5995       * @see HttpClientBuilder#addInterceptorLast(HttpResponseInterceptor)
5996       */
5997      @FluentSetter
5998      public Builder addInterceptorLast(HttpResponseInterceptor itcp) {
5999         httpClientBuilder().addInterceptorLast(itcp);
6000         return this;
6001      }
6002
6003      /**
6004       * Adds this protocol interceptor to the head of the protocol processing list.
6005       *
6006       * <h5 class='section'>Notes:</h5><ul>
6007       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6008       * </ul>
6009       *
6010       * @param itcp New property value.
6011       * @return This object.
6012       * @see HttpClientBuilder#addInterceptorFirst(HttpRequestInterceptor)
6013       */
6014      @FluentSetter
6015      public Builder addInterceptorFirst(HttpRequestInterceptor itcp) {
6016         httpClientBuilder().addInterceptorFirst(itcp);
6017         return this;
6018      }
6019
6020      /**
6021       * Adds this protocol interceptor to the tail of the protocol processing list.
6022       *
6023       * <h5 class='section'>Notes:</h5><ul>
6024       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6025       * </ul>
6026       *
6027       * @param itcp New property value.
6028       * @return This object.
6029       * @see HttpClientBuilder#addInterceptorLast(HttpRequestInterceptor)
6030       */
6031      @FluentSetter
6032      public Builder addInterceptorLast(HttpRequestInterceptor itcp) {
6033         httpClientBuilder().addInterceptorLast(itcp);
6034         return this;
6035      }
6036
6037      /**
6038       * Disables state (cookie) management.
6039       *
6040       * <h5 class='section'>Notes:</h5><ul>
6041       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6042       * </ul>
6043       *
6044       * @return This object.
6045       * @see HttpClientBuilder#disableCookieManagement()
6046       */
6047      @FluentSetter
6048      public Builder disableCookieManagement() {
6049         httpClientBuilder().disableCookieManagement();
6050         return this;
6051      }
6052
6053      /**
6054       * Disables automatic content decompression.
6055       *
6056       * <h5 class='section'>Notes:</h5><ul>
6057       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6058       * </ul>
6059       *
6060       * @return This object.
6061       * @see HttpClientBuilder#disableContentCompression()
6062       */
6063      @FluentSetter
6064      public Builder disableContentCompression() {
6065         httpClientBuilder().disableContentCompression();
6066         return this;
6067      }
6068
6069      /**
6070       * Disables authentication scheme caching.
6071       *
6072       * <h5 class='section'>Notes:</h5><ul>
6073       *    <li class='note'>This value can be overridden by the {@link #httpProcessor(HttpProcessor)} method.
6074       * </ul>
6075       *
6076       * @return This object.
6077       * @see HttpClientBuilder#disableAuthCaching()
6078       */
6079      @FluentSetter
6080      public Builder disableAuthCaching() {
6081         httpClientBuilder().disableAuthCaching();
6082         return this;
6083      }
6084
6085      /**
6086       * Assigns {@link HttpProcessor} instance.
6087       *
6088       * @param httpprocessor New property value.
6089       * @return This object.
6090       * @see HttpClientBuilder#setHttpProcessor(HttpProcessor)
6091       */
6092      @FluentSetter
6093      public Builder httpProcessor(HttpProcessor httpprocessor) {
6094         httpClientBuilder().setHttpProcessor(httpprocessor);
6095         return this;
6096      }
6097
6098      /**
6099       * Assigns {@link HttpRequestRetryHandler} instance.
6100       *
6101       * <h5 class='section'>Notes:</h5><ul>
6102       *    <li class='note'>This value can be overridden by the {@link #disableAutomaticRetries()} method.
6103       * </ul>
6104       *
6105       * @param retryHandler New property value.
6106       * @return This object.
6107       * @see HttpClientBuilder#setRetryHandler(HttpRequestRetryHandler)
6108       */
6109      @FluentSetter
6110      public Builder retryHandler(HttpRequestRetryHandler retryHandler) {
6111         httpClientBuilder().setRetryHandler(retryHandler);
6112         return this;
6113      }
6114
6115      /**
6116       * Disables automatic request recovery and re-execution.
6117       *
6118       * @return This object.
6119       * @see HttpClientBuilder#disableAutomaticRetries()
6120       */
6121      @FluentSetter
6122      public Builder disableAutomaticRetries() {
6123         httpClientBuilder().disableAutomaticRetries();
6124         return this;
6125      }
6126
6127      /**
6128       * Assigns default proxy value.
6129       *
6130       * <h5 class='section'>Notes:</h5><ul>
6131       *    <li class='note'>This value can be overridden by the {@link #routePlanner(HttpRoutePlanner)} method.
6132       * </ul>
6133       *
6134       * @param proxy New property value.
6135       * @return This object.
6136       * @see HttpClientBuilder#setProxy(HttpHost)
6137       */
6138      @FluentSetter
6139      public Builder proxy(HttpHost proxy) {
6140         httpClientBuilder().setProxy(proxy);
6141         return this;
6142      }
6143
6144      /**
6145       * Assigns {@link HttpRoutePlanner} instance.
6146       *
6147       * @param routePlanner New property value.
6148       * @return This object.
6149       * @see HttpClientBuilder#setRoutePlanner(HttpRoutePlanner)
6150       */
6151      @FluentSetter
6152      public Builder routePlanner(HttpRoutePlanner routePlanner) {
6153         httpClientBuilder().setRoutePlanner(routePlanner);
6154         return this;
6155      }
6156
6157      /**
6158       * Assigns {@link ConnectionBackoffStrategy} instance.
6159       *
6160       * @param connectionBackoffStrategy New property value.
6161       * @return This object.
6162       * @see HttpClientBuilder#setConnectionBackoffStrategy(ConnectionBackoffStrategy)
6163       */
6164      @FluentSetter
6165      public Builder connectionBackoffStrategy(ConnectionBackoffStrategy connectionBackoffStrategy) {
6166         httpClientBuilder().setConnectionBackoffStrategy(connectionBackoffStrategy);
6167         return this;
6168      }
6169
6170      /**
6171       * Assigns {@link BackoffManager} instance.
6172       *
6173       * @param backoffManager New property value.
6174       * @return This object.
6175       * @see HttpClientBuilder#setBackoffManager(BackoffManager)
6176       */
6177      @FluentSetter
6178      public Builder backoffManager(BackoffManager backoffManager) {
6179         httpClientBuilder().setBackoffManager(backoffManager);
6180         return this;
6181      }
6182
6183      /**
6184       * Assigns {@link ServiceUnavailableRetryStrategy} instance.
6185       *
6186       * @param serviceUnavailStrategy New property value.
6187       * @return This object.
6188       * @see HttpClientBuilder#setServiceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy)
6189       */
6190      @FluentSetter
6191      public Builder serviceUnavailableRetryStrategy(ServiceUnavailableRetryStrategy serviceUnavailStrategy) {
6192         httpClientBuilder().setServiceUnavailableRetryStrategy(serviceUnavailStrategy);
6193         return this;
6194      }
6195
6196      /**
6197       * Assigns default {@link CookieStore} instance which will be used for request execution if not explicitly set in the client execution context.
6198       *
6199       * @param cookieStore New property value.
6200       * @return This object.
6201       * @see HttpClientBuilder#setDefaultCookieStore(CookieStore)
6202       */
6203      @FluentSetter
6204      public Builder defaultCookieStore(CookieStore cookieStore) {
6205         httpClientBuilder().setDefaultCookieStore(cookieStore);
6206         return this;
6207      }
6208
6209      /**
6210       * Assigns default {@link CredentialsProvider} instance which will be used for request execution if not explicitly set in the client execution context.
6211       *
6212       * @param credentialsProvider New property value.
6213       * @return This object.
6214       * @see HttpClientBuilder#setDefaultCredentialsProvider(CredentialsProvider)
6215       */
6216      @FluentSetter
6217      public Builder defaultCredentialsProvider(CredentialsProvider credentialsProvider) {
6218         httpClientBuilder().setDefaultCredentialsProvider(credentialsProvider);
6219         return this;
6220      }
6221
6222      /**
6223       * Assigns default {@link org.apache.http.auth.AuthScheme} registry which will be used for request execution if not explicitly set in the client execution context.
6224       *
6225       * @param authSchemeRegistry New property value.
6226       * @return This object.
6227       * @see HttpClientBuilder#setDefaultAuthSchemeRegistry(Lookup)
6228       */
6229      @FluentSetter
6230      public Builder defaultAuthSchemeRegistry(Lookup<AuthSchemeProvider> authSchemeRegistry) {
6231         httpClientBuilder().setDefaultAuthSchemeRegistry(authSchemeRegistry);
6232         return this;
6233      }
6234
6235      /**
6236       * Assigns a map of {@link org.apache.http.client.entity.InputStreamFactory InputStreamFactories} to be used for automatic content decompression.
6237       *
6238       * @param contentDecoderMap New property value.
6239       * @return This object.
6240       * @see HttpClientBuilder#setContentDecoderRegistry(Map)
6241       */
6242      @FluentSetter
6243      public Builder contentDecoderRegistry(Map<String,InputStreamFactory> contentDecoderMap) {
6244         httpClientBuilder().setContentDecoderRegistry(contentDecoderMap);
6245         return this;
6246      }
6247
6248      /**
6249       * Assigns default {@link RequestConfig} instance which will be used for request execution if not explicitly set in the client execution context.
6250       *
6251       * @param config New property value.
6252       * @return This object.
6253       * @see HttpClientBuilder#setDefaultRequestConfig(RequestConfig)
6254       */
6255      @FluentSetter
6256      public Builder defaultRequestConfig(RequestConfig config) {
6257         httpClientBuilder().setDefaultRequestConfig(config);
6258         return this;
6259      }
6260
6261      /**
6262       * Use system properties when creating and configuring default implementations.
6263       *
6264       * @return This object.
6265       * @see HttpClientBuilder#useSystemProperties()
6266       */
6267      @FluentSetter
6268      public Builder useSystemProperties() {
6269         httpClientBuilder().useSystemProperties();
6270         return this;
6271      }
6272
6273      /**
6274       * Makes this instance of {@link HttpClient} proactively evict expired connections from the connection pool using a background thread.
6275       *
6276       * <h5 class='section'>Notes:</h5><ul>
6277       *    <li class='note'>One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order to stop and release the background thread.
6278       *    <li class='note'>This method has no effect if the instance of {@link HttpClient} is configured to use a shared connection manager.
6279       *    <li class='note'>This method may not be used when the instance of {@link HttpClient} is created inside an EJB container.
6280       * </ul>
6281       *
6282       * @return This object.
6283       * @see HttpClientBuilder#evictExpiredConnections()
6284       */
6285      @FluentSetter
6286      public Builder evictExpiredConnections() {
6287         httpClientBuilder().evictExpiredConnections();
6288         return this;
6289      }
6290
6291      /**
6292       * Makes this instance of {@link HttpClient} proactively evict idle connections from the connection pool using a background thread.
6293       *
6294       * <h5 class='section'>Notes:</h5><ul>
6295       *    <li class='note'>One MUST explicitly close HttpClient with {@link CloseableHttpClient#close()} in order to stop and release the background thread.
6296       *    <li class='note'>This method has no effect if the instance of {@link HttpClient} is configured to use a shared connection manager.
6297       *    <li class='note'>This method may not be used when the instance of {@link HttpClient} is created inside an EJB container.
6298       * </ul>
6299       *
6300       * @param maxIdleTime New property value.
6301       * @param maxIdleTimeUnit New property value.
6302       * @return This object.
6303       * @see HttpClientBuilder#evictIdleConnections(long,TimeUnit)
6304       */
6305      @FluentSetter
6306      public Builder evictIdleConnections(long maxIdleTime, TimeUnit maxIdleTimeUnit) {
6307         httpClientBuilder().evictIdleConnections(maxIdleTime, maxIdleTimeUnit);
6308         return this;
6309      }
6310   }
6311
6312   //-------------------------------------------------------------------------------------------------------------------
6313   // Instance
6314   //-------------------------------------------------------------------------------------------------------------------
6315
6316   final HeaderList headerData;
6317   final PartList queryData, formData, pathData;
6318   final CloseableHttpClient httpClient;
6319
6320   private final HttpClientConnectionManager connectionManager;
6321   private final boolean keepHttpClientOpen, detectLeaks, skipEmptyHeaderData, skipEmptyQueryData, skipEmptyFormData;
6322   private final BeanStore beanStore;
6323   private final UrlEncodingSerializer urlEncodingSerializer;  // Used for form posts only.
6324   final HttpPartSerializer partSerializer;
6325   final HttpPartParser partParser;
6326   private final RestCallHandler callHandler;
6327   private final String rootUrl;
6328   private volatile boolean isClosed = false;
6329   private final StackTraceElement[] creationStack;
6330   private final Logger logger;
6331   final DetailLevel logRequests;
6332   final BiPredicate<RestRequest,RestResponse> logRequestsPredicate;
6333   final Level logRequestsLevel;
6334   final boolean ignoreErrors;
6335   private final boolean logToConsole;
6336   private final PrintStream console;
6337   private StackTraceElement[] closedStack;
6338   private static final ConcurrentHashMap<Class<?>,Context> requestContexts = new ConcurrentHashMap<>();
6339
6340   // These are read directly by RestCall.
6341   final SerializerSet serializers;
6342   final ParserSet parsers;
6343   Predicate<Integer> errorCodes;
6344
6345   final RestCallInterceptor[] interceptors;
6346
6347   private final Map<Class<?>, HttpPartParser> partParsers = new ConcurrentHashMap<>();
6348   private final Map<Class<?>, HttpPartSerializer> partSerializers = new ConcurrentHashMap<>();
6349
6350   // This is lazy-created.
6351   private volatile ExecutorService executorService;
6352   private final boolean executorServiceShutdownOnClose;
6353
6354   private static final
6355      BiPredicate<RestRequest,RestResponse> LOG_REQUESTS_PREDICATE_DEFAULT = (req,res) -> true;
6356
6357   /**
6358    * Constructor.
6359    *
6360    * @param builder The builder for this client.
6361    */
6362   public RestClient(Builder builder) {
6363      super(builder);
6364
6365      beanStore = builder.beanStore
6366         .addBean(RestClient.class, this);
6367
6368      httpClient = builder.getHttpClient();
6369      headerData = builder.headers().copy();
6370      queryData = builder.queryData().copy();
6371      formData = builder.formData().copy();
6372      pathData = builder.pathData().copy();
6373      callHandler = builder.callHandler().run();
6374      skipEmptyHeaderData = builder.skipEmptyHeaderData;
6375      skipEmptyQueryData = builder.skipEmptyQueryData;
6376      skipEmptyFormData = builder.skipEmptyFormData;
6377      rootUrl = builder.rootUrl;
6378      errorCodes = builder.errorCodes;
6379      connectionManager = builder.connectionManager;
6380      console = builder.console != null ? builder.console : System.err;
6381      executorService = builder.executorService;
6382      executorServiceShutdownOnClose = builder.executorServiceShutdownOnClose;
6383      ignoreErrors = builder.ignoreErrors;
6384      keepHttpClientOpen = builder.keepHttpClientOpen;
6385      detectLeaks = builder.detectLeaks;
6386      logger = builder.logger != null ? builder.logger : Logger.getLogger(RestClient.class.getName());
6387      logToConsole = builder.logToConsole || isDebug();
6388      logRequests = builder.logRequests != null ? builder.logRequests : isDebug() ? DetailLevel.FULL : DetailLevel.NONE;
6389      logRequestsLevel = builder.logRequestsLevel != null ? builder.logRequestsLevel : isDebug() ? Level.WARNING : Level.OFF;
6390      logRequestsPredicate = builder.logRequestsPredicate != null ? builder.logRequestsPredicate : LOG_REQUESTS_PREDICATE_DEFAULT;
6391      interceptors = builder.interceptors != null ? builder.interceptors.toArray(EMPTY_REST_CALL_INTERCEPTORS) : EMPTY_REST_CALL_INTERCEPTORS;
6392      serializers = builder.serializers().build();
6393      parsers = builder.parsers().build();
6394      partSerializer = builder.partSerializer().create();
6395      partParser = builder.partParser().create();
6396      urlEncodingSerializer = builder.urlEncodingSerializer().build();
6397      creationStack = isDebug() ? Thread.currentThread().getStackTrace() : null;
6398
6399      init();
6400   }
6401
6402   @Override /* Context */
6403   public Builder copy() {
6404      throw new NoSuchMethodError("Not implemented.");
6405   }
6406
6407   /**
6408    * Perform optional initialization on builder before it is used.
6409    *
6410    * <p>
6411    * Default behavior is a no-op.
6412    *
6413    * @param builder The builder to initialize.
6414    */
6415   protected void init(RestClient.Builder builder) {}
6416
6417   /**
6418    * Gets called add the end of the constructor call to perform any post-initialization.
6419    */
6420   protected void init() {
6421   }
6422
6423   /**
6424    * Calls {@link CloseableHttpClient#close()} on the underlying {@link CloseableHttpClient}.
6425    *
6426    * <p>
6427    * It's good practice to call this method after the client is no longer used.
6428    *
6429    * @throws IOException Thrown by underlying stream.
6430    */
6431   @Override
6432   public void close() throws IOException {
6433      isClosed = true;
6434      if (! keepHttpClientOpen)
6435         httpClient.close();
6436      if (executorService != null && executorServiceShutdownOnClose)
6437         executorService.shutdown();
6438      if (creationStack != null)
6439         closedStack = Thread.currentThread().getStackTrace();
6440   }
6441
6442   /**
6443    * Same as {@link #close()}, but ignores any exceptions.
6444    */
6445   public void closeQuietly() {
6446      isClosed = true;
6447      try {
6448         if (! keepHttpClientOpen)
6449            httpClient.close();
6450         if (executorService != null && executorServiceShutdownOnClose)
6451            executorService.shutdown();
6452      } catch (Throwable t) {}
6453      if (creationStack != null)
6454         closedStack = Thread.currentThread().getStackTrace();
6455   }
6456
6457   /**
6458    * Entrypoint for executing all requests and returning a response.
6459    *
6460    * <p>
6461    * Subclasses can override this method to provide specialized handling.
6462    *
6463    * <p>
6464    * The behavior of this method can also be modified by specifying a different {@link RestCallHandler}.
6465    *
6466    * <h5 class='section'>See Also:</h5><ul>
6467    *    <li class='jm'>{@link Builder#callHandler()}
6468    * </ul>
6469    *
6470    * @param target The target host for the request.
6471    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
6472    *       target or by inspecting the request.
6473    * @param request The request to execute.
6474    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
6475    * @return
6476    *    The response to the request.
6477    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
6478    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
6479    *       implementation and configuration of this client.
6480    * @throws IOException In case of a problem or the connection was aborted.
6481    * @throws ClientProtocolException In case of an http protocol error.
6482    */
6483   protected HttpResponse run(HttpHost target, HttpRequest request, HttpContext context) throws ClientProtocolException, IOException {
6484      return callHandler.run(target, request, context);
6485   }
6486
6487   /**
6488    * Perform a <c>GET</c> request against the specified URI.
6489    *
6490    * @param uri
6491    *    The URI of the remote REST resource.
6492    *    <br>Can be any of the following types:
6493    *    <ul>
6494    *       <li>{@link URIBuilder}
6495    *       <li>{@link URI}
6496    *       <li>{@link URL}
6497    *       <li>{@link String}
6498    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6499    *    </ul>
6500    * @return
6501    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6502    *    as a parsed object.
6503    * @throws RestCallException If any authentication errors occurred.
6504    */
6505   public RestRequest get(Object uri) throws RestCallException {
6506      return request(op("GET", uri, NO_BODY));
6507   }
6508
6509   /**
6510    * Perform a <c>GET</c> request against the root URI.
6511    *
6512    * @return
6513    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6514    *    as a parsed object.
6515    * @throws RestCallException If any authentication errors occurred.
6516    */
6517   public RestRequest get() throws RestCallException {
6518      return request(op("GET", null, NO_BODY));
6519   }
6520
6521   /**
6522    * Perform a <c>PUT</c> request against the specified URI.
6523    *
6524    * @param uri
6525    *    The URI of the remote REST resource.
6526    *    <br>Can be any of the following types:
6527    *    <ul>
6528    *       <li>{@link URIBuilder}
6529    *       <li>{@link URI}
6530    *       <li>{@link URL}
6531    *       <li>{@link String}
6532    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6533    *    </ul>
6534    * @param body
6535    *    The object to serialize and transmit to the URI as the body of the request.
6536    *    Can be of the following types:
6537    *    <ul class='spaced-list'>
6538    *       <li>
6539    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6540    *       <li>
6541    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6542    *       <li>
6543    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6544    *          {@link RestClient}.
6545    *       <li>
6546    *          {@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6547    *       <li>
6548    *          {@link PartList} - Converted to a URL-encoded FORM post.
6549    *       <li>
6550    *          {@link Supplier} - A supplier of anything on this list.
6551    *    </ul>
6552    * @return
6553    *    A {@link RestRequest} object that can be further tailored before executing the request
6554    *    and getting the response as a parsed object.
6555    * @throws RestCallException If any authentication errors occurred.
6556    */
6557   public RestRequest put(Object uri, Object body) throws RestCallException {
6558      return request(op("PUT", uri, body));
6559   }
6560
6561   /**
6562    * Perform a <c>PUT</c> request against the specified URI using a plain text body bypassing the serializer.
6563    *
6564    * @param uri
6565    *    The URI of the remote REST resource.
6566    *    <br>Can be any of the following types:
6567    *    <ul>
6568    *       <li>{@link URIBuilder}
6569    *       <li>{@link URI}
6570    *       <li>{@link URL}
6571    *       <li>{@link String}
6572    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6573    *    </ul>
6574    * @param body
6575    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6576    * @param contentType The content type of the request.
6577    * @return
6578    *    A {@link RestRequest} object that can be further tailored before executing the request
6579    *    and getting the response as a parsed object.
6580    * @throws RestCallException If any authentication errors occurred.
6581    */
6582   public RestRequest put(Object uri, String body, ContentType contentType) throws RestCallException {
6583      return request(op("PUT", uri, stringBody(body))).header(contentType);
6584   }
6585
6586   /**
6587    * Same as {@link #put(Object, Object)} but don't specify the input yet.
6588    *
6589    * <p>
6590    * You must call either {@link RestRequest#content(Object)} or {@link RestRequest#formData(String, Object)}
6591    * to set the contents on the result object.
6592    *
6593    * @param uri
6594    *    The URI of the remote REST resource.
6595    *    <br>Can be any of the following types:
6596    *    <ul>
6597    *       <li>{@link URIBuilder}
6598    *       <li>{@link URI}
6599    *       <li>{@link URL}
6600    *       <li>{@link String}
6601    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6602    *    </ul>
6603    * @return
6604    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6605    *    as a parsed object.
6606    * @throws RestCallException REST call failed.
6607    */
6608   public RestRequest put(Object uri) throws RestCallException {
6609      return request(op("PUT", uri, NO_BODY));
6610   }
6611
6612   /**
6613    * Perform a <c>POST</c> request against the specified URI.
6614    *
6615    * <h5 class='section'>Notes:</h5><ul>
6616    *    <li class='note'>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
6617    * </ul>
6618    *
6619    * @param uri
6620    *    The URI of the remote REST resource.
6621    *    <br>Can be any of the following types:
6622    *    <ul>
6623    *       <li>{@link URIBuilder}
6624    *       <li>{@link URI}
6625    *       <li>{@link URL}
6626    *       <li>{@link String}
6627    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6628    *    </ul>
6629    * @param body
6630    *    The object to serialize and transmit to the URI as the body of the request.
6631    *    Can be of the following types:
6632    *    <ul class='spaced-list'>
6633    *       <li>
6634    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6635    *       <li>
6636    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6637    *       <li>
6638    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6639    *          {@link RestClient}.
6640    *       <li>
6641    *          {@link HttpEntity} / {@link HttpResource} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6642    *       <li>
6643    *          {@link PartList} - Converted to a URL-encoded FORM post.
6644    *       <li>
6645    *          {@link Supplier} - A supplier of anything on this list.
6646    *    </ul>
6647    * @return
6648    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6649    *    as a parsed object.
6650    * @throws RestCallException If any authentication errors occurred.
6651    */
6652   public RestRequest post(Object uri, Object body) throws RestCallException {
6653      return request(op("POST", uri, body));
6654   }
6655
6656   /**
6657    * Perform a <c>POST</c> request against the specified URI as a plain text body bypassing the serializer.
6658    *
6659    * @param uri
6660    *    The URI of the remote REST resource.
6661    *    <br>Can be any of the following types:
6662    *    <ul>
6663    *       <li>{@link URIBuilder}
6664    *       <li>{@link URI}
6665    *       <li>{@link URL}
6666    *       <li>{@link String}
6667    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6668    *    </ul>
6669    * @param body
6670    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6671    * @param contentType
6672    *    The content type of the request.
6673    * @return
6674    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6675    *    as a parsed object.
6676    * @throws RestCallException If any authentication errors occurred.
6677    */
6678   public RestRequest post(Object uri, String body, ContentType contentType) throws RestCallException {
6679      return request(op("POST", uri, stringBody(body))).header(contentType);
6680   }
6681
6682   /**
6683    * Same as {@link #post(Object, Object)} but don't specify the input yet.
6684    *
6685    * <p>
6686    * You must call either {@link RestRequest#content(Object)} or {@link RestRequest#formData(String, Object)} to set the
6687    * contents on the result object.
6688    *
6689    * <h5 class='section'>Notes:</h5><ul>
6690    *    <li class='note'>Use {@link #formPost(Object, Object)} for <c>application/x-www-form-urlencoded</c> form posts.
6691    * </ul>
6692    *
6693    * @param uri
6694    *    The URI of the remote REST resource.
6695    *    <br>Can be any of the following types:
6696    *    <ul>
6697    *       <li>{@link URIBuilder}
6698    *       <li>{@link URI}
6699    *       <li>{@link URL}
6700    *       <li>{@link String}
6701    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6702    *    </ul>
6703    * @return
6704    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6705    *    as a parsed object.
6706    * @throws RestCallException REST call failed.
6707    */
6708   public RestRequest post(Object uri) throws RestCallException {
6709      return request(op("POST", uri, NO_BODY));
6710   }
6711
6712   /**
6713    * Perform a <c>DELETE</c> request against the specified URI.
6714    *
6715    * @param uri
6716    *    The URI of the remote REST resource.
6717    *    <br>Can be any of the following types:
6718    *    <ul>
6719    *       <li>{@link URIBuilder}
6720    *       <li>{@link URI}
6721    *       <li>{@link URL}
6722    *       <li>{@link String}
6723    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6724    *    </ul>
6725    * @return
6726    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6727    *    as a parsed object.
6728    * @throws RestCallException If any authentication errors occurred.
6729    */
6730   public RestRequest delete(Object uri) throws RestCallException {
6731      return request(op("DELETE", uri, NO_BODY));
6732   }
6733
6734   /**
6735    * Perform an <c>OPTIONS</c> request against the specified URI.
6736    *
6737    * @param uri
6738    *    The URI of the remote REST resource.
6739    *    <br>Can be any of the following types:
6740    *    <ul>
6741    *       <li>{@link URIBuilder}
6742    *       <li>{@link URI}
6743    *       <li>{@link URL}
6744    *       <li>{@link String}
6745    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6746    *    </ul>
6747    * @return
6748    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6749    *    as a parsed object.
6750    * @throws RestCallException If any authentication errors occurred.
6751    */
6752   public RestRequest options(Object uri) throws RestCallException {
6753      return request(op("OPTIONS", uri, NO_BODY));
6754   }
6755
6756   /**
6757    * Perform a <c>HEAD</c> request against the specified URI.
6758    *
6759    * @param uri
6760    *    The URI of the remote REST resource.
6761    *    <br>Can be any of the following types:
6762    *    <ul>
6763    *       <li>{@link URIBuilder}
6764    *       <li>{@link URI}
6765    *       <li>{@link URL}
6766    *       <li>{@link String}
6767    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6768    *    </ul>
6769    * @return
6770    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6771    *    as a parsed object.
6772    * @throws RestCallException If any authentication errors occurred.
6773    */
6774   public RestRequest head(Object uri) throws RestCallException {
6775      return request(op("HEAD", uri, NO_BODY));
6776   }
6777
6778   /**
6779    * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
6780    * against the specified URI.
6781    *
6782    * @param uri
6783    *    The URI of the remote REST resource.
6784    *    <br>Can be any of the following types:
6785    *    <ul>
6786    *       <li>{@link URIBuilder}
6787    *       <li>{@link URI}
6788    *       <li>{@link URL}
6789    *       <li>{@link String}
6790    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6791    *    </ul>
6792    * @param body
6793    *    The object to serialize and transmit to the URI as the body of the request.
6794    *    <ul class='spaced-list'>
6795    *       <li>{@link NameValuePair} - URL-encoded as a single name-value pair.
6796    *       <li>{@link NameValuePair} array - URL-encoded as name value pairs.
6797    *       <li>{@link PartList} - URL-encoded as name value pairs.
6798    *       <li>{@link Reader}/{@link InputStream}- Streamed directly and <l>Content-Type</l> set to <js>"application/x-www-form-urlencoded"</js>
6799    *       <li>{@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
6800    *       <li>{@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6801    *       <li>{@link Object} - Converted to a {@link SerializedEntity} using {@link UrlEncodingSerializer} to serialize.
6802    *       <li>{@link Supplier} - A supplier of anything on this list.
6803    *    </ul>
6804    * @return
6805    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6806    *    as a parsed object.
6807    * @throws RestCallException If any authentication errors occurred.
6808    */
6809   public RestRequest formPost(Object uri, Object body) throws RestCallException {
6810      RestRequest req = request(op("POST", uri, NO_BODY));
6811      try {
6812         if (body instanceof Supplier)
6813            body = ((Supplier<?>)body).get();
6814         if (body instanceof NameValuePair)
6815            return req.content(new UrlEncodedFormEntity(alist((NameValuePair)body)));
6816         if (body instanceof NameValuePair[])
6817            return req.content(new UrlEncodedFormEntity(alist((NameValuePair[])body)));
6818         if (body instanceof PartList)
6819            return req.content(new UrlEncodedFormEntity(((PartList)body)));
6820         if (body instanceof HttpResource)
6821            ((HttpResource)body).getHeaders().forEach(x-> req.header(x));
6822         if (body instanceof HttpEntity) {
6823            HttpEntity e = (HttpEntity)body;
6824            if (e.getContentType() == null)
6825               req.header(ContentType.APPLICATION_FORM_URLENCODED);
6826            return req.content(e);
6827         }
6828         if (body instanceof Reader || body instanceof InputStream)
6829            return req.header(ContentType.APPLICATION_FORM_URLENCODED).content(body);
6830         return req.content(serializedEntity(body, urlEncodingSerializer, null));
6831      } catch (IOException e) {
6832         throw new RestCallException(null, e, "Could not read form post body.");
6833      }
6834   }
6835
6836   /**
6837    * Same as {@link #formPost(Object, Object)} but doesn't specify the input yet.
6838    *
6839    * @param uri
6840    *    The URI of the remote REST resource.
6841    *    <br>Can be any of the following types:
6842    *    <ul>
6843    *       <li>{@link URIBuilder}
6844    *       <li>{@link URI}
6845    *       <li>{@link URL}
6846    *       <li>{@link String}
6847    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6848    *    </ul>
6849    * @return
6850    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6851    *    as a parsed object.
6852    * @throws RestCallException If any authentication errors occurred.
6853    */
6854   public RestRequest formPost(Object uri) throws RestCallException {
6855      return request(op("POST", uri, NO_BODY));
6856   }
6857
6858   /**
6859    * Perform a <c>POST</c> request with a content type of <c>application/x-www-form-urlencoded</c>
6860    * against the specified URI.
6861    *
6862    * @param uri
6863    *    The URI of the remote REST resource.
6864    *    <br>Can be any of the following types:
6865    *    <ul>
6866    *       <li>{@link URIBuilder}
6867    *       <li>{@link URI}
6868    *       <li>{@link URL}
6869    *       <li>{@link String}
6870    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6871    *    </ul>
6872    * @param parameters
6873    *    The parameters of the form post.
6874    *    <br>The parameters represent name/value pairs and must be an even number of arguments.
6875    *    <br>Parameters are converted to {@link BasicPart} objects.
6876    * @return
6877    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6878    *    as a parsed object.
6879    * @throws RestCallException If any authentication errors occurred.
6880    */
6881   public RestRequest formPostPairs(Object uri, String...parameters) throws RestCallException {
6882      return formPost(uri, partList(parameters));
6883   }
6884
6885   /**
6886    * Perform a <c>PATCH</c> request against the specified URI.
6887    *
6888    * @param uri
6889    *    The URI of the remote REST resource.
6890    *    <br>Can be any of the following types:
6891    *    <ul>
6892    *       <li>{@link URIBuilder}
6893    *       <li>{@link URI}
6894    *       <li>{@link URL}
6895    *       <li>{@link String}
6896    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6897    *    </ul>
6898    * @param body
6899    *    The object to serialize and transmit to the URI as the body of the request.
6900    *    Can be of the following types:
6901    *    <ul class='spaced-list'>
6902    *       <li>
6903    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
6904    *       <li>
6905    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
6906    *       <li>
6907    *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
6908    *       <li>
6909    *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
6910    *       <li>
6911    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
6912    *          {@link RestClient}.
6913    *       <li>
6914    *          {@link PartList} - Converted to a URL-encoded FORM post.
6915    *       <li>
6916    *          {@link Supplier} - A supplier of anything on this list.
6917    *    </ul>
6918    * @return
6919    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6920    *    as a parsed object.
6921    * @throws RestCallException If any authentication errors occurred.
6922    */
6923   public RestRequest patch(Object uri, Object body) throws RestCallException {
6924      return request(op("PATCH", uri, body));
6925   }
6926
6927   /**
6928    * Perform a <c>PATCH</c> request against the specified URI as a plain text body bypassing the serializer.
6929    *
6930    * @param uri
6931    *    The URI of the remote REST resource.
6932    *    <br>Can be any of the following types:
6933    *    <ul>
6934    *       <li>{@link URIBuilder}
6935    *       <li>{@link URI}
6936    *       <li>{@link URL}
6937    *       <li>{@link String}
6938    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6939    *    </ul>
6940    * @param body
6941    *    The object to serialize and transmit to the URI as the body of the request bypassing the serializer.
6942    * @param contentType
6943    *    The content type of the request.
6944    * @return
6945    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6946    *    as a parsed object.
6947    * @throws RestCallException If any authentication errors occurred.
6948    */
6949   public RestRequest patch(Object uri, String body, ContentType contentType) throws RestCallException {
6950      return request(op("PATCH", uri, stringBody(body))).header(contentType);
6951   }
6952
6953   /**
6954    * Same as {@link #patch(Object, Object)} but don't specify the input yet.
6955    *
6956    * <p>
6957    * You must call {@link RestRequest#content(Object)} to set the contents on the result object.
6958    *
6959    * @param uri
6960    *    The URI of the remote REST resource.
6961    *    <br>Can be any of the following types:
6962    *    <ul>
6963    *       <li>{@link URIBuilder}
6964    *       <li>{@link URI}
6965    *       <li>{@link URL}
6966    *       <li>{@link String}
6967    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
6968    *    </ul>
6969    * @return
6970    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
6971    *    as a parsed object.
6972    * @throws RestCallException REST call failed.
6973    */
6974   public RestRequest patch(Object uri) throws RestCallException {
6975      return request(op("PATCH", uri, NO_BODY));
6976   }
6977
6978
6979   /**
6980    * Performs a REST call where the entire call is specified in a simple string.
6981    *
6982    * <p>
6983    * This method is useful for performing callbacks when the target of a callback is passed in
6984    * on an initial request, for example to signal when a long-running process has completed.
6985    *
6986    * <p>
6987    * The call string can be any of the following formats:
6988    * <ul class='spaced-list'>
6989    *    <li>
6990    *       <js>"[method] [uri]"</js> - e.g. <js>"GET http://localhost/callback"</js>
6991    *    <li>
6992    *       <js>"[method] [uri] [payload]"</js> - e.g. <js>"POST http://localhost/callback some text payload"</js>
6993    *    <li>
6994    *       <js>"[method] [headers] [uri] [payload]"</js> - e.g. <js>"POST {'Content-Type':'text/json'} http://localhost/callback {'some':'json'}"</js>
6995    * </ul>
6996    * <p>
6997    * The payload will always be sent using a simple {@link StringEntity}.
6998    *
6999    * @param callString The call string.
7000    * @return
7001    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7002    *    as a parsed object.
7003    * @throws RestCallException REST call failed.
7004    */
7005   public RestRequest callback(String callString) throws RestCallException {
7006      callString = emptyIfNull(callString);
7007
7008      // S01 - Looking for end of method.
7009      // S02 - Found end of method, looking for beginning of URI or headers.
7010      // S03 - Found beginning of headers, looking for end of headers.
7011      // S04 - Found end of headers, looking for beginning of URI.
7012      // S05 - Found beginning of URI, looking for end of URI.
7013
7014      StateMachineState state = S01;
7015
7016      int mark = 0;
7017      String method = null, headers = null, uri = null, content = null;
7018      for (int i = 0; i < callString.length(); i++) {
7019         char c = callString.charAt(i);
7020         if (state == S01) {
7021            if (isWhitespace(c)) {
7022               method = callString.substring(mark, i);
7023               state = S02;
7024            }
7025         } else if (state == S02) {
7026            if (! isWhitespace(c)) {
7027               mark = i;
7028               if (c == '{')
7029                  state = S03;
7030               else
7031                  state = S05;
7032            }
7033         } else if (state == S03) {
7034            if (c == '}') {
7035               headers = callString.substring(mark, i+1);
7036               state = S04;
7037            }
7038         } else if (state == S04) {
7039            if (! isWhitespace(c)) {
7040               mark = i;
7041               state = S05;
7042            }
7043         } else /* (state == S05) */ {
7044            if (isWhitespace(c)) {
7045               uri = callString.substring(mark, i);
7046               content = callString.substring(i).trim();
7047               break;
7048            }
7049         }
7050      }
7051
7052      if (state != S05)
7053         throw new RestCallException(null, null, "Invalid format for call string.  State={0}", state);
7054
7055      try {
7056         RestRequest req = request(method, uri, isNotEmpty(content));
7057         if (headers != null)
7058            JsonMap.ofJson(headers).forEach((k,v) -> req.header(stringHeader(k, stringify(v))));
7059         if (isNotEmpty(content))
7060            req.contentString(content);
7061         return req;
7062      } catch (ParseException e) {
7063         throw new RestCallException(null, e, "Invalid format for call string.");
7064      }
7065   }
7066
7067   /**
7068    * Perform a generic REST call.
7069    *
7070    * @param method The HTTP method.
7071    * @param uri
7072    *    The URI of the remote REST resource.
7073    *    <br>Can be any of the following types:
7074    *    <ul>
7075    *       <li>{@link URIBuilder}
7076    *       <li>{@link URI}
7077    *       <li>{@link URL}
7078    *       <li>{@link String}
7079    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7080    *    </ul>
7081    * @param body
7082    *    The HTTP body content.
7083    *    Can be of the following types:
7084    *    <ul class='spaced-list'>
7085    *       <li>
7086    *          {@link Reader} - Raw contents of {@code Reader} will be serialized to remote resource.
7087    *       <li>
7088    *          {@link InputStream} - Raw contents of {@code InputStream} will be serialized to remote resource.
7089    *       <li>
7090    *          {@link HttpResource} - Raw contents will be serialized to remote resource.  Additional headers and media type will be set on request.
7091    *       <li>
7092    *          {@link HttpEntity} - Bypass Juneau serialization and pass HttpEntity directly to HttpClient.
7093    *       <li>
7094    *          {@link Object} - POJO to be converted to text using the {@link Serializer} registered with the
7095    *          {@link RestClient}.
7096    *       <li>
7097    *          {@link PartList} - Converted to a URL-encoded FORM post.
7098    *       <li>
7099    *          {@link Supplier} - A supplier of anything on this list.
7100    *    </ul>
7101    *    This parameter is IGNORED if the method type normally does not have content.
7102    * @return
7103    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7104    *    as a parsed object.
7105    * @throws RestCallException If any authentication errors occurred.
7106    */
7107   public RestRequest request(String method, Object uri, Object body) throws RestCallException {
7108      return request(op(method, uri, body));
7109   }
7110
7111   /**
7112    * Perform a generic REST call.
7113    *
7114    * @param method The HTTP method.
7115    * @param uri
7116    *    The URI of the remote REST resource.
7117    *    <br>Can be any of the following types:
7118    *    <ul>
7119    *       <li>{@link URIBuilder}
7120    *       <li>{@link URI}
7121    *       <li>{@link URL}
7122    *       <li>{@link String}
7123    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7124    *    </ul>
7125    * @return
7126    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7127    *    as a parsed object.
7128    * @throws RestCallException If any authentication errors occurred.
7129    */
7130   public RestRequest request(String method, Object uri) throws RestCallException {
7131      return request(op(method, uri, NO_BODY));
7132   }
7133
7134   /**
7135    * Perform a generic REST call.
7136    *
7137    * <p>
7138    * Typically you're going to use {@link #request(String, Object)} or {@link #request(String, Object, Object)},
7139    * but this method is provided to allow you to perform non-standard HTTP methods (e.g. HTTP FOO).
7140    *
7141    * @param method The method name (e.g. <js>"GET"</js>, <js>"OPTIONS"</js>).
7142    * @param uri
7143    *    The URI of the remote REST resource.
7144    *    <br>Can be any of the following types:
7145    *    <ul>
7146    *       <li>{@link URIBuilder}
7147    *       <li>{@link URI}
7148    *       <li>{@link URL}
7149    *       <li>{@link String}
7150    *       <li>{@link Object} - Converted to <c>String</c> using <c>toString()</c>
7151    *    </ul>
7152    * @param hasBody Boolean flag indicating if the specified request has content associated with it.
7153    * @return
7154    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7155    *    as a parsed object.
7156    * @throws RestCallException If any authentication errors occurred.
7157    */
7158   public RestRequest request(String method, Object uri, boolean hasBody) throws RestCallException {
7159      return request(op(method, uri, NO_BODY).hasContent(hasBody));
7160   }
7161
7162   /**
7163    * Perform an arbitrary request against the specified URI.
7164    *
7165    * <p>
7166    * All requests feed through this method so it can be used to intercept request creations and make modifications
7167    * (such as add headers).
7168    *
7169    * @param op The operation that identifies the HTTP method, URL, and optional payload.
7170    * @return
7171    *    A {@link RestRequest} object that can be further tailored before executing the request and getting the response
7172    *    as a parsed object.
7173    * @throws RestCallException If any authentication errors occurred.
7174    */
7175   protected RestRequest request(RestOperation op) throws RestCallException {
7176      if (isClosed) {
7177         Exception e2 = null;
7178         if (closedStack != null) {
7179            e2 = new Exception("Creation stack:");
7180            e2.setStackTrace(closedStack);
7181            throw new RestCallException(null, e2, "RestClient.close() has already been called.  This client cannot be reused.");
7182         }
7183         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.");
7184      }
7185
7186      RestRequest req = createRequest(toURI(op.getUri(), rootUrl), op.getMethod(), op.hasContent());
7187
7188      onCallInit(req);
7189
7190      req.content(op.getContent());
7191
7192      return req;
7193   }
7194
7195   /**
7196    * Creates a {@link RestRequest} object from the specified {@link HttpRequest} object.
7197    *
7198    * <p>
7199    * Subclasses can override this method to provide their own specialized {@link RestRequest} objects.
7200    *
7201    * @param uri The target.
7202    * @param method The HTTP method (uppercase).
7203    * @param hasBody Whether this method has a request entity.
7204    * @return A new {@link RestRequest} object.
7205    * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
7206    */
7207   protected RestRequest createRequest(URI uri, String method, boolean hasBody) throws RestCallException {
7208      return new RestRequest(this, uri, method, hasBody);
7209   }
7210
7211   /**
7212    * Creates a {@link RestResponse} object from the specified {@link HttpResponse} object.
7213    *
7214    * <p>
7215    * Subclasses can override this method to provide their own specialized {@link RestResponse} objects.
7216    *
7217    * @param request The request creating this response.
7218    * @param httpResponse The response object to wrap.
7219    * @param parser The parser to use to parse the response.
7220    *
7221    * @return A new {@link RestResponse} object.
7222    * @throws RestCallException If an exception or non-200 response code occurred during the connection attempt.
7223    */
7224   protected RestResponse createResponse(RestRequest request, HttpResponse httpResponse, Parser parser) throws RestCallException {
7225      return new RestResponse(this, request, httpResponse, parser);
7226   }
7227
7228   /**
7229    * Create a new proxy interface against a 3rd-party REST interface.
7230    *
7231    * <p>
7232    * The URI to the REST interface is based on the following values:
7233    * <ul>
7234    *    <li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
7235    *    <li>The {@link Builder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
7236    *    <li>The fully-qualified class name of the interface (<c>class-name</c>).
7237    * </ul>
7238    *
7239    * <p>
7240    * The URI calculation is as follows:
7241    * <ul>
7242    *    <li><c>remote-path</c> - If remote path is absolute.
7243    *    <li><c>root-uri/remote-path</c> - If remote path is relative and root-uri has been specified.
7244    *    <li><c>root-uri/class-name</c> - If remote path is not specified.
7245    * </ul>
7246    *
7247    * <p>
7248    * If the information is not available to resolve to an absolute URI, a {@link RemoteMetadataException} is thrown.
7249    *
7250    * <h5 class='section'>Examples:</h5>
7251    * <p class='bjava'>
7252    *    <jk>package</jk> org.apache.foo;
7253    *
7254    *    <ja>@RemoteResource</ja>(path=<js>"http://hostname/resturi/myinterface1"</js>)
7255    *    <jk>public interface</jk> MyInterface1 { ... }
7256    *
7257    *    <ja>@RemoteResource</ja>(path=<js>"/myinterface2"</js>)
7258    *    <jk>public interface</jk> MyInterface2 { ... }
7259    *
7260    *    <jk>public interface</jk> MyInterface3 { ... }
7261    *
7262    *    <jc>// Resolves to "http://localhost/resturi/myinterface1"</jc>
7263    *    MyInterface1 <jv>interface1</jv> = RestClient
7264    *       .<jsm>create</jsm>()
7265    *       .build()
7266    *       .getRemote(MyInterface1.<jk>class</jk>);
7267    *
7268    *    <jc>// Resolves to "http://hostname/resturi/myinterface2"</jc>
7269    *    MyInterface2 <jv>interface2</jv> = RestClient
7270    *       .<jsm>create</jsm>()
7271    *       .rootUrl(<js>"http://hostname/resturi"</js>)
7272    *       .build()
7273    *       .getRemote(MyInterface2.<jk>class</jk>);
7274    *
7275    *    <jc>// Resolves to "http://hostname/resturi/org.apache.foo.MyInterface3"</jc>
7276    *    MyInterface3 <jv>interface3</jv> = RestClient
7277    *       .<jsm>create</jsm>()
7278    *       .rootUrl(<js>"http://hostname/resturi"</js>)
7279    *       .build()
7280    *       .getRemote(MyInterface3.<jk>class</jk>);
7281    * </p>
7282    *
7283    * <h5 class='section'>Notes:</h5><ul>
7284    *    <li class='note'>
7285    *       If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
7286    *       pooling client connection manager.
7287    * </ul>
7288    *
7289    * <h5 class='section'>See Also:</h5><ul>
7290    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7291    * </ul>
7292    *
7293    * @param <T> The interface to create a proxy for.
7294    * @param interfaceClass The interface to create a proxy for.
7295    * @return The new proxy interface.
7296    * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
7297    */
7298   public <T> T getRemote(Class<T> interfaceClass) {
7299      return getRemote(interfaceClass, null);
7300   }
7301
7302   /**
7303    * Same as {@link #getRemote(Class)} except explicitly specifies the URI of the REST interface.
7304    *
7305    * <h5 class='section'>See Also:</h5><ul>
7306    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7307    * </ul>
7308    *
7309    * @param <T> The interface to create a proxy for.
7310    * @param interfaceClass The interface to create a proxy for.
7311    * @param rootUrl The URI of the REST interface.
7312    * @return The new proxy interface.
7313    */
7314   public <T> T getRemote(Class<T> interfaceClass, Object rootUrl) {
7315      return getRemote(interfaceClass, rootUrl, null, null);
7316   }
7317
7318   /**
7319    * Same as {@link #getRemote(Class, Object)} but allows you to override the serializer and parser used.
7320    *
7321    * <h5 class='section'>See Also:</h5><ul>
7322    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrc.Proxies">REST Proxies</a>
7323    * </ul>
7324
7325    * @param <T> The interface to create a proxy for.
7326    * @param interfaceClass The interface to create a proxy for.
7327    * @param rootUrl The URI of the REST interface.
7328    * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
7329    * @param parser The parser used to parse POJOs from the body of the HTTP response.
7330    * @return The new proxy interface.
7331    */
7332   @SuppressWarnings({ "unchecked" })
7333   public <T> T getRemote(final Class<T> interfaceClass, Object rootUrl, final Serializer serializer, final Parser parser) {
7334
7335      if (rootUrl == null)
7336         rootUrl = this.rootUrl;
7337
7338      final String restUrl2 = trimSlashes(emptyIfNull(rootUrl));
7339
7340      return (T)Proxy.newProxyInstance(
7341         interfaceClass.getClassLoader(),
7342         new Class[] { interfaceClass },
7343         new InvocationHandler() {
7344
7345            final RemoteMeta rm = new RemoteMeta(interfaceClass);
7346
7347            @Override /* InvocationHandler */
7348            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
7349               RemoteOperationMeta rom = rm.getOperationMeta(method);
7350
7351               String uri = rom.getFullPath();
7352               if (uri.indexOf("://") == -1)
7353                  uri = restUrl2 + '/' + uri;
7354               if (uri.indexOf("://") == -1)
7355                  throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote resource.");
7356
7357               String httpMethod = rom.getHttpMethod();
7358               RestRequest rc = request(httpMethod, uri, hasContent(httpMethod));
7359
7360               rc.serializer(serializer);
7361               rc.parser(parser);
7362
7363               rm.getHeaders().forEach(x -> rc.header(x));
7364               rom.forEachPathArg(a -> rc.pathArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer)));
7365               rom.forEachQueryArg(a -> rc.queryArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7366               rom.forEachFormDataArg(a -> rc.formDataArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7367               rom.forEachHeaderArg(a -> rc.headerArg(a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer().orElse(partSerializer), a.isSkipIfEmpty()));
7368
7369               RemoteOperationArg ba = rom.getContentArg();
7370               if (ba != null)
7371                  rc.content(args[ba.getIndex()], ba.getSchema());
7372
7373               rom.forEachRequestArg(rmba -> {
7374                     RequestBeanMeta rbm = rmba.getMeta();
7375                     Object bean = args[rmba.getIndex()];
7376                     if (bean != null) {
7377                        for (RequestBeanPropertyMeta p : rbm.getProperties()) {
7378                           Object val = safeSupplier(()->p.getGetter().invoke(bean));
7379                           HttpPartType pt = p.getPartType();
7380                           String pn = p.getPartName();
7381                           HttpPartSchema schema = p.getSchema();
7382                           if (pt == PATH)
7383                              rc.pathArg(pn, val, schema, p.getSerializer().orElse(partSerializer));
7384                           else if (val != null) {
7385                              if (pt == QUERY)
7386                                 rc.queryArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7387                              else if (pt == FORMDATA)
7388                                 rc.formDataArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7389                              else if (pt == HEADER)
7390                                 rc.headerArg(pn, val, schema, p.getSerializer().orElse(partSerializer), schema.isSkipIfEmpty());
7391                              else /* (pt == HttpPartType.BODY) */
7392                                 rc.content(val, schema);
7393                           }
7394                        }
7395                     }
7396               });
7397
7398               RemoteOperationReturn ror = rom.getReturns();
7399               if (ror.isFuture()) {
7400                  return getExecutorService().submit(new Callable<Object>() {
7401                     @Override
7402                     public Object call() throws Exception {
7403                        try {
7404                           return executeRemote(interfaceClass, rc, method, rom);
7405                        } catch (Exception e) {
7406                           throw e;
7407                        } catch (Throwable e) {
7408                           throw asRuntimeException(e);
7409                        }
7410                     }
7411                  });
7412               } else if (ror.isCompletableFuture()) {
7413                  CompletableFuture<Object> cf = new CompletableFuture<>();
7414                  getExecutorService().submit(new Callable<Object>() {
7415                     @Override
7416                     public Object call() throws Exception {
7417                        try {
7418                           cf.complete(executeRemote(interfaceClass, rc, method, rom));
7419                        } catch (Throwable e) {
7420                           cf.completeExceptionally(e);
7421                        }
7422                        return null;
7423                     }
7424                  });
7425                  return cf;
7426               }
7427
7428               return executeRemote(interfaceClass, rc, method, rom);
7429            }
7430      });
7431   }
7432
7433   Object executeRemote(Class<?> interfaceClass, RestRequest rc, Method method, RemoteOperationMeta rom) throws Throwable {
7434      RemoteOperationReturn ror = rom.getReturns();
7435
7436      try {
7437         Object ret = null;
7438         RestResponse res = null;
7439         rc.rethrow(RuntimeException.class);
7440         rom.forEachException(x -> rc.rethrow(x));
7441         if (ror.getReturnValue() == RemoteReturn.NONE) {
7442            res = rc.complete();
7443         } else if (ror.getReturnValue() == RemoteReturn.STATUS) {
7444            res = rc.complete();
7445            int returnCode = res.getStatusCode();
7446            Class<?> rt = method.getReturnType();
7447            if (rt == Integer.class || rt == int.class)
7448               ret = returnCode;
7449            else if (rt == Boolean.class || rt == boolean.class)
7450               ret = returnCode < 400;
7451            else
7452               throw new RestCallException(res, null, "Invalid return type on method annotated with @RemoteOp(returns=RemoteReturn.STATUS).  Only integer and booleans types are valid.");
7453         } else if (ror.getReturnValue() == RemoteReturn.BEAN) {
7454            rc.ignoreErrors();
7455            res = rc.run();
7456            ret = res.as(ror.getResponseBeanMeta());
7457         } else {
7458            Class<?> rt = method.getReturnType();
7459            if (Throwable.class.isAssignableFrom(rt))
7460               rc.ignoreErrors();
7461            res = rc.run();
7462            Object v = res.getContent().as(ror.getReturnType());
7463            if (v == null && rt.isPrimitive())
7464               v = ClassInfo.of(rt).getPrimitiveDefault();
7465            ret = v;
7466         }
7467         return ret;
7468      } catch (RestCallException e) {
7469         Throwable t = e.getCause();
7470         if (t instanceof RuntimeException)
7471            throw t;
7472         for (Class<?> t2 : method.getExceptionTypes())
7473            if (t2.isInstance(t))
7474               throw t;
7475         throw asRuntimeException(e);
7476      }
7477   }
7478
7479   /**
7480    * Create a new proxy interface against an RRPC-style service.
7481    *
7482    * <p>
7483    * Remote interfaces are interfaces exposed on the server side using either the <c>RrpcServlet</c>
7484    * or <c>RRPC</c> REST methods.
7485    *
7486    * <p>
7487    * The URI to the REST interface is based on the following values:
7488    * <ul>
7489    *    <li>The {@link Remote#path() @Remote(path)} annotation on the interface (<c>remote-path</c>).
7490    *    <li>The {@link Builder#rootUrl(Object) rootUrl} on the client (<c>root-url</c>).
7491    *    <li>The fully-qualified class name of the interface (<c>class-name</c>).
7492    * </ul>
7493    *
7494    * <p>
7495    * The URI calculation is as follows:
7496    * <ul>
7497    *    <li><c>remote-path</c> - If remote path is absolute.
7498    *    <li><c>root-url/remote-path</c> - If remote path is relative and root-url has been specified.
7499    *    <li><c>root-url/class-name</c> - If remote path is not specified.
7500    * </ul>
7501    *
7502    * <p>
7503    * If the information is not available to resolve to an absolute URI, a {@link RemoteMetadataException} is thrown.
7504    *
7505    * <h5 class='section'>Notes:</h5><ul>
7506    *    <li class='note'>
7507    *       If you plan on using your proxy in a multi-threaded environment, you'll want to use an underlying
7508    *       pooling client connection manager.
7509    * </ul>
7510    *
7511    * <h5 class='section'>See Also:</h5><ul>
7512    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7513    * </ul>
7514    *
7515    * @param <T> The interface to create a proxy for.
7516    * @param interfaceClass The interface to create a proxy for.
7517    * @return The new proxy interface.
7518    * @throws RemoteMetadataException If the REST URI cannot be determined based on the information given.
7519    */
7520   public <T> T getRrpcInterface(final Class<T> interfaceClass) {
7521      return getRrpcInterface(interfaceClass, null);
7522   }
7523
7524   /**
7525    * Same as {@link #getRrpcInterface(Class)} except explicitly specifies the URI of the REST interface.
7526    *
7527    * <h5 class='section'>See Also:</h5><ul>
7528    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7529    * </ul>
7530    *
7531    * @param <T> The interface to create a proxy for.
7532    * @param interfaceClass The interface to create a proxy for.
7533    * @param uri The URI of the REST interface.
7534    * @return The new proxy interface.
7535    */
7536   public <T> T getRrpcInterface(final Class<T> interfaceClass, final Object uri) {
7537      return getRrpcInterface(interfaceClass, uri, null, null);
7538   }
7539
7540   /**
7541    * Same as {@link #getRrpcInterface(Class, Object)} but allows you to override the serializer and parser used.
7542    *
7543    * <h5 class='section'>See Also:</h5><ul>
7544    *    <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestRpc">REST/RPC</a>
7545    * </ul>
7546    *
7547    * @param <T> The interface to create a proxy for.
7548    * @param interfaceClass The interface to create a proxy for.
7549    * @param uri The URI of the REST interface.
7550    * @param serializer The serializer used to serialize POJOs to the body of the HTTP request.
7551    * @param parser The parser used to parse POJOs from the body of the HTTP response.
7552    * @return The new proxy interface.
7553    */
7554   @SuppressWarnings({ "unchecked" })
7555   public <T> T getRrpcInterface(final Class<T> interfaceClass, Object uri, final Serializer serializer, final Parser parser) {
7556
7557      if (uri == null) {
7558         RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, "");
7559         String path = rm.getPath();
7560         if (path.indexOf("://") == -1) {
7561            if (isEmpty(rootUrl))
7562               throw new RemoteMetadataException(interfaceClass, "Root URI has not been specified.  Cannot construct absolute path to remote interface.");
7563            path = trimSlashes(rootUrl) + '/' + path;
7564         }
7565         uri = path;
7566      }
7567
7568      final String restUrl2 = stringify(uri);
7569
7570      return (T)Proxy.newProxyInstance(
7571         interfaceClass.getClassLoader(),
7572         new Class[] { interfaceClass },
7573         new InvocationHandler() {
7574
7575            final RrpcInterfaceMeta rm = new RrpcInterfaceMeta(interfaceClass, restUrl2);
7576
7577            @Override /* InvocationHandler */
7578            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
7579               RrpcInterfaceMethodMeta rim = rm.getMethodMeta(method);
7580
7581               String uri = rim.getUri();
7582               RestResponse res = null;
7583
7584               try {
7585                  RestRequest rc = request("POST", uri, true)
7586                     .serializer(serializer)
7587                     .content(args)
7588                     .rethrow(RuntimeException.class)
7589                     .rethrow(method.getExceptionTypes());
7590
7591                  res = rc.run();
7592
7593                  Object v = res.getContent().as(method.getGenericReturnType());
7594                  if (v == null && method.getReturnType().isPrimitive())
7595                     v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
7596                  return v;
7597
7598               } catch (Throwable e) {
7599                  if (e instanceof RestCallException) {
7600                     Throwable t = e.getCause();
7601                     if (t != null)
7602                        e = t;
7603                  }
7604                  if (e instanceof RuntimeException)
7605                     throw e;
7606                  for (Class<?> t2 : method.getExceptionTypes())
7607                     if (t2.isInstance(e))
7608                        throw e;
7609                  throw asRuntimeException(e);
7610               }
7611            }
7612      });
7613   }
7614
7615   @Override
7616   protected void finalize() throws Throwable {
7617      if (detectLeaks && ! isClosed && ! keepHttpClientOpen) {
7618         StringBuilder sb = new StringBuilder("WARNING:  RestClient garbage collected before it was finalized.");  // NOT DEBUG
7619         if (creationStack != null) {
7620            sb.append("\nCreation Stack:");  // NOT DEBUG
7621            for (StackTraceElement e : creationStack)
7622               sb.append("\n\t" + e);  // NOT DEBUG
7623         }
7624         log(WARNING, sb.toString());
7625      }
7626   }
7627
7628   /**
7629    * Logs a message.
7630    *
7631    * @param level The log level.
7632    * @param t Thrown exception.  Can be <jk>null</jk>.
7633    * @param msg The message.
7634    * @param args Optional message arguments.
7635    */
7636   protected void log(Level level, Throwable t, String msg, Object...args) {
7637      logger.log(level, t, msg(msg, args));
7638      if (logToConsole) {
7639         console.println(msg(msg, args).get());
7640         if (t != null)
7641            t.printStackTrace(console);
7642      }
7643   }
7644
7645   /**
7646    * Logs a message.
7647    *
7648    * @param level The log level.
7649    * @param msg The message with {@link MessageFormat}-style arguments.
7650    * @param args The arguments.
7651    */
7652   protected void log(Level level, String msg, Object...args) {
7653      logger.log(level, msg(msg, args));
7654      if (logToConsole)
7655         console.println(msg(msg, args).get());
7656   }
7657
7658   private Supplier<String> msg(String msg, Object...args) {
7659      return ()->args.length == 0 ? msg : MessageFormat.format(msg, args);
7660   }
7661
7662   /**
7663    * Returns the part serializer associated with this client.
7664    *
7665    * @return The part serializer associated with this client.
7666    */
7667   protected HttpPartSerializer getPartSerializer() {
7668      return partSerializer;
7669   }
7670
7671   /**
7672    * Returns the part parser associated with this client.
7673    *
7674    * @return The part parser associated with this client.
7675    */
7676   protected HttpPartParser getPartParser() {
7677      return partParser;
7678   }
7679
7680   /**
7681    * Returns the part serializer instance of the specified type.
7682    *
7683    * @param c The part serializer class.
7684    * @return The part serializer.
7685    */
7686   protected HttpPartSerializer getPartSerializer(Class<? extends HttpPartSerializer> c) {
7687      HttpPartSerializer x = partSerializers.get(c);
7688      if (x == null) {
7689         try {
7690            x = beanStore.createBean(c).run();
7691         } catch (ExecutableException e) {
7692            throw asRuntimeException(e);
7693         }
7694         partSerializers.put(c, x);
7695      }
7696      return x;
7697   }
7698
7699   /**
7700    * Returns the part parser instance of the specified type.
7701    *
7702    * @param c The part parser class.
7703    * @return The part parser.
7704    */
7705   protected HttpPartParser getPartParser(Class<? extends HttpPartParser> c) {
7706      HttpPartParser x = partParsers.get(c);
7707      if (x == null) {
7708         try {
7709            x = beanStore.createBean(c).run();
7710         } catch (ExecutableException e) {
7711            throw asRuntimeException(e);
7712         }
7713         partParsers.put(c, x);
7714      }
7715      return x;
7716   }
7717
7718   /**
7719    * Returns <jk>true</jk> if empty request header values should be ignored.
7720    *
7721    * @return <jk>true</jk> if empty request header values should be ignored.
7722    */
7723   protected boolean isSkipEmptyHeaderData() {
7724      return skipEmptyHeaderData;
7725   }
7726
7727   /**
7728    * Returns <jk>true</jk> if empty request query parameter values should be ignored.
7729    *
7730    * @return <jk>true</jk> if empty request query parameter values should be ignored.
7731    */
7732   protected boolean isSkipEmptyQueryData() {
7733      return skipEmptyQueryData;
7734   }
7735
7736   /**
7737    * Returns <jk>true</jk> if empty request form-data parameter values should be ignored.
7738    *
7739    * @return <jk>true</jk> if empty request form-data parameter values should be ignored.
7740    */
7741   protected boolean isSkipEmptyFormData() {
7742      return skipEmptyFormData;
7743   }
7744
7745   //-----------------------------------------------------------------------------------------------------------------
7746   // Part list builders methods
7747   //-----------------------------------------------------------------------------------------------------------------
7748
7749   /**
7750    * Creates a mutable copy of the header data defined on this client.
7751    *
7752    * <p>
7753    * Used during the construction of {@link RestRequest} objects.
7754    *
7755    * <p>
7756    * Subclasses can override this method to provide their own builder.
7757    *
7758    * @return A new builder.
7759    */
7760   public HeaderList createHeaderData() {
7761      return headerData.copy();
7762   }
7763
7764   /**
7765    * Creates a mutable copy of the query data defined on this client.
7766    *
7767    * <p>
7768    * Used during the construction of {@link RestRequest} objects.
7769    *
7770    * <p>
7771    * Subclasses can override this method to provide their own builder.
7772    *
7773    * @return A new builder.
7774    */
7775   public PartList createQueryData() {
7776      return queryData.copy();
7777   }
7778
7779   /**
7780    * Creates a mutable copy of the form data defined on this client.
7781    *
7782    * <p>
7783    * Used during the construction of {@link RestRequest} objects.
7784    *
7785    * <p>
7786    * Subclasses can override this method to provide their own builder.
7787    *
7788    * @return A new builder.
7789    */
7790   public PartList createFormData() {
7791      return formData.copy();
7792   }
7793
7794   /**
7795    * Creates a mutable copy of the path data defined on this client.
7796    *
7797    * <p>
7798    * Used during the construction of {@link RestRequest} objects.
7799    *
7800    * <p>
7801    * Subclasses can override this method to provide their own builder.
7802    *
7803    * @return A new builder.
7804    */
7805   public PartList createPathData() {
7806      return pathData.copy();
7807   }
7808
7809   //-----------------------------------------------------------------------------------------------------------------
7810   // RestCallInterceptor methods
7811   //-----------------------------------------------------------------------------------------------------------------
7812
7813   /**
7814    * Interceptor method called immediately after the RestRequest object is created and all headers/query/form-data has been copied from the client.
7815    *
7816    * <p>
7817    * Subclasses can override this method to intercept the request and perform special modifications.
7818    *
7819    * <h5 class='section'>See Also:</h5><ul>
7820    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7821    * </ul>
7822    *
7823    * @param req The HTTP request.
7824    * @throws RestCallException If any of the interceptors threw an exception.
7825    */
7826   protected void onCallInit(RestRequest req) throws RestCallException {
7827      try {
7828         for (RestCallInterceptor rci : interceptors)
7829            rci.onInit(req);
7830      } catch (RuntimeException | RestCallException e) {
7831         throw e;
7832      } catch (Exception e) {
7833         throw new RestCallException(null, e, "Interceptor threw an exception on init.");
7834      }
7835   }
7836
7837   /**
7838    * Interceptor method called immediately after an HTTP response has been received.
7839    *
7840    * <p>
7841    * Subclasses can override this method to intercept the response and perform special modifications.
7842    *
7843    * <h5 class='section'>See Also:</h5><ul>
7844    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7845    * </ul>
7846    *
7847    * @param req The HTTP request.
7848    * @param res The HTTP response.
7849    * @throws RestCallException If any of the interceptors threw an exception.
7850    */
7851   protected void onCallConnect(RestRequest req, RestResponse res) throws RestCallException {
7852      try {
7853         for (RestCallInterceptor rci : interceptors)
7854            rci.onConnect(req, res);
7855      } catch (RuntimeException | RestCallException e) {
7856         throw e;
7857      } catch (Exception e) {
7858         throw new RestCallException(res, e, "Interceptor threw an exception on connect.");
7859      }
7860   }
7861
7862   /**
7863    * 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.
7864    *
7865    * <p>
7866    * Subclasses can override this method to handle any cleanup operations.
7867    *
7868    * <h5 class='section'>See Also:</h5><ul>
7869    *    <li class='jm'>{@link Builder#interceptors(Object...)}
7870    * </ul>
7871    *
7872    * @param req The HTTP request.
7873    * @param res The HTTP response.
7874    * @throws RestCallException If any of the interceptors threw an exception.
7875    */
7876   protected void onCallClose(RestRequest req, RestResponse res) throws RestCallException {
7877      try {
7878         for (RestCallInterceptor rci : interceptors)
7879            rci.onClose(req, res);
7880      } catch (RuntimeException | RestCallException e) {
7881         throw e;
7882      } catch (Exception e) {
7883         throw new RestCallException(res, e, "Interceptor threw an exception on close.");
7884      }
7885   }
7886
7887   //------------------------------------------------------------------------------------------------
7888   // Passthrough methods for HttpClient.
7889   //------------------------------------------------------------------------------------------------
7890
7891   /**
7892    * Obtains the parameters for this client.
7893    *
7894    * These parameters will become defaults for all requests being executed with this client, and for the parameters of dependent objects in this client.
7895    *
7896    * @return The default parameters.
7897    * @deprecated Use {@link RequestConfig}.
7898    */
7899   @Deprecated
7900   @Override /* HttpClient */
7901   public HttpParams getParams() {
7902      return httpClient.getParams();
7903   }
7904
7905   /**
7906    * Obtains the connection manager used by this client.
7907    *
7908    * @return The connection manager.
7909    * @deprecated Use {@link HttpClientBuilder}.
7910    */
7911   @Deprecated
7912   @Override /* HttpClient */
7913   public ClientConnectionManager getConnectionManager() {
7914      return httpClient.getConnectionManager();
7915   }
7916
7917   /**
7918    * Returns the connection manager if one was specified in the client builder.
7919    *
7920    * @return The connection manager.  May be <jk>null</jk>.
7921    */
7922   public HttpClientConnectionManager getHttpClientConnectionManager() {
7923      return connectionManager;
7924   }
7925
7926   /**
7927    * Executes HTTP request using the default context.
7928    *
7929    * <h5 class='section'>Notes:</h5><ul>
7930    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7931    * </ul>
7932    *
7933    * @param request The request to execute.
7934    * @return
7935    *    The response to the request.
7936    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7937    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7938    *       implementation and configuration of this client.
7939    * @throws IOException In case of a problem or the connection was aborted.
7940    * @throws ClientProtocolException In case of an http protocol error.
7941    */
7942   @Override /* HttpClient */
7943   public HttpResponse execute(HttpUriRequest request) throws IOException, ClientProtocolException {
7944      return httpClient.execute(request);
7945   }
7946
7947   /**
7948    * Executes HTTP request using the given context.
7949    *
7950    * <h5 class='section'>Notes:</h5><ul>
7951    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7952    * </ul>
7953    *
7954    * @param request The request to execute.
7955    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
7956    * @return
7957    *    The response to the request.
7958    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7959    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7960    *       implementation and configuration of this client.
7961    * @throws IOException In case of a problem or the connection was aborted.
7962    * @throws ClientProtocolException In case of an http protocol error.
7963    */
7964   @Override /* HttpClient */
7965   public HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
7966      return httpClient.execute(request, context);
7967   }
7968
7969   /**
7970    * Executes HTTP request using the default context.
7971    *
7972    * <h5 class='section'>Notes:</h5><ul>
7973    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7974    * </ul>
7975    *
7976    * @param target The target host for the request.
7977    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
7978    *       target or by inspecting the request.
7979    * @param request The request to execute.
7980    * @return The response to the request.
7981    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
7982    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
7983    *       implementation and configuration of this client.
7984    * @throws IOException In case of a problem or the connection was aborted.
7985    * @throws ClientProtocolException In case of an http protocol error.
7986    */
7987   @Override /* HttpClient */
7988   public HttpResponse execute(HttpHost target, HttpRequest request) throws IOException, ClientProtocolException {
7989      return httpClient.execute(target, request);
7990   }
7991
7992   /**
7993    * Executes HTTP request using the given context.
7994    *
7995    * <h5 class='section'>Notes:</h5><ul>
7996    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
7997    *    <li class='note'>The {@link #run(HttpHost,HttpRequest,HttpContext)} method has been provided as a wrapper around this method.
7998    *       Subclasses can override these methods for handling requests with and without bodies separately.
7999    *    <li class='note'>The {@link RestCallHandler} interface can also be implemented to intercept this method.
8000    * </ul>
8001    *
8002    * @param target The target host for the request.
8003    *    <br>Implementations may accept <jk>null</jk> if they can still determine a route, for example to a default
8004    *       target or by inspecting the request.
8005    * @param request The request to execute.
8006    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8007    * @return
8008    *    The response to the request.
8009    *    <br>This is always a final response, never an intermediate response with an 1xx status code.
8010    *    <br>Whether redirects or authentication challenges will be returned or handled automatically depends on the
8011    *       implementation and configuration of this client.
8012    * @throws IOException In case of a problem or the connection was aborted.
8013    * @throws ClientProtocolException In case of an http protocol error.
8014    */
8015   @Override /* HttpClient */
8016   public HttpResponse execute(HttpHost target, HttpRequest request, HttpContext context) throws IOException, ClientProtocolException {
8017      return httpClient.execute(target, request, context);
8018   }
8019
8020   /**
8021    * Executes HTTP request using the default context and processes the response using the given response handler.
8022    *
8023    * <p>
8024    * The content entity associated with the response is fully consumed and the underlying connection is released back
8025    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8026    * from having to manage resource deallocation internally.
8027    *
8028    * <h5 class='section'>Notes:</h5><ul>
8029    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8030    * </ul>
8031    *
8032    * @param request The request to execute.
8033    * @param responseHandler The response handler.
8034    * @return Object returned by response handler.
8035    * @throws IOException In case of a problem or the connection was aborted.
8036    * @throws ClientProtocolException In case of an http protocol error.
8037    */
8038   @Override /* HttpClient */
8039   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
8040      return httpClient.execute(request, responseHandler);
8041   }
8042
8043   /**
8044    * Executes HTTP request using the given context and processes the response using the given response handler.
8045    *
8046    * <p>
8047    * The content entity associated with the response is fully consumed and the underlying connection is released back
8048    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8049    * from having to manage resource deallocation internally.
8050    *
8051    * <h5 class='section'>Notes:</h5><ul>
8052    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8053    * </ul>
8054    *
8055    * @param request The request to execute.
8056    * @param responseHandler The response handler.
8057    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8058    * @return The response object as generated by the response handler.
8059    * @throws IOException In case of a problem or the connection was aborted.
8060    * @throws ClientProtocolException In case of an http protocol error.
8061    */
8062   @Override /* HttpClient */
8063   public <T> T execute(HttpUriRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
8064      return httpClient.execute(request, responseHandler, context);
8065   }
8066
8067   /**
8068    * Executes HTTP request to the target using the default context and processes the response using the given response handler.
8069    *
8070    * <p>
8071    * The content entity associated with the response is fully consumed and the underlying connection is released back
8072    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8073    * from having to manage resource deallocation internally.
8074    *
8075    * <h5 class='section'>Notes:</h5><ul>
8076    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8077    * </ul>
8078    *
8079    * @param target
8080    *    The target host for the request.
8081    *    <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.
8082    * @param request The request to execute.
8083    * @param responseHandler The response handler.
8084    * @return The response object as generated by the response handler.
8085    * @throws IOException In case of a problem or the connection was aborted.
8086    * @throws ClientProtocolException In case of an http protocol error.
8087    */
8088   @Override /* HttpClient */
8089   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler) throws IOException, ClientProtocolException {
8090      return httpClient.execute(target, request, responseHandler);
8091   }
8092
8093   /**
8094    * Executes a request using the default context and processes the response using the given response handler.
8095    *
8096    * <p>
8097    * The content entity associated with the response is fully consumed and the underlying connection is released back
8098    * to the connection manager automatically in all cases relieving individual {@link ResponseHandler ResponseHandlers}
8099    * from having to manage resource deallocation internally.
8100    *
8101    * <h5 class='section'>Notes:</h5><ul>
8102    *    <li class='note'>This method gets passed on directly to the underlying {@link HttpClient} class.
8103    * </ul>
8104    *
8105    * @param target
8106    *    The target host for the request.
8107    *    <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.
8108    * @param request The request to execute.
8109    * @param responseHandler The response handler.
8110    * @param context The context to use for the execution, or <jk>null</jk> to use the default context.
8111    * @return The response object as generated by the response handler.
8112    * @throws IOException In case of a problem or the connection was aborted.
8113    * @throws ClientProtocolException In case of an http protocol error.
8114    */
8115   @Override /* HttpClient */
8116   public <T> T execute(HttpHost target, HttpRequest request, ResponseHandler<? extends T> responseHandler, HttpContext context) throws IOException, ClientProtocolException {
8117      return httpClient.execute(target, request, responseHandler, context);
8118   }
8119
8120   //-----------------------------------------------------------------------------------------------------------------
8121   // Other methods
8122   //-----------------------------------------------------------------------------------------------------------------
8123
8124   private Pattern absUrlPattern = Pattern.compile("^\\w+\\:\\/\\/.*");
8125
8126   URI toURI(Object x, String rootUrl) throws RestCallException {
8127      try {
8128         if (x instanceof URI)
8129            return (URI)x;
8130         if (x instanceof URL)
8131            ((URL)x).toURI();
8132         if (x instanceof URIBuilder)
8133            return ((URIBuilder)x).build();
8134         String s = x == null ? "" : x.toString();
8135         if (rootUrl != null && ! absUrlPattern.matcher(s).matches()) {
8136            if (s.isEmpty())
8137               s = rootUrl;
8138            else {
8139               StringBuilder sb = new StringBuilder(rootUrl);
8140               if (! s.startsWith("/"))
8141                  sb.append('/');
8142               sb.append(s);
8143               s = sb.toString();
8144            }
8145         }
8146         s = fixUrl(s);
8147         return new URI(s);
8148      } catch (URISyntaxException e) {
8149         throw new RestCallException(null, e, "Invalid URI encountered:  {0}", x);  // Shouldn't happen.
8150      }
8151   }
8152
8153   ExecutorService getExecutorService() {
8154      if (executorService != null)
8155         return executorService;
8156      synchronized(this) {
8157         executorService = new ThreadPoolExecutor(1, 1, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(10));
8158         return executorService;
8159      }
8160   }
8161
8162   /*
8163    * Returns the serializer that best matches the specified content type.
8164    * If no match found or the content type is null, returns the serializer in the list if it's a list of one.
8165    * Returns null if no serializers are defined.
8166    */
8167   Serializer getMatchingSerializer(String mediaType) {
8168      if (serializers.isEmpty())
8169         return null;
8170      if (mediaType != null) {
8171         Serializer s = serializers.getSerializer(mediaType);
8172         if (s != null)
8173            return s;
8174      }
8175      List<Serializer> l = serializers.getSerializers();
8176      return (l.size() == 1 ? l.get(0) : null);
8177   }
8178
8179   boolean hasSerializers() {
8180      return ! serializers.getSerializers().isEmpty();
8181   }
8182
8183   /*
8184    * Returns the parser that best matches the specified content type.
8185    * If no match found or the content type is null, returns the parser in the list if it's a list of one.
8186    * Returns null if no parsers are defined.
8187    */
8188   Parser getMatchingParser(String mediaType) {
8189      if (parsers.isEmpty())
8190         return null;
8191      if (mediaType != null) {
8192         Parser p = parsers.getParser(mediaType);
8193         if (p != null)
8194            return p;
8195      }
8196      List<Parser> l = parsers.getParsers();
8197      return (l.size() == 1 ? l.get(0) : null);
8198   }
8199
8200   boolean hasParsers() {
8201      return ! parsers.getParsers().isEmpty();
8202   }
8203
8204   @SuppressWarnings("unchecked")
8205   <T extends Context> T getInstance(Class<T> c) {
8206      Context o = requestContexts.get(c);
8207      if (o == null) {
8208         if (Serializer.class.isAssignableFrom(c)) {
8209            o = Serializer.createSerializerBuilder((Class<? extends Serializer>)c).beanContext(getBeanContext()).build();
8210         } else if (Parser.class.isAssignableFrom(c)) {
8211            o = Parser.createParserBuilder((Class<? extends Parser>)c).beanContext(getBeanContext()).build();
8212         }
8213         requestContexts.put(c, o);
8214      }
8215      return (T)o;
8216   }
8217
8218   private RestOperation op(String method, Object url, Object body) {
8219      return RestOperation.of(method, url, body);
8220   }
8221
8222   private Reader stringBody(String body) {
8223      return body == null ? null : new StringReader(stringify(body));
8224   }
8225
8226   @Override /* Context */
8227   protected JsonMap properties() {
8228      return filteredMap()
8229         .append("errorCodes", errorCodes)
8230         .append("executorService", executorService)
8231         .append("executorServiceShutdownOnClose", executorServiceShutdownOnClose)
8232         .append("headerData", headerData)
8233         .append("interceptors", interceptors)
8234         .append("keepHttpClientOpen", keepHttpClientOpen)
8235         .append("partParser", partParser)
8236         .append("partSerializer", partSerializer)
8237         .append("queryData", queryData)
8238         .append("rootUrl", rootUrl);
8239   }
8240}