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

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


The following commit(s) were added to refs/heads/master by this push:
     new 25562e5  RestClient tests.
25562e5 is described below

commit 25562e5f6e9141b1fdfb6a1a8c3e131eb46a79c9
Author: JamesBognar <james.bog...@salesforce.com>
AuthorDate: Sat Jun 20 10:32:28 2020 -0400

    RestClient tests.
---
 .../org/apache/juneau/http/BasicNameValuePair.java |   10 +-
 .../java/org/apache/juneau/http/Headerable.java    |   32 +
 .../org/apache/juneau/http/SerializedHeader.java   |   12 +
 .../juneau/http/SerializedNameValuePair.java       |    9 +-
 .../org/apache/juneau/http/header/BasicHeader.java |   12 +
 .../org/apache/juneau/httppart/HttpPartSchema.java |   17 +-
 .../juneau/httppart/HttpPartSchemaBuilder.java     |  116 +-
 .../juneau/rest/client2/QueryAnnotationTest.java   |    2 +-
 .../apache/juneau/rest/client2/RestClientTest.java |  179 ++-
 .../org/apache/juneau/rest/client2/RestClient.java |   60 +-
 .../juneau/rest/client2/RestClientBuilder.java     |  111 +-
 .../juneau/rest/client2/RestClientUtils.java       |  103 --
 .../apache/juneau/rest/client2/RestRequest.java    | 1579 ++++----------------
 13 files changed, 781 insertions(+), 1461 deletions(-)

diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNameValuePair.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNameValuePair.java
index 6910f0f..952705e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNameValuePair.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicNameValuePair.java
@@ -17,15 +17,16 @@ import static org.apache.juneau.internal.StringUtils.*;
 import java.util.function.*;
 
 import org.apache.http.*;
+import org.apache.juneau.http.header.*;
 
 /**
  * Subclass of {@link NameValuePair} for serializing POJOs as URL-encoded form 
post entries.
- *
+ * 
  * <p>
  * The value is serialized using {@link Object#toString()} at the point of 
reading.  This allows the value to be modified
  * periodically by overriding the method to return different values.
  */
-public class BasicNameValuePair implements NameValuePair {
+public class BasicNameValuePair implements NameValuePair, Headerable {
        private String name;
        private Object value;
 
@@ -65,6 +66,11 @@ public class BasicNameValuePair implements NameValuePair {
                this.value = value;
        }
 
+       @Override /* Headerable */
+       public BasicHeader asHeader() {
+               return BasicHeader.of(name, value);
+       }
+
        @Override /* NameValuePair */
        public String getName() {
                return name;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Headerable.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Headerable.java
new file mode 100644
index 0000000..682c257
--- /dev/null
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/Headerable.java
@@ -0,0 +1,32 @@
+// 
***************************************************************************************************************************
+// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
+// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
+// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
+// * with the License.  You may obtain a copy of the License at                
                                              *
+// *                                                                           
                                              *
+// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
+// *                                                                           
                                              *
+// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
+// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
+// * specific language governing permissions and limitations under the 
License.                                              *
+// 
***************************************************************************************************************************
+package org.apache.juneau.http;
+
+import org.apache.http.*;
+
+/**
+ * Identifies a class that can be converted to a {@link Header} object.
+ * 
+ * <p>
+ * Typically used on {@link NameValuePair} classes to allow them to be easily 
converted to {@link Header}
+ * objects in a controlled way.
+ */
+public interface Headerable {
+
+       /**
+        * Convert the object to a {@link Header}.
+        *
+        * @return The object converted to a {@link Header}.
+        */
+       Header asHeader();
+}
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
index 94f7eda..032b184 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedHeader.java
@@ -133,6 +133,18 @@ public class SerializedHeader extends BasicStringHeader {
                 * @param value The new value for this property.
                 * @return This object (for method chaining).
                 */
+               public Builder serializer(HttpPartSerializer value) {
+                       if (value != null)
+                               return 
serializer(value.createPartSession(null));
+                       return this;
+               }
+
+               /**
+                * Sets the serializer to use for serializing the value to a 
string value.
+                *
+                * @param value The new value for this property.
+                * @return This object (for method chaining).
+                */
                public Builder serializer(HttpPartSerializerSession value) {
                        return serializer(value, true);
                }
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
index 3ad07e0..519471e 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/SerializedNameValuePair.java
@@ -35,7 +35,7 @@ import org.apache.juneau.urlencoding.*;
  *     request.setEntity(<jk>new</jk> UrlEncodedFormEntity(params));
  * </p>
  */
-public class SerializedNameValuePair implements NameValuePair {
+public class SerializedNameValuePair implements NameValuePair, Headerable {
        private String name;
        private Object value;
        private HttpPartType type;
@@ -76,6 +76,11 @@ public class SerializedNameValuePair implements 
NameValuePair {
                this.skipIfEmpty = skipIfEmpty;
        }
 
+       @Override /* Headerable */
+       public SerializedHeader asHeader() {
+               return new SerializedHeader(name, value, serializer, schema, 
skipIfEmpty);
+       }
+
        SerializedNameValuePair(Builder b) {
                this.name = b.name;
                this.value = b.value;
@@ -208,6 +213,8 @@ public class SerializedNameValuePair implements 
NameValuePair {
                                        return null;
                                if (schema.getDefault() == null && ! 
schema.isRequired())
                                        return null;
+                               if (schema.isAllowEmptyValue() && 
schema.getDefault() == null)
+                                       return null;
                        }
                        if (isEmpty(v) && skipIfEmpty && schema.getDefault() == 
null)
                                return null;
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
index adac8cb..cbc1674 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/header/BasicHeader.java
@@ -47,6 +47,18 @@ public class BasicHeader implements Header, Cloneable, 
Serializable {
        }
 
        /**
+        * Convenience creator.
+        *
+        * @param o The name value pair that makes up the header name and value.
+        *      The parameter value.
+        *      <br>Any non-String value will be converted to a String using 
{@link Object#toString()}.
+        * @return A new {@link BasicHeader} object.
+        */
+       public static Header of(NameValuePair o) {
+               return new BasicHeader(o.getName(), o.getValue());
+       }
+
+       /**
         * Convenience creator using supplier.
         *
         * <p>
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
index ae54100..480a064 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchema.java
@@ -1471,20 +1471,25 @@ public class HttpPartSchema {
                return in == null ? Collections.emptySet() : 
unmodifiableSet(new LinkedHashSet<>(in));
        }
 
-       private static Map<String,HttpPartSchema> 
build(Map<String,HttpPartSchemaBuilder> in, boolean noValidate) {
+       private static Map<String,HttpPartSchema> build(Map<String,Object> in, 
boolean noValidate) {
                if (in == null)
                        return null;
                Map<String,HttpPartSchema> m = new LinkedHashMap<>();
-               for (Map.Entry<String,HttpPartSchemaBuilder> e : in.entrySet())
-                       m.put(e.getKey(), 
e.getValue().noValidate(noValidate).build());
+               for (Map.Entry<String,Object> e : in.entrySet()) {
+                       Object v = e.getValue();
+                       m.put(e.getKey(), build(v, noValidate));
+               }
                return unmodifiableMap(m);
        }
 
-       private static HttpPartSchema build(HttpPartSchemaBuilder in, boolean 
noValidate) {
-               return in == null ? null : in.noValidate(noValidate).build();
+       private static HttpPartSchema build(Object in, boolean noValidate) {
+               if (in == null)
+                       return null;
+               if (in instanceof HttpPartSchema)
+                       return (HttpPartSchema)in;
+               return 
((HttpPartSchemaBuilder)in).noValidate(noValidate).build();
        }
 
-
        
//-----------------------------------------------------------------------------------------------------------------
        // Helper methods.
        
//-----------------------------------------------------------------------------------------------------------------
diff --git 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
index 00cb8c3..c350d4f 100644
--- 
a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
+++ 
b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/httppart/HttpPartSchemaBuilder.java
@@ -41,8 +41,8 @@ public class HttpPartSchemaBuilder {
        Pattern pattern;
        Number maximum, minimum, multipleOf;
        Long maxLength, minLength, maxItems, minItems, maxProperties, 
minProperties;
-       Map<String,HttpPartSchemaBuilder> properties;
-       HttpPartSchemaBuilder items, additionalProperties;
+       Map<String,Object> properties;
+       Object items, additionalProperties;
        boolean noValidate;
        Class<? extends HttpPartParser> parser;
        Class<? extends HttpPartSerializer> serializer;
@@ -1068,6 +1068,35 @@ public class HttpPartSchemaBuilder {
                return this;
        }
 
+       /**
+        * <mk>items</mk> field.
+        *
+        * <p>
+        * Describes the type of items in the array.
+        * <p>
+        * Required if <c>type</c> is <js>"array"</js>.
+        * <br>Can only be used if <c>type</c> is <js>"array"</js>.
+        *
+        * <p>
+        * Applicable to the following Swagger schema objects:
+        * <ul>
+        *      <li>{@doc SwaggerParameterObject Parameter}
+        *      <li>{@doc SwaggerSchemaObject Schema}
+        *      <li>{@doc SwaggerItemsObject Items}
+        *      <li>{@doc SwaggerHeaderObject Header}
+        * </ul>
+        *
+        * @param value
+        *      The new value for this property.
+        *      <br>Ignored if value is <jk>null</jk> or empty.
+        * @return This object (for method chaining).
+        */
+       public HttpPartSchemaBuilder items(HttpPartSchema value) {
+               if (value != null)
+                       this.items = value;
+               return this;
+       }
+
        HttpPartSchemaBuilder items(OMap value) {
                if (value != null && ! value.isEmpty())
                        items = HttpPartSchema.create().apply(value);
@@ -1926,6 +1955,31 @@ public class HttpPartSchemaBuilder {
        }
 
        /**
+        * <mk>properties</mk> field.
+        *
+        * <p>
+        * Applicable to the following Swagger schema objects:
+        * <ul>
+        *      <li>{@doc SwaggerSchemaObject Schema}
+        * </ul>
+        *
+        * @param key
+        *      The property name.
+        * @param value
+        *      The new value for this property.
+        *      <br>Ignored if value is <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public HttpPartSchemaBuilder property(String key, HttpPartSchema value) 
{
+               if ( key != null && value != null) {
+                       if (properties == null)
+                               properties = new LinkedHashMap<>();
+                       properties.put(key, value);
+               }
+               return this;
+       }
+
+       /**
         * Shortcut for <c>property(key, value)</c>.
         *
         * <p>
@@ -1945,6 +1999,26 @@ public class HttpPartSchemaBuilder {
                return property(key, value);
        }
 
+       /**
+        * Shortcut for <c>property(key, value)</c>.
+        *
+        * <p>
+        * Applicable to the following Swagger schema objects:
+        * <ul>
+        *      <li>{@doc SwaggerSchemaObject Schema}
+        * </ul>
+        *
+        * @param key
+        *      The property name.
+        * @param value
+        *      The new value for this property.
+        *      <br>Ignored if value is <jk>null</jk>.
+        * @return This object (for method chaining).
+        */
+       public HttpPartSchemaBuilder p(String key, HttpPartSchema value) {
+               return property(key, value);
+       }
+
        private HttpPartSchemaBuilder properties(OMap value) {
                if (value != null && ! value.isEmpty())
                for (Map.Entry<String,Object> e : value.entrySet())
@@ -1973,6 +2047,26 @@ public class HttpPartSchemaBuilder {
        }
 
        /**
+        * <mk>additionalProperties</mk> field.
+        *
+        * <p>
+        * Applicable to the following Swagger schema objects:
+        * <ul>
+        *      <li>{@doc SwaggerSchemaObject Schema}
+        * </ul>
+        *
+        * @param value
+        *      The new value for this property.
+        *      <br>Ignored if value is <jk>null</jk> or empty.
+        * @return This object (for method chaining).
+        */
+       public HttpPartSchemaBuilder additionalProperties(HttpPartSchema value) 
{
+               if (value != null)
+                       additionalProperties = value;
+               return this;
+       }
+
+       /**
         * Shortcut for <c>additionalProperties(value)</c>
         *
         * <p>
@@ -1990,6 +2084,24 @@ public class HttpPartSchemaBuilder {
                return additionalProperties(value);
        }
 
+       /**
+        * Shortcut for <c>additionalProperties(value)</c>
+        *
+        * <p>
+        * Applicable to the following Swagger schema objects:
+        * <ul>
+        *      <li>{@doc SwaggerSchemaObject Schema}
+        * </ul>
+        *
+        * @param value
+        *      The new value for this property.
+        *      <br>Ignored if value is <jk>null</jk> or empty.
+        * @return This object (for method chaining).
+        */
+       public HttpPartSchemaBuilder ap(HttpPartSchema value) {
+               return additionalProperties(value);
+       }
+
        private HttpPartSchemaBuilder additionalProperties(OMap value) {
                if (value != null && ! value.isEmpty())
                        additionalProperties = 
HttpPartSchema.create().apply(value);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
index ad89bd1..2f14e32 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/QueryAnnotationTest.java
@@ -75,7 +75,7 @@ public class QueryAnnotationTest {
                @RemoteMethod(path="a") String getA06b(@Query("*") 
Map<String,Bean> b);
                @RemoteMethod(path="a") String getA06c(@Query Map<String,Bean> 
b);
                @RemoteMethod(path="a") String getA06d(@Query(n="x",cf="uon") 
Map<String,Bean> b);
-               @RemoteMethod(path="a") String getA06e(@Query(cf="uon") 
Map<String,Bean> b);
+               @RemoteMethod(path="a") String getA06e(@Query(f="uon") 
Map<String,Bean> b);
                @RemoteMethod(path="a") String getA07a(@Query("*") Reader b);
                @RemoteMethod(path="a") String getA07b(@Query Reader b);
                @RemoteMethod(path="a") String getA08a(@Query("*") InputStream 
b);
diff --git 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
index 77b4255..e1e17b4 100644
--- 
a/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
+++ 
b/juneau-rest/juneau-rest-client-utest/src/test/java/org/apache/juneau/rest/client2/RestClientTest.java
@@ -2824,7 +2824,7 @@ public class RestClientTest {
                                .headers("Foo");
                        fail("Exception expected");
                } catch (RuntimeException e) {
-                       assertEquals("Invalid type passed to 
headers(Object...):  java.lang.String", e.getLocalizedMessage());
+                       assertEquals("Invalid type passed to headers():  
java.lang.String", e.getLocalizedMessage());
                }
        }
 
@@ -2837,7 +2837,7 @@ public class RestClientTest {
                                .headerPairs("Foo");
                        fail("Exception expected");
                } catch (RuntimeException e) {
-                       assertEquals("Odd number of parameters passed into 
headerPairs(Object...)", e.getLocalizedMessage());
+                       assertEquals("Odd number of parameters passed into 
headerPairs()", e.getLocalizedMessage());
                }
        }
 
@@ -2992,7 +2992,7 @@ public class RestClientTest {
                                .queries(BasicNameValuePair.of("Foo","bar"), 
"Baz");
                        fail();
                } catch (Exception e) {
-                       assertEquals("Invalid type passed to query(Object...):  
java.lang.String", e.getMessage());
+                       assertEquals("Invalid type passed to query():  
java.lang.String", e.getMessage());
                }
        }
 
@@ -3033,6 +3033,83 @@ public class RestClientTest {
                }
        }
 
+       public static class I11 {
+               public String foo;
+
+               I11 init() {
+                       this.foo = "baz";
+                       return this;
+               }
+       }
+
+       @Test
+       public void i11_query_request() throws Exception {
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/echo")
+                       .query("foo", "bar")
+                       .run()
+                       .assertBody().contains("GET /echo?foo=bar");
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/echo")
+                       .query("foo", AList.of("bar","baz"), 
HttpPartSchema.T_ARRAY_PIPES)
+                       .run()
+                       .assertBody().contains("GET /echo?foo=bar%7Cbaz");
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .query("foo","bar")
+                       .build()
+                       .get("/echo")
+                       .query(EnumSet.of(AddFlag.PREPEND), "foo", "baz")
+                       .run()
+                       .assertBody().contains("GET /echo?foo=baz&foo=bar");
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .query("foo","bar")
+                       .build()
+                       .get("/echo")
+                       .query(EnumSet.of(AddFlag.PREPEND), "foo", 
AList.of("baz","qux"), HttpPartSchema.T_ARRAY_PIPES)
+                       .run()
+                       .assertBody().contains("GET 
/echo?foo=baz%7Cqux&foo=bar");
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .query("foo","bar")
+                       .build()
+                       .get("/echo")
+                       .queries(BasicNameValuePair.of("foo","baz"), 
NameValuePairs.of("foo","qux"), OMap.of("foo","quux"))
+                       .run()
+                       .assertBody().contains("GET 
/echo?foo=bar&foo=baz&foo=qux&foo=quux");
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .query("foo","bar")
+                       .build()
+                       .get("/echo")
+                       .queries(new I11().init())
+                       .run()
+                       .assertBody().contains("GET /echo?foo=bar&foo=baz");
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .simpleJson()
+                               .build()
+                               .get("/echo")
+                               .queries("foo=baz")
+                               .run();
+                       fail();
+               } catch (RestCallException e) {
+                       assertEquals("Invalid type passed to queries(): 
java.lang.String", e.getMessage());
+               }
+       }
+
        
//-----------------------------------------------------------------------------------------------------------------
        // Form data
        
//-----------------------------------------------------------------------------------------------------------------
@@ -3181,7 +3258,7 @@ public class RestClientTest {
                                .formDatas(BasicNameValuePair.of("Foo","bar"), 
"Baz");
                        fail();
                } catch (Exception e) {
-                       assertEquals("Invalid type passed to 
formData(Object...):  java.lang.String", e.getMessage());
+                       assertEquals("Invalid type passed to formData():  
java.lang.String", e.getMessage());
                }
        }
 
@@ -6423,9 +6500,9 @@ public class RestClientTest {
        
//-----------------------------------------------------------------------------------------------------------------
 
        public static class Q01 {
-               public int foo;
+               public int x;
                public Q01 init() {
-                       foo = 1;
+                       x = 1;
                        return this;
                }
 
@@ -6444,82 +6521,116 @@ public class RestClientTest {
                        .get("/echo/{x}")
                        .path("x", new Q01().init())
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo=1")
+                       .assertBody().contains("HTTP GET /echo/x=1")
                ;
                MockRestClient
                        .create(A.class)
                        .simpleJson()
                        .build()
                        .get("/echo/{x}")
-                       .path("x", ()->new Q01().init())
+                       .path(BasicNameValuePair.of("x","foo"))
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo=1")
+                       .assertBody().contains("HTTP GET /echo/foo")
                ;
                MockRestClient
                        .create(A.class)
                        .simpleJson()
                        .build()
-                       .get("/echo/*")
-                       .path("/*", new Q01().init())
+                       .get("/echo/{x}")
+                       .paths(BasicNameValuePair.of("x","foo"))
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo=1")
+                       .assertBody().contains("HTTP GET /echo/foo")
                ;
                MockRestClient
                        .create(A.class)
                        .simpleJson()
                        .build()
-                       .get("/echo/*")
-                       .path("/*", ()->new Q01().init())
+                       .get("/echo/{x}")
+                       .paths(NameValuePairs.of("x","foo"))
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo=1")
-                       ;
-       }
-
-       @Test
-       public void q03_request_path_withSchema() throws Exception {
-               String[] a = new String[]{"foo","bar"};
-
+                       .assertBody().contains("HTTP GET /echo/foo")
+               ;
                MockRestClient
                        .create(A.class)
                        .simpleJson()
                        .build()
                        .get("/echo/{x}")
-                       .path("x", a, HttpPartSchema.T_ARRAY_PIPES)
+                       .paths(OMap.of("x","foo"))
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo%7Cbar")
+                       .assertBody().contains("HTTP GET /echo/foo")
                ;
                MockRestClient
                        .create(A.class)
                        .simpleJson()
                        .build()
                        .get("/echo/{x}")
-                       .path("x", ()->a, HttpPartSchema.T_ARRAY_PIPES)
+                       .paths(new Q01().init())
                        .run()
-                       .assertBody().contains("HTTP GET /echo/foo%7Cbar")
+                       .assertBody().contains("HTTP GET /echo/1")
+               ;
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/echo/{x}")
+                       .pathPairs("x", 1)
+                       .run()
+                       .assertBody().contains("HTTP GET /echo/1")
+               ;
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/echo/*")
+                       .path("/*", new Q01().init())
+                       .run()
+                       .assertBody().contains("HTTP GET /echo/x=1")
                ;
-       }
-
-       @Test
-       public void q04_request_path_invalid() throws Exception {
                try {
                        MockRestClient
                                .create(A.class)
                                .simpleJson()
                                .build()
                                .get("/echo/{x}")
-                               .path("y", "foo")
+                               .paths("x")
                                .run()
-                               .assertBody().contains("HTTP GET 
/echo/foo%7Cbar")
                        ;
                        fail();
                } catch (RestCallException e) {
-                       assertEquals("Path variable {y} was not found in 
path.", e.getMessage());
+                       assertEquals("Invalid type passed to path(): 
java.lang.String", e.getMessage());
+               }
+               try {
+                       MockRestClient
+                               .create(A.class)
+                               .simpleJson()
+                               .build()
+                               .get("/echo/{x}")
+                               .pathPairs("x")
+                               .run()
+                       ;
+                       fail();
+               } catch (RestCallException e) {
+                       assertEquals("Odd number of parameters passed into 
pathPairs()", e.getMessage());
                }
        }
 
+       @Test
+       public void q03_request_path_withSchema() throws Exception {
+               String[] a = new String[]{"foo","bar"};
+
+               MockRestClient
+                       .create(A.class)
+                       .simpleJson()
+                       .build()
+                       .get("/echo/{x}")
+                       .path("x", a, HttpPartSchema.T_ARRAY_PIPES)
+                       .run()
+                       .assertBody().contains("HTTP GET /echo/foo%7Cbar")
+               ;
+       }
 
        @Test
-       public void q05_request_path_invalid() throws Exception {
+       public void q04_request_path_invalid() throws Exception {
                try {
                        MockRestClient
                                .create(A.class)
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
index fa9a63f..1a76f8b 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClient.java
@@ -15,7 +15,6 @@ package org.apache.juneau.rest.client2;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.AddFlag.*;
 import static org.apache.juneau.httppart.HttpPartType.*;
-import static org.apache.juneau.rest.client2.RestClientUtils.*;
 import static java.util.logging.Level.*;
 import static org.apache.juneau.internal.StateMachineState.*;
 import static java.lang.Character.*;
@@ -56,6 +55,8 @@ import org.apache.juneau.assertions.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.http.remote.RemoteReturn;
 import org.apache.juneau.http.*;
+import org.apache.juneau.http.BasicNameValuePair;
+import org.apache.juneau.http.header.BasicHeader;
 import org.apache.juneau.http.remote.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.httppart.bean.*;
@@ -323,7 +324,6 @@ import org.apache.http.client.CookieStore;
  *             <li class='jm'>{@link RestRequest#header(EnumSet,String,Object) 
header(EnumSet&gt;AddFlag&gt;,String,Object)}
  *             <li class='jm'>{@link RestRequest#header(Header) header(Header)}
  *             <li class='jm'>{@link RestRequest#header(NameValuePair) 
header(NameValuePair)}
- *             <li class='jm'>{@link RestRequest#header(EnumSet,Object) 
header(EnumSet&gt;AddFlag&gt;,Object)}
  *             <li class='jm'>{@link RestRequest#headers(Object...) 
headers(Object...)}
  *             <li class='jm'>{@link RestRequest#headers(EnumSet,Object...) 
headers(EnumSet&gt;AddFlag&gt;Object...)}
  *             <li class='jm'>{@link RestRequest#headerPairs(Object...) 
headers(Object...)}
@@ -413,7 +413,7 @@ import org.apache.http.client.CookieStore;
  *             <li class='jm'>{@link RestRequest#query(String,Object) 
query(String,Object)}
  *             <li class='jm'>{@link RestRequest#query(EnumSet,String,Object) 
query(EnumSet&lt;AddFlag&gt;,String,Object)}
  *             <li class='jm'>{@link RestRequest#queries(Object...) 
queries(Object...)}
- *             <li class='jm'>{@link RestRequest#query(EnumSet,Object...) 
query(EnumSet&lt;AddFlag&gt;,Object...)}
+ *             <li class='jm'>{@link RestRequest#queries(EnumSet,Object...) 
queries(EnumSet&lt;AddFlag&gt;,Object...)}
  *             <li class='jm'>{@link RestRequest#queryPairs(Object...) 
queryPairs(Object...)}
  *             <li class='jm'>{@link RestRequest#queryCustom(Object) 
queryCustom(Object)}
  *     </ul>
@@ -452,7 +452,7 @@ import org.apache.http.client.CookieStore;
  *             <li class='jm'>{@link RestRequest#formData(String,Object) 
formData(String,Object)}
  *             <li class='jm'>{@link 
RestRequest#formData(EnumSet,String,Object) 
formData(EnumSet&lt;AddFlag&gt;,String,Object)}
  *             <li class='jm'>{@link RestRequest#formDatas(Object...) 
formDatas(Object...)}
- *             <li class='jm'>{@link RestRequest#formData(EnumSet,Object...) 
formData(EnumSet&lt;AddFlag&gt;,Object...)}
+ *             <li class='jm'>{@link RestRequest#formDatas(EnumSet,Object...) 
formDatas(EnumSet&lt;AddFlag&gt;,Object...)}
  *             <li class='jm'>{@link RestRequest#formDataPairs(Object...) 
formDataPairs(Object...)}
  *             <li class='jm'>{@link RestRequest#formDataCustom(Object) 
formDataCustom(Object)}
  *     </ul>
@@ -1168,7 +1168,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formData(String,Object) 
formData(String,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formData(EnumSet,String,Object) 
formData(EnumSet&lt;AddFlag&gt;,String,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formDatas(Object...) 
formDatas(Object...)}
-        *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formData(EnumSet,Object...) 
formData(EnumSet&lt;AddFlag&gt;Object...)}
+        *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formDatas(EnumSet,Object...) 
formDatas(EnumSet&lt;AddFlag&gt;Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formDataPairs(Object...) 
formDataPairs(Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#formDataCustom(Object) 
formDataCustom(Object)}
         *                      </ul>
@@ -1238,7 +1238,6 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#header(EnumSet,String,Object) 
header(EnumSet&gt;AddFlag&gt;,String,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#header(Header) header(Header)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#header(NameValuePair) 
header(NameValuePair)}
-        *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#header(EnumSet,Object) 
header(EnumSet&gt;AddFlag&gt;,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#headers(Object...) 
headers(Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#headers(EnumSet,Object...) 
headers(EnumSet&gt;AddFlag&gt;,Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#headerPairs(Object...) 
headerPairs(Object...)}
@@ -1772,7 +1771,7 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#query(String,Object) 
query(String,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#query(EnumSet,String,Object) 
query(EnumSet&lt;AddFlag&gt;,String,Object)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#queries(Object...) 
queries(Object...)}
-        *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#query(EnumSet,Object...) 
query(EnumSet&lt;AddFlag&gt;,Object...)}
+        *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#queries(EnumSet,Object...) 
queries(EnumSet&lt;AddFlag&gt;,Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#queryPairs(Object...) 
queryPairs(Object...)}
         *                              <li class='jm'>{@link 
org.apache.juneau.rest.client2.RestRequest#queryCustom(Object) 
queryCustom(Object)}
         *                      </ul>
@@ -1984,7 +1983,16 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
 
                HttpPartSerializerSession partSerializerSession = 
partSerializer.createPartSession(null);
 
-               Function<Object,Object> f = x -> x instanceof 
SerializedNameValuePair.Builder ? 
((SerializedNameValuePair.Builder)x).serializer(partSerializerSession, 
false).build() : x;
+               Function<Object,Object> f = new Function<Object,Object>() {
+                       @Override
+                       public Object apply(Object x) {
+                               if (x instanceof 
SerializedNameValuePair.Builder)
+                                       return 
((SerializedNameValuePair.Builder)x).serializer(partSerializerSession, 
false).build();
+                               if (x instanceof SerializedHeader.Builder)
+                                       return 
((SerializedHeader.Builder)x).serializer(partSerializerSession, false).build();
+                               return x;
+                       }
+               };
 
                this.headers = Collections.unmodifiableList(
                        getListProperty(RESTCLIENT_headers, Object.class)
@@ -2844,10 +2852,10 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                        req.header(toHeader(o));
 
                for (Object o : query)
-                       req.query(toQuery(o));
+                       req.query(toNameValuePair(o));
 
                for (Object o : formData)
-                       req.formData(toFormData(o));
+                       req.formData(toNameValuePair(o));
 
                onInit(req);
 
@@ -3005,16 +3013,16 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                        rc.parser(parser);
 
                                        for (RemoteMethodArg a : 
rmm.getPathArgs())
-                                               rc.path(a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
+                                               rc.pathArg(a.getName(), 
args[a.getIndex()], a.getSchema(), a.getSerializer(s));
 
                                        for (RemoteMethodArg a : 
rmm.getQueryArgs())
-                                               rc.query(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
+                                               rc.queryArg(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
 
                                        for (RemoteMethodArg a : 
rmm.getFormDataArgs())
-                                               rc.formData(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
+                                               
rc.formDataArg(a.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, 
a.getName(), args[a.getIndex()], a.getSchema(), a.getSerializer(s));
 
                                        for (RemoteMethodArg a : 
rmm.getHeaderArgs())
-                                               rc.header(a.isSkipIfEmpty() ? 
SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
+                                               rc.headerArg(a.isSkipIfEmpty() 
? SKIP_IF_EMPTY_FLAGS : DEFAULT_FLAGS, a.getName(), args[a.getIndex()], 
a.getSchema(), a.getSerializer(s));
 
                                        RemoteMethodArg ba = rmm.getBodyArg();
                                        if (ba != null)
@@ -3033,14 +3041,14 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                                                                        
HttpPartSchema schema = p.getSchema();
                                                                        
EnumSet<AddFlag> flags = schema.isSkipIfEmpty() ? SKIP_IF_EMPTY_FLAGS : 
DEFAULT_FLAGS;
                                                                        if (pt 
== PATH)
-                                                                               
rc.path(pn, val, schema, p.getSerializer(s));
+                                                                               
rc.pathArg(pn, val, schema, p.getSerializer(s));
                                                                        else if 
(val != null) {
                                                                                
if (pt == QUERY)
-                                                                               
        rc.query(flags, pn, val, schema, ps);
+                                                                               
        rc.queryArg(flags, pn, val, schema, ps);
                                                                                
else if (pt == FORMDATA)
-                                                                               
        rc.formData(flags, pn, val, schema, ps);
+                                                                               
        rc.formDataArg(flags, pn, val, schema, ps);
                                                                                
else if (pt == HEADER)
-                                                                               
        rc.header(flags, pn, val, schema, ps);
+                                                                               
        rc.headerArg(flags, pn, val, schema, ps);
                                                                                
else /* (pt == HttpPartType.BODY) */
                                                                                
        rc.body(val, schema);
                                                                        }
@@ -3693,6 +3701,22 @@ public class RestClient extends BeanContext implements 
HttpClient, Closeable, Re
                return (T)o;
        }
 
+       private static Header toHeader(Object o) {
+               if (o instanceof Header)
+                       return (Header)o;
+               if (o instanceof Headerable)
+                       return ((Headerable)o).asHeader();
+               if (o instanceof NameValuePair)
+                       return BasicHeader.of((NameValuePair)o);
+               return null;
+       }
+
+       private static NameValuePair toNameValuePair(Object o) {
+               if (o instanceof NameValuePair)
+                       return (NameValuePair)o;
+               return null;
+       }
+
        @Override /* Context */
        public OMap toMap() {
                return super.toMap()
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
index 5bb4302..f9effa6 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientBuilder.java
@@ -48,6 +48,7 @@ import org.apache.http.conn.util.*;
 import org.apache.http.cookie.*;
 import org.apache.http.impl.client.*;
 import org.apache.http.impl.conn.*;
+import org.apache.juneau.http.header.BasicHeader;
 import org.apache.http.protocol.*;
 import org.apache.juneau.*;
 import org.apache.juneau.annotation.*;
@@ -1087,7 +1088,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Object value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_headers, 
SerializedNameValuePair.create().name(name).value(value).type(HEADER).serializer(serializer).schema(schema));
+               return headers(serializedHeader(name, value, serializer, 
schema));
        }
 
        /**
@@ -1123,7 +1124,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Supplier<?> value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_headers, 
SerializedNameValuePair.create().name(name).value(value).type(HEADER).serializer(serializer).schema(schema));
+               return headers(serializedHeader(name, value, serializer, 
schema));
        }
 
        /**
@@ -1155,7 +1156,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Object value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_headers, 
SerializedNameValuePair.create().name(name).value(value).type(HEADER).schema(schema));
+               return headers(serializedHeader(name, value, null, schema));
        }
 
        /**
@@ -1187,7 +1188,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Supplier<?> value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_headers, 
SerializedNameValuePair.create().name(name).value(value).type(HEADER).schema(schema));
+               return headers(serializedHeader(name, value, null, schema));
        }
 
        /**
@@ -1216,7 +1217,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Object value) {
-               return header(name, value, null, null);
+               return headers(serializedHeader(name, value, null, null));
        }
 
        /**
@@ -1245,7 +1246,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(String name, Supplier<?> value) {
-               return header(name, value, (HttpPartSchema)null, null);
+               return headers(serializedHeader(name, value, null, null));
        }
 
        /**
@@ -1264,7 +1265,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(Header header) {
-               return appendTo(RESTCLIENT_headers, header);
+               return headers(header);
        }
 
        /**
@@ -1283,7 +1284,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder header(NameValuePair pair) {
-               return appendTo(RESTCLIENT_headers, pair);
+               return headers(pair);
        }
 
        /**
@@ -1323,19 +1324,21 @@ public class RestClientBuilder extends 
BeanContextBuilder {
        @FluentSetter
        public RestClientBuilder headers(Object...headers) {
                for (Object h : headers) {
-                       if (h instanceof Header)
-                               header((Header)h);
-                       else if (h instanceof NameValuePair)
-                               header((NameValuePair)h);
-                       else if (h instanceof Map) {
-                               Map m = (Map)h;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       header(stringify(e.getKey()), 
e.getValue(), null, null);
+                       if (h instanceof Header || h instanceof 
SerializedHeader.Builder || h instanceof SerializedNameValuePair.Builder)
+                               appendTo(RESTCLIENT_headers, h);
+                       else if (h instanceof Headerable)
+                               appendTo(RESTCLIENT_headers, 
((Headerable)h).asHeader());
+                       else if (h instanceof NameValuePair) {
+                               NameValuePair p = (NameValuePair)h;
+                               appendTo(RESTCLIENT_headers, new 
BasicHeader(p.getName(), p.getValue()));
+                       } else if (h instanceof Map) {
+                               for (Map.Entry e : toMap(h).entrySet())
+                                       appendTo(RESTCLIENT_headers, 
serializedHeader(e.getKey(), e.getValue(), null, null));
                        } else if (h instanceof NameValuePairs) {
                                for (NameValuePair p : (NameValuePairs)h)
-                                       header(p);
+                                       headers(p);
                        } else if (h != null) {
-                               throw new RuntimeException("Invalid type passed 
to headers(Object...):  " + h.getClass().getName());
+                               throw new RuntimeException("Invalid type passed 
to headers():  " + h.getClass().getName());
                        }
                }
                return this;
@@ -1363,9 +1366,9 @@ public class RestClientBuilder extends BeanContextBuilder 
{
        @FluentSetter
        public RestClientBuilder headerPairs(Object...pairs) {
                if (pairs.length % 2 != 0)
-                       throw new RuntimeException("Odd number of parameters 
passed into headerPairs(Object...)");
+                       throw new RuntimeException("Odd number of parameters 
passed into headerPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       header(stringify(pairs[i]), pairs[i+1]);
+                       headers(serializedHeader(pairs[i], pairs[i+1], null, 
null));
                return this;
        }
 
@@ -1868,7 +1871,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Object value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_query, 
SerializedNameValuePair.create().name(name).value(value).type(QUERY).serializer(serializer).schema(schema));
+               return queries(serializedNameValuePair(name, value, QUERY, 
serializer, schema));
        }
 
        /**
@@ -1904,7 +1907,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Supplier<?> value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_query, 
SerializedNameValuePair.create().name(name).value(value).type(QUERY).serializer(serializer).schema(schema));
+               return queries(serializedNameValuePair(name, value, QUERY, 
serializer, schema));
        }
 
        /**
@@ -1936,7 +1939,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Object value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_query, 
SerializedNameValuePair.create().name(name).value(value).type(QUERY).schema(schema));
+               return queries(serializedNameValuePair(name, value, QUERY, 
null, schema));
        }
 
        /**
@@ -1968,7 +1971,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Supplier<?> value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_query, 
SerializedNameValuePair.create().name(name).value(value).type(QUERY).schema(schema));
+               return queries(serializedNameValuePair(name, value, QUERY, 
null, schema));
        }
 
        /**
@@ -1993,7 +1996,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Object value) {
-               return query(name, value, null, null);
+               return queries(serializedNameValuePair(name, value, QUERY, 
null, null));
        }
 
        /**
@@ -2037,7 +2040,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder query(String name, Supplier<?> value) {
-               return query(name, value, (HttpPartSchema)null, null);
+               return queries(serializedNameValuePair(name, value, QUERY, 
null, null));
        }
 
        /**
@@ -2076,17 +2079,16 @@ public class RestClientBuilder extends 
BeanContextBuilder {
        @FluentSetter
        public RestClientBuilder queries(Object...params) {
                for (Object p : params) {
-                       if (p instanceof NameValuePair) {
+                       if (p instanceof NameValuePair || p instanceof 
SerializedNameValuePair.Builder) {
                                appendTo(RESTCLIENT_query, p);
                        } else if (p instanceof Map) {
-                               Map m = (Map)p;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       query(stringify(e.getKey()), 
e.getValue(), null, null);
+                               for (Map.Entry e : toMap(p).entrySet())
+                                       appendTo(RESTCLIENT_query, 
serializedNameValuePair(e.getKey(), e.getValue(), QUERY, null, null));
                        } else if (p instanceof NameValuePairs) {
                                for (NameValuePair nvp : (NameValuePairs)p)
-                                       queries(nvp);
+                                       appendTo(RESTCLIENT_query, nvp);
                        } else if (p != null) {
-                               throw new RuntimeException("Invalid type passed 
to query(Object...):  " + p.getClass().getName());
+                               throw new RuntimeException("Invalid type passed 
to query():  " + p.getClass().getName());
                        }
                }
                return this;
@@ -2116,7 +2118,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
                if (pairs.length % 2 != 0)
                        throw new RuntimeException("Odd number of parameters 
passed into queryPairs(Object...)");
                for (int i = 0; i < pairs.length; i+=2)
-                       query(stringify(pairs[i]), pairs[i+1]);
+                       queries(serializedNameValuePair(pairs[i], pairs[i+1], 
QUERY, null, null));
                return this;
        }
 
@@ -2157,7 +2159,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Object value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_formData, 
SerializedNameValuePair.create().name(name).value(value).type(FORMDATA).serializer(serializer).schema(schema));
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
serializer, schema));
        }
 
        /**
@@ -2193,7 +2195,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Supplier<?> value, 
HttpPartSchema schema, HttpPartSerializer serializer) {
-               return appendTo(RESTCLIENT_formData, 
SerializedNameValuePair.create().name(name).value(value).type(FORMDATA).serializer(serializer).schema(schema));
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
serializer, schema));
        }
 
        /**
@@ -2225,7 +2227,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Object value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_formData, 
SerializedNameValuePair.create().name(name).value(value).type(FORMDATA).schema(schema));
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
null, schema));
        }
 
        /**
@@ -2257,7 +2259,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Supplier<?> value, 
HttpPartSchema schema) {
-               return appendTo(RESTCLIENT_formData, 
SerializedNameValuePair.create().name(name).value(value).type(FORMDATA).schema(schema));
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
null, schema));
        }
 
        /**
@@ -2282,7 +2284,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Object value) {
-               return formData(name, value, null, null);
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
null, null));
        }
 
        /**
@@ -2326,7 +2328,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
         */
        @FluentSetter
        public RestClientBuilder formData(String name, Supplier<?> value) {
-               return formData(name, value, (HttpPartSchema)null, null);
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
null, null));
        }
 
        /**
@@ -2361,21 +2363,19 @@ public class RestClientBuilder extends 
BeanContextBuilder {
         * @param params The form-data parameter.
         * @return This object (for method chaining).
         */
-       @SuppressWarnings("rawtypes")
        @FluentSetter
        public RestClientBuilder formDatas(Object...params) {
                for (Object p : params) {
-                       if (p instanceof NameValuePair) {
+                       if (p instanceof NameValuePair || p instanceof 
SerializedNameValuePair.Builder) {
                                appendTo(RESTCLIENT_formData, p);
                        } else if (p instanceof Map) {
-                               Map m = (Map)p;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       formData(stringify(e.getKey()), 
e.getValue(), null, null);
+                               for (Map.Entry<Object,Object> e : 
toMap(p).entrySet())
+                                       appendTo(RESTCLIENT_formData, 
serializedNameValuePair(e.getKey(), e.getValue(), FORMDATA, null, null));
                        } else if (p instanceof NameValuePairs) {
                                for (NameValuePair nvp : (NameValuePairs)p)
-                                       formDatas(nvp);
+                                       appendTo(RESTCLIENT_formData, nvp);
                        } else if (p != null) {
-                               throw new RuntimeException("Invalid type passed 
to formData(Object...):  " + p.getClass().getName());
+                               throw new RuntimeException("Invalid type passed 
to formData():  " + p.getClass().getName());
                        }
                }
                return this;
@@ -2405,7 +2405,7 @@ public class RestClientBuilder extends BeanContextBuilder 
{
                if (pairs.length % 2 != 0)
                        throw new RuntimeException("Odd number of parameters 
passed into formDataPairs(Object...)");
                for (int i = 0; i < pairs.length; i+=2)
-                       formData(stringify(pairs[i]), pairs[i+1]);
+                       formDatas(serializedNameValuePair(pairs[i], pairs[i+1], 
FORMDATA, null, null));
                return this;
        }
 
@@ -5808,4 +5808,21 @@ public class RestClientBuilder extends 
BeanContextBuilder {
                httpClientBuilder.evictIdleConnections(maxIdleTime, 
maxIdleTimeUnit);
                return this;
        }
+
+       
//------------------------------------------------------------------------------------------------------------------
+       // Utility methods.
+       
//------------------------------------------------------------------------------------------------------------------
+
+       @SuppressWarnings("unchecked")
+       private static Map<Object,Object> toMap(Object o) {
+               return (Map<Object,Object>)o;
+       }
+
+       private static SerializedNameValuePair.Builder 
serializedNameValuePair(Object key, Object value, HttpPartType type, 
HttpPartSerializer serializer, HttpPartSchema schema) {
+               return 
SerializedNameValuePair.create().name(stringify(key)).value(value).type(type).serializer(serializer).schema(schema);
+       }
+
+       private static SerializedHeader.Builder serializedHeader(Object key, 
Object value, HttpPartSerializer serializer, HttpPartSchema schema) {
+               return 
SerializedHeader.create().name(stringify(key)).value(value).serializer(serializer).schema(schema);
+       }
 }
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientUtils.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientUtils.java
deleted file mode 100644
index 56593e2..0000000
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestClientUtils.java
+++ /dev/null
@@ -1,103 +0,0 @@
-// 
***************************************************************************************************************************
-// * Licensed to the Apache Software Foundation (ASF) under one or more 
contributor license agreements.  See the NOTICE file *
-// * distributed with this work for additional information regarding copyright 
ownership.  The ASF licenses this file        *
-// * to you under the Apache License, Version 2.0 (the "License"); you may not 
use this file except in compliance            *
-// * with the License.  You may obtain a copy of the License at                
                                              *
-// *                                                                           
                                              *
-// *  http://www.apache.org/licenses/LICENSE-2.0                               
                                              *
-// *                                                                           
                                              *
-// * Unless required by applicable law or agreed to in writing, software 
distributed under the License is distributed on an  *
-// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either 
express or implied.  See the License for the        *
-// * specific language governing permissions and limitations under the 
License.                                              *
-// 
***************************************************************************************************************************
-package org.apache.juneau.rest.client2;
-
-import static org.apache.juneau.AddFlag.*;
-import static org.apache.juneau.httppart.HttpPartType.*;
-import static org.apache.juneau.internal.StringUtils.*;
-
-import java.util.*;
-
-import org.apache.http.*;
-import org.apache.http.message.BasicHeader;
-import org.apache.juneau.*;
-import org.apache.juneau.http.*;
-import org.apache.juneau.httppart.*;
-
-/**
- * Static utility methods shared by mutiple classes.
- */
-class RestClientUtils {
-
-       static Header toHeader(Object o) {
-               if (o instanceof Header)
-                       return (Header)o;
-               if (o instanceof NameValuePair) {
-                       NameValuePair p = (NameValuePair)o;
-                       return new BasicHeader(p.getName(), p.getValue());
-               }
-               return null;
-       }
-
-       static NameValuePair toQuery(Object o) {
-               if (o instanceof NameValuePair)
-                       return (NameValuePair)o;
-               return null;
-       }
-
-       static NameValuePair toFormData(Object o) {
-               if (o instanceof NameValuePair)
-                       return (NameValuePair)o;
-               return null;
-       }
-
-       static List<Header> toHeaders(NameValuePair...pairs) {
-               List<Header> l = new ArrayList<>();
-               for (NameValuePair p : pairs)
-                       l.add(toHeader(p));
-               return l;
-       }
-
-       static List<Header> toHeaders(NameValuePairs pairs) {
-               List<Header> l = new ArrayList<>();
-               for (NameValuePair p : pairs)
-                       l.add(toHeader(p));
-               return l;
-       }
-
-       static Header toHeader(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               return new SerializedHeader(name, value, serializer, schema, 
flags.contains(SKIP_IF_EMPTY));
-       }
-
-       static NameValuePair toQuery(EnumSet<AddFlag> flags, String name, 
Object value, HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               return new SerializedNameValuePair(name, value, QUERY,  
serializer, schema, flags.contains(SKIP_IF_EMPTY));
-       }
-
-       static NameValuePair toFormData(EnumSet<AddFlag> flags, String name, 
Object value, HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               return new SerializedNameValuePair(name, value, FORMDATA,  
serializer, schema, flags.contains(SKIP_IF_EMPTY));
-       }
-
-       @SuppressWarnings("rawtypes")
-       static List<Header> toHeaders(EnumSet<AddFlag> flags, Map headers, 
HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               List<Header> l = new ArrayList<>();
-               for (Map.Entry e : (Set<Map.Entry>)headers.entrySet())
-                       l.add(new SerializedHeader(stringify(e.getKey()), 
e.getValue(), serializer, null, flags.contains(SKIP_IF_EMPTY)));
-               return l;
-       }
-
-       @SuppressWarnings("rawtypes")
-       static List<NameValuePair> toQuery(EnumSet<AddFlag> flags, Map params, 
HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               List<NameValuePair> l = new ArrayList<>();
-               for (Map.Entry e : (Set<Map.Entry>)params.entrySet())
-                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), QUERY, serializer, 
null, flags.contains(SKIP_IF_EMPTY)));
-               return l;
-       }
-
-       @SuppressWarnings("rawtypes")
-       static List<NameValuePair> toFormData(EnumSet<AddFlag> flags, Map 
params, HttpPartSerializerSession serializer, HttpPartSchema schema) {
-               List<NameValuePair> l = new ArrayList<>();
-               for (Map.Entry e : (Set<Map.Entry>)params.entrySet())
-                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), FORMDATA, 
serializer, null, flags.contains(SKIP_IF_EMPTY)));
-               return l;
-       }
-}
diff --git 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
index b834687..08380bc 100644
--- 
a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
+++ 
b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client2/RestRequest.java
@@ -15,7 +15,6 @@ package org.apache.juneau.rest.client2;
 import static org.apache.juneau.internal.StringUtils.*;
 import static org.apache.juneau.AddFlag.*;
 import static org.apache.juneau.httppart.HttpPartType.*;
-import static org.apache.juneau.rest.client2.RestClientUtils.*;
 
 import java.io.*;
 import java.net.*;
@@ -33,13 +32,13 @@ import org.apache.http.client.utils.*;
 import org.apache.http.concurrent.*;
 import org.apache.http.entity.*;
 import org.apache.http.entity.ContentType;
+import org.apache.juneau.http.header.BasicHeader;
 import org.apache.http.params.*;
 import org.apache.http.protocol.*;
 import org.apache.juneau.*;
 import org.apache.juneau.collections.*;
 import org.apache.juneau.html.*;
 import org.apache.juneau.http.*;
-import org.apache.juneau.http.header.*;
 import org.apache.juneau.httppart.*;
 import org.apache.juneau.internal.*;
 import org.apache.juneau.json.*;
@@ -47,7 +46,6 @@ import org.apache.juneau.msgpack.*;
 import org.apache.juneau.oapi.*;
 import org.apache.juneau.parser.*;
 import org.apache.juneau.plaintext.*;
-import org.apache.juneau.reflect.*;
 import org.apache.juneau.serializer.*;
 import org.apache.juneau.uon.*;
 import org.apache.juneau.urlencoding.*;
@@ -863,6 +861,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Sets path to "/bar".</jc>
         *      client
         *              .get(<js>"/{foo}"</js>)
         *              .path(<js>"foo"</js>, <js>"bar"</js>)
@@ -872,15 +871,14 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @param name The parameter name.
         * @param value The parameter value.
         *      <ul>
-        *              <li>Can be any POJO.
-        *              <li>Converted to a string using the specified part 
serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest path(String name, Object value) throws 
RestCallException {
-               return path(name, value, null, partSerializer);
+               return paths(serializedNameValuePair(name, value, PATH, 
partSerializer, null, null));
        }
 
        /**
@@ -888,6 +886,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Sets path to "/bar".</jc>
         *      client
         *              .get(<js>"/{foo}"</js>)
         *              .path(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, 
<js>"bar"</js>))
@@ -899,7 +898,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest path(NameValuePair pair) throws RestCallException {
-               return innerPath(pair);
+               return paths(pair);
        }
 
        /**
@@ -907,90 +906,28 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Sets path to "/bar|baz".</jc>
         *      client
         *              .get(<js>"/{foo}"</js>)
-        *              .path(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
+        *              .path(
+        *                      <js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
         *              .run();
         * </p>
         *
-        * @param name
-        *      The parameter name.
-        *      <br>Can also be <js>"/*"</js> to replace the remainder in a 
path of the form <js>"/foo/*"</js>.
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>Can be any POJO.
-        *              <li>Converted to a string using the specified part 
serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest path(String name, Supplier<?> value) throws 
RestCallException {
-               return path(name, value, null, partSerializer);
-       }
-
-       /**
-        * Replaces a path parameter of the form <js>"{name}"</js> in the URL.
-        *
-        * <p>
-        * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        * <jc>// Creates path "/bar|baz"</jc>
-        *      client
-        *              .get(<js>"/{foo}"</js>)
-        *              .path(<js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
-        *              .run();
-        * </p>
-        *
-        * @param name
-        *      The parameter name.
-        *      <br>Can also be <js>"/*"</js> to replace the remainder in a 
path of the form <js>"/foo/*"</js>.
+        * @param name The parameter name.
         * @param value The parameter value.
         *      <ul>
-        *              <li>Can be any POJO.
-        *              <li>Converted to a string using the specified part 
serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The part schema.  Can be <jk>null</jk>.
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest path(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return path(name, value, schema, partSerializer);
-       }
-
-       /**
-        * Replaces a path parameter of the form <js>"{name}"</js> in the URL.
-        *
-        * <p>
-        * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        * <jc>// Creates path "/bar|baz"</jc>
-        *      client
-        *              .get(<js>"/{foo}"</js>)
-        *              .path(<js>"foo"</js>, 
()-&gt;AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
-        *              .run();
-        * </p>
-        *
-        * @param name
-        *      The parameter name.
-        *      <br>Can also be <js>"/*"</js> to replace the remainder in a 
path of the form <js>"/foo/*"</js>.
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>Can be any POJO.
-        *              <li>Converted to a string using the specified part 
serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
-        *      </ul>
-        * @param schema The part schema.  Can be <jk>null</jk>.
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest path(String name, Supplier<?> value, HttpPartSchema 
schema) throws RestCallException {
-               return path(name, value, schema, partSerializer);
+               return paths(serializedNameValuePair(name, value, PATH, 
partSerializer, schema, null));
        }
 
        /**
@@ -998,27 +935,21 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Sets path to "/baz/qux".</jc>
         *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .path(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, 
<js>"bar"</js>))
+        *              .get(<js>"/{foo}/{bar}")
+        *              .paths(
+        *                      
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, <js>"baz"</js>),
+        *                      AMap.<jsm>of</jsm>(<js>"bar"</js>, 
<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
-        * @param params The parameters to set.
+        * @param params The path parameters to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link NameValuePair} / {@link NameValuePairs} - 
Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
@@ -1032,12 +963,11 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                for (NameValuePair p : (NameValuePairs)o)
                                        innerPath(p);
                        } else if (o instanceof Map) {
-                               Map m = (Map)o;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       innerPath(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), PATH, 
partSerializer, null, false));
+                               for (Map.Entry e : toMap(o).entrySet())
+                                       
innerPath(serializedNameValuePair(e.getKey(), e.getValue(), PATH, 
partSerializer, null, null));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       innerPath(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), PATH, 
partSerializer, null, false));
+                                       
innerPath(serializedNameValuePair(e.getKey(), e.getValue(), PATH, 
partSerializer, null, null));
                        } else {
                                throw new RestCallException("Invalid type 
passed to path(): " + o.getClass().getName());
                        }
@@ -1050,9 +980,13 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Sets path to "/baz/qux".</jc>
         *      client
         *              .get(<js>"/{foo}/{bar}"</js>)
-        *              
.path(<js>"foo"</js>,<js>"val1"</js>,<js>"bar"</js>,<js>"val2"</js>)
+        *              .pathPairs(
+        *                      <js>"foo"</js>,<js>"baz"</js>,
+        *                      <js>"bar"</js>,<js>"qux"</js>
+        *              )
         *              .run();
         * </p>
         *
@@ -1060,37 +994,34 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *      <ul>
         *              <li>Values can be any POJO.
         *              <li>Values converted to a string using the configured 
part serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest pathPairs(Object...pairs) throws RestCallException {
                if (pairs.length % 2 != 0)
-                       throw new RestCallException("Odd number of parameters 
passed into path(Object...)");
+                       throw new RestCallException("Odd number of parameters 
passed into pathPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       paths(new SerializedNameValuePair(stringify(pairs[i]), 
pairs[i+1], PATH, partSerializer, null, false));
+                       paths(serializedNameValuePair(pairs[i], pairs[i+1], 
PATH, partSerializer, null, null));
                return this;
        }
 
-       @SuppressWarnings("unchecked")
-       RestRequest path(String name, Object value, HttpPartSchema schema, 
HttpPartSerializerSession serializer) throws RestCallException {
+       RestRequest pathArg(String name, Object value, HttpPartSchema schema, 
HttpPartSerializerSession serializer) throws RestCallException {
                serializer = (serializer == null ? partSerializer : serializer);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof NameValuePairs;
-               if (! isMulti) {
-                       innerPath(new SerializedNameValuePair(name, value, 
PATH, serializer, schema, false));
-               } else if (value instanceof NameValuePairs) {
+
+               if (! isMulti)
+                       return innerPath(serializedNameValuePair(name, value, 
PATH, serializer, schema, null));
+
+               if (value instanceof NameValuePairs) {
                        for (NameValuePair p : (NameValuePairs)value)
                                innerPath(p);
                } else if (value instanceof Map) {
-                       for (Map.Entry<String,Object> p : ((Map<String,Object>) 
value).entrySet()) {
-                               String n = p.getKey();
-                               Object v = p.getValue();
-                               HttpPartSchema s = schema == null ? null : 
schema.getProperty(n);
-                               innerPath(new SerializedNameValuePair(n, v, 
PATH, serializer, s, false));
-                       }
+                       for (Map.Entry<Object,Object> p : 
toMap(value).entrySet())
+                               innerPath(serializedNameValuePair(p.getKey(), 
p.getValue(), PATH, serializer, schema, null));
                } else if (isBean(value)) {
-                       return path(name, toBeanMap(value), schema, serializer);
+                       for (Map.Entry<String,Object> p : 
toBeanMap(value).entrySet())
+                               innerPath(serializedNameValuePair(p.getKey(), 
p.getValue(), PATH, serializer, schema, null));
                } else if (value != null) {
                        throw new RestCallException("Invalid name ''{0}'' 
passed to path(name,value) for data type ''{1}''", name, className(value));
                }
@@ -1119,6 +1050,19 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        /**
         * Sets a query parameter on the URI.
         *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Adds query parameter "foo=bar|baz".</jc>
+        *      client
+        *              .get(<jsf>URL</jsf>)
+        *              .query(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
+        *              .run();
+        * </p>
+        *
         * @param flags Instructions on how to add this parameter.
         *      <ul>
         *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
@@ -1127,34 +1071,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The schema object that defines the format of the 
output.
         *      <ul>
@@ -1165,59 +1085,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSchema schema) throws RestCallException {
-               return query(flags, name, value, schema, partSerializer);
-       }
-
-       /**
-        * Sets a query parameter on the URI.
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The schema object that defines the format of the 
output.
-        *      <ul>
-        *              <li>If <jk>null</jk>, defaults to {@link 
HttpPartSchema#DEFAULT}.
-        *              <li>Only used if serializer is schema-aware (e.g. 
{@link OpenApiSerializer}).
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest query(EnumSet<AddFlag> flags, String name, 
Supplier<?> value, HttpPartSchema schema) throws RestCallException {
-               return query(flags, name, value, schema, partSerializer);
+               return queries(flags, serializedNameValuePair(name, value, 
QUERY, partSerializer, schema, null));
        }
 
        /**
@@ -1225,6 +1093,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameter "foo=bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
         *              .query(<js>"foo"</js>, <js>"bar"</js>)
@@ -1232,40 +1101,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * </p>
         *
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(String name, Object value) throws 
RestCallException {
-               return query(DEFAULT_FLAGS, name, value, null, partSerializer);
+               return queries(serializedNameValuePair(name, value, QUERY, 
partSerializer, null, null));
        }
 
        /**
@@ -1273,6 +1118,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameter "foo=bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
         *              .query(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, 
<js>"bar"</js>))
@@ -1290,54 +1136,6 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        /**
         * Adds a query parameter to the URI.
         *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .query(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest query(String name, Supplier<?> value) throws 
RestCallException {
-               return query(DEFAULT_FLAGS, name, value, null, partSerializer);
-       }
-
-       /**
-        * Adds a query parameter to the URI.
-        *
         * <p>
         * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
         *
@@ -1346,109 +1144,39 @@ public class RestRequest extends BeanSession 
implements HttpUriRequest, Configur
         *      <jc>// Creates query parameter "foo=bar|baz"</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .query(<js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
+        *              .query(
+        *                      <js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
         *              .run();
         * </p>
         *
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The HTTP part schema.  Can be <jk>null</jk>.
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return query(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
+               return queries(serializedNameValuePair(name, value, QUERY, 
partSerializer, schema, null));
        }
 
        /**
         * Adds a query parameter to the URI.
         *
-        * <p>
-        * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
-        *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
-        *      <jc>// Creates query parameter "foo=bar|baz"</jc>
+        *      <jc>// Adds query parameter "foo=bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .query(<js>"foo"</js>, 
()-&gt;AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
-        *              .run();
-        * </p>
-        *
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The HTTP part schema.  Can be <jk>null</jk>.
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest query(String name, Supplier<?> value, HttpPartSchema 
schema) throws RestCallException {
-               return query(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
-       }
-
-       /**
-        * Adds a query parameter to the URI.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .query(<js>"foo"</js>, <js>"bar"</js>)
+        *              .query(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"foo"</js>, <js>"bar"</js>
+        *              )
         *              .run();
         * </p>
         *
@@ -1460,95 +1188,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest query(EnumSet<AddFlag> flags, String name, Object 
value) throws RestCallException {
-               return query(flags, name, value, null, partSerializer);
-       }
-
-       /**
-        * Adds a query parameter to the URI.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .query(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest query(EnumSet<AddFlag> flags, String name, 
Supplier<?> value) throws RestCallException {
-               return query(flags, name, value, null, partSerializer);
+               return queries(flags, serializedNameValuePair(name, value, 
QUERY, partSerializer, null, null));
        }
 
        /**
@@ -1556,33 +1205,27 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameters "foo=bar&baz=qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .query(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, 
<js>"bar"</js>))
+        *              .queries(
+        *                      
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>),
+        *                      
AMap.<jsm>of</jsm>(<js>"baz"<j/s>,<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
         * @param params The parameters to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link NameValuePair} / {@link NameValuePairs} - 
Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest queries(Object...params) throws RestCallException {
-               return query(DEFAULT_FLAGS, params);
+               return queries(DEFAULT_FLAGS, params);
        }
 
        /**
@@ -1590,9 +1233,14 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameters "foo=bar&baz=qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.query(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),BasicNameValuePair.<jsm>of</jsm>(<js>"Foo"</js>,
 <js>"bar"</js>))
+        *              .queries(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>),
+        *                      
AMap.<jsm>of</jsm>(<js>"baz"<j/s>,<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
@@ -1606,42 +1254,27 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @param params The parameters to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link NameValuePair} / {@link NameValuePairs} - 
Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
-       @SuppressWarnings("rawtypes")
-       public RestRequest query(EnumSet<AddFlag> flags, Object...params) 
throws RestCallException {
+       public RestRequest queries(EnumSet<AddFlag> flags, Object...params) 
throws RestCallException {
                List<NameValuePair> l = new ArrayList<>();
-               boolean skipIfEmpty = flags.contains(SKIP_IF_EMPTY);
                for (Object o : params) {
                        if (o instanceof NameValuePair) {
                                l.add((NameValuePair)o);
                        } else if (o instanceof NameValuePairs) {
                                l.addAll((NameValuePairs)o);
                        } else if (o instanceof Map) {
-                               Map m = (Map)o;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), QUERY, 
partSerializer, null, skipIfEmpty));
+                               for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
+                                       
l.add(serializedNameValuePair(e.getKey(), e.getValue(), QUERY, partSerializer, 
null, null));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), QUERY, 
partSerializer, null, skipIfEmpty));
-                       } else if (o instanceof Reader || o instanceof 
InputStream  || o instanceof CharSequence) {
-                               queryCustom(o);
+                                       
l.add(serializedNameValuePair(e.getKey(), e.getValue(), QUERY, partSerializer, 
null, null));
                        } else {
-                               throw new RestCallException("Invalid type 
passed to query(): " + o.getClass().getName());
+                               throw new RestCallException("Invalid type 
passed to queries(): " + o.getClass().getName());
                        }
                }
                return innerQuery(flags, l);
@@ -1652,37 +1285,38 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameters "foo=bar&baz=qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.queryPairs(<js>"key1"</js>,<js>"val1"</js>,<js>"key2"</js>,<js>"val2"</js>)
+        *              
.queryPairs(<js>"foo"</js>,<js>"bar"</js>,<js>"baz"</js>,<js>"qux"</js>)
         *              .run();
         * </p>
         *
-        * @param pairs The query key/value pairs.
+        * @param pairs The query key/value pairs.
         *      <ul>
         *              <li>Values can be any POJO.
         *              <li>Values converted to a string using the configured 
part serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest queryPairs(Object...pairs) throws RestCallException {
                if (pairs.length % 2 != 0)
-                       throw new RestCallException("Odd number of parameters 
passed into query(Object...)");
+                       throw new RestCallException("Odd number of parameters 
passed into queryPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       queries(new 
SerializedNameValuePair(stringify(pairs[i]), pairs[i+1], QUERY, partSerializer, 
null, false));
+                       queries(serializedNameValuePair(pairs[i], pairs[i+1], 
QUERY, partSerializer, null, null));
                return this;
        }
 
        /**
-        * Adds form-data parameters as the entire body of the request.
+        * Adds a free-form custom query.
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds query parameter "foo=bar&baz=qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .customQuery(<js>"key1=val1&key2=val2"</js>)
+        *              .queryCustom(<js>"foo=bar&baz=qux"</js>)
         *              .run();
         * </p>
         *
@@ -1717,25 +1351,31 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return this;
        }
 
-       @SuppressWarnings("unchecked")
-       RestRequest query(EnumSet<AddFlag> flags, String name, Object value, 
HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
+       RestRequest queryArg(EnumSet<AddFlag> flags, String name, Object value, 
HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
                serializer = (serializer == null ? partSerializer : serializer);
                flags = AddFlag.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof NameValuePairs;
-               if (! isMulti) {
-                       innerQuery(flags, AList.of(toQuery(flags, name, value, 
serializer, schema)));
-               } else if (value instanceof NameValuePairs) {
-                       innerQuery(flags, AList.of((NameValuePairs)value));
+
+               if (! isMulti)
+                       return innerQuery(flags, 
AList.of(serializedNameValuePair(name, value, QUERY, serializer, schema, 
flags)));
+
+               List<NameValuePair> l = AList.of();
+
+               if (value instanceof NameValuePairs) {
+                       l.addAll((NameValuePairs)value);
                } else if (value instanceof Map) {
-                       innerQuery(flags, toQuery(flags, 
(Map<String,Object>)value, serializer, schema));
+                       for (Map.Entry<Object,Object> e : 
toMap(value).entrySet())
+                               l.add(serializedNameValuePair(e.getKey(), 
e.getValue(), QUERY, serializer, schema, flags));
                } else if (isBean(value)) {
-                       query(flags, name, toBeanMap(value), schema, 
serializer);
+                       for (Map.Entry<String,Object> e : 
toBeanMap(value).entrySet())
+                               l.add(serializedNameValuePair(e.getKey(), 
e.getValue(), QUERY, serializer, schema, flags));
                } else if (value instanceof Reader || value instanceof 
InputStream || value instanceof CharSequence) {
-                       queryCustom(value);
+                       return queryCustom(value);
                } else {
                        throw new RestCallException("Invalid name ''{0}'' 
passed to query() for data type ''{1}''", name, className(value));
                }
-               return this;
+
+               return innerQuery(flags, l);
        }
 
        private RestRequest innerQuery(EnumSet<AddFlag> flags, 
List<NameValuePair> params) {
@@ -1772,6 +1412,18 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        /**
         * Adds a form-data parameter to the request body.
         *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Adds form data parameter "foo=bar|baz".</jc>
+        *      client
+        *              .formPost(<jsf>URL</jsf>)
+        *              .formData(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              .run();
+        * </p>
+        *
         * @param flags Instructions on how to add this parameter.
         *      <ul>
         *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
@@ -1780,34 +1432,10 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence} / {@link HttpEntity}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The schema object that defines the format of the 
output.
         *      <ul>
@@ -1818,59 +1446,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSchema schema) throws RestCallException {
-               return formData(flags, name, value, schema, partSerializer);
-       }
-
-       /**
-        * Adds a form-data parameter to the request body.
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence} / {@link HttpEntity}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The schema object that defines the format of the 
output.
-        *      <ul>
-        *              <li>If <jk>null</jk>, defaults to {@link 
HttpPartSchema#DEFAULT}.
-        *              <li>Only used if serializer is schema-aware (e.g. 
{@link OpenApiSerializer}).
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest formData(EnumSet<AddFlag> flags, String name, 
Supplier<?> value, HttpPartSchema schema) throws RestCallException {
-               return formData(flags, name, value, schema, partSerializer);
+               return formDatas(flags, serializedNameValuePair(name, value, 
FORMDATA, partSerializer, schema, flags));
        }
 
        /**
@@ -1878,6 +1454,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds form data parameter "foo=bar|baz".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
         *              .formData(<js>"foo"</js>, <js>"bar"</js>)
@@ -1885,40 +1462,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * </p>
         *
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(String name, Object value) throws 
RestCallException {
-               return formData(DEFAULT_FLAGS, name, value, null, 
partSerializer);
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
partSerializer, null, null));
        }
 
        /**
@@ -1926,6 +1479,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds form data parameter "foo=bar".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
         *              
.formData(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, <js>"bar"</js>))
@@ -1943,169 +1497,52 @@ public class RestRequest extends BeanSession 
implements HttpUriRequest, Configur
        /**
         * Adds a form-data parameter to the request body.
         *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .formPost(<jsf>URL</jsf>)
-        *              .formData(<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest formData(String name, Supplier<?> value) throws 
RestCallException {
-               return formData(DEFAULT_FLAGS, name, value, null, 
partSerializer);
-       }
-
-       /**
-        * Adds a form-data parameter to the request body.
-        *
         * <p>
         * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
-        *      <jc>// Creates form-data parameter "foo=bar|baz"</jc>
+        *      <jc>// Adds form data parameter "foo=bar|baz".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
-        *              .formData(<js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
+        *              .formData(
+        *                      <js>"foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
         *              .run();
         * </p>
         *
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The HTTP part schema.  Can be <jk>null</jk>.
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return formData(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
+               return formDatas(serializedNameValuePair(name, value, FORMDATA, 
partSerializer, schema, null));
        }
 
        /**
         * Adds a form-data parameter to the request body.
         *
-        * <p>
-        * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
-        *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
-        *      <jc>// Creates form-data parameter "foo=bar|baz"</jc>
+        *      <jc>// Adds form data parameter "foo=bar".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
-        *              .formData(<js>"foo"</js>, 
()-&gt;AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
+        *              .formData(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"foo"</js>, <js>"bar"</js>
+        *              )
         *              .run();
         * </p>
         *
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The HTTP part schema.  Can be <jk>null</jk>.
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest formData(String name, Supplier<?> value, 
HttpPartSchema schema) throws RestCallException {
-               return formData(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
-       }
-
-       /**
-        * Adds a form-data parameter to the request body.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .formPost(<jsf>URL</jsf>)
-        *              
.formData(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>), 
<js>"foo"</js>, <js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param flags Instructions on how to add this parameter.
+        * @param flags
+        *      Instructions on how to add this parameter.
         *      <ul>
         *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
         *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
@@ -2113,95 +1550,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
         * @param value The parameter value.
         *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest formData(EnumSet<AddFlag> flags, String name, Object 
value) throws RestCallException {
-               return formData(flags, name, value, null, partSerializer);
-       }
-
-       /**
-        * Adds a form-data parameter to the request body.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .formPost(<jsf>URL</jsf>)
-        *              
.formData(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>), 
<js>"foo"</js>, ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The parameter name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of parameters.
-        *      </ul>
-        * @param value The parameter value supplier.
-        *      <ul>
-        *              <li>For single value parameters:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value parameters:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *                      <li>{@link Reader} / {@link InputStream} / 
{@link CharSequence}
-        *                      <ul>
-        *                              <li>Sets the entire query string to the 
contents of the input.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest formData(EnumSet<AddFlag> flags, String name, 
Supplier<?> value) throws RestCallException {
-               return formData(flags, name, value, null, partSerializer);
+               return formDatas(flags, serializedNameValuePair(name, value, 
FORMDATA, partSerializer, null, flags));
        }
 
        /**
@@ -2209,43 +1567,42 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds form data parameters "foo=bar&baz=qux".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
-        *              
.formData(BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, <js>"bar"</js>))
+        *              .formDatas(
+        *                      
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>),
+        *                      
AMap.<jsm>of</jsm>(<js>"baz"<j/s>,<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
         * @param params The parameters to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link NameValuePair} / {@link NameValuePairs} - 
Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest formDatas(Object...params) throws RestCallException {
-               return formData(DEFAULT_FLAGS, params);
+               return formDatas(DEFAULT_FLAGS, params);
        }
 
        /**
-        * Adds a form-data parameter to the request body.
+        * Adds multiple form-data parameters to the request body.
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds form data parameters "foo=bar&baz=qux".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
-        *              
.formData(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>), 
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>, <js>"bar"</js>))
+        *              .formDatas(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      
BasicNameValuePair.<jsm>of</jsm>(<js>"foo"</js>,<js>"bar"</js>),
+        *                      
AMap.<jsm>of</jsm>(<js>"baz"<j/s>,<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
@@ -2259,42 +1616,27 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @param params The parameters to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link NameValuePair} / {@link NameValuePairs} - 
Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
-       @SuppressWarnings("rawtypes")
-       public RestRequest formData(EnumSet<AddFlag> flags, Object...params) 
throws RestCallException {
+       public RestRequest formDatas(EnumSet<AddFlag> flags, Object...params) 
throws RestCallException {
                List<NameValuePair> l = new ArrayList<>();
-               boolean skipIfEmpty = flags.contains(SKIP_IF_EMPTY);
                for (Object o : params) {
                        if (o instanceof NameValuePair) {
                                l.add((NameValuePair)o);
                        } else if (o instanceof NameValuePairs) {
                                l.addAll((NameValuePairs)o);
                        } else if (o instanceof Map) {
-                               Map m = (Map)o;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), FORMDATA, 
partSerializer, null, skipIfEmpty));
+                               for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
+                                       
l.add(serializedNameValuePair(e.getKey(), e.getValue(), FORMDATA, 
partSerializer, null, flags));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(new 
SerializedNameValuePair(stringify(e.getKey()), e.getValue(), FORMDATA, 
partSerializer, null, skipIfEmpty));
-                       } else if (o instanceof Reader || o instanceof 
InputStream  || o instanceof CharSequence || o instanceof HttpEntity) {
-                               formDataCustom(o);
+                                       
l.add(serializedNameValuePair(e.getKey(), e.getValue(), FORMDATA, 
partSerializer, null, flags));
                        } else {
-                               throw new RestCallException("Invalid type 
passed to formData(): " + o.getClass().getName());
+                               throw new RestCallException("Invalid type 
passed to formDatas(): " + o.getClass().getName());
                        }
                }
                return innerFormData(flags, l);
@@ -2305,6 +1647,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Creates form data "key1=val1&key2=val2".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
         *              
.formDataPairs(<js>"key1"</js>,<js>"val1"</js>,<js>"key2"</js>,<js>"val2"</js>)
@@ -2315,16 +1658,15 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *      <ul>
         *              <li>Values can be any POJO.
         *              <li>Values converted to a string using the configured 
part serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest formDataPairs(Object...pairs) throws 
RestCallException {
                if (pairs.length % 2 != 0)
-                       throw new RestCallException("Odd number of parameters 
passed into formData(Object...)");
+                       throw new RestCallException("Odd number of parameters 
passed into formDataPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       formDatas(new 
SerializedNameValuePair(stringify(pairs[i]), pairs[i+1], FORMDATA, 
partSerializer, null, false));
+                       formDatas(serializedNameValuePair(pairs[i], pairs[i+1], 
FORMDATA, partSerializer, null, null));
                return this;
        }
 
@@ -2333,9 +1675,22 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Creates form data "foo=bar&baz=qux".</jc>
         *      client
         *              .formPost(<jsf>URL</jsf>)
-        *              .customFormData(<js>"key1=val1&key2=val2"</js>)
+        *              .formDataCustom(<js>"foo=bar&baz=qux"</js>)
+        *              .run();
+        *
+        *      <jc>// Creates form data "foo=bar&baz=qux" using 
StringEntity.</jc>
+        *      client
+        *              .formPost(<jsf>URL</jsf>)
+        *              .formDataCustom(<js>new</js> 
StringEntity(<js>"foo=bar&baz=qux"</js>,<js>"application/x-www-form-urlencoded"</js>))
+        *              .run();
+        *
+        *      <jc>// Creates form data "foo=bar&baz=qux" using StringEntity 
and body().</jc>
+        *      client
+        *              .formPost(<jsf>URL</jsf>)
+        *              .body(<js>new</js> 
StringEntity(<js>"foo=bar&baz=qux"</js>,<js>"application/x-www-form-urlencoded"</js>))
         *              .run();
         * </p>
         *
@@ -2369,29 +1724,31 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return this;
        }
 
-       @SuppressWarnings("unchecked")
-       RestRequest formData(EnumSet<AddFlag> flags, String name, Object value, 
HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
+       RestRequest formDataArg(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
                serializer = (serializer == null ? partSerializer : serializer);
                flags = AddFlag.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof NameValuePairs;
-               if (! isMulti) {
-                       innerFormData(flags, toQuery(flags, name, value, 
serializer, schema));
-               } else if (value instanceof NameValuePairs) {
-                       innerFormData(flags, AList.of((NameValuePairs)value));
+
+               if (! isMulti)
+                       return innerFormData(flags, 
AList.of(serializedNameValuePair(name, value, FORMDATA, serializer, schema, 
flags)));
+
+               List<NameValuePair> l = AList.of();
+
+               if (value instanceof NameValuePairs) {
+                       l.addAll((NameValuePairs)value);
                } else if (value instanceof Map) {
-                       innerFormData(flags, toQuery(flags, 
(Map<String,Object>)value, serializer, schema));
+                       for (Map.Entry<Object,Object> e : 
toMap(value).entrySet())
+                               l.add(serializedNameValuePair(e.getKey(), 
e.getValue(), FORMDATA, serializer, schema, flags));
                } else if (isBean(value)) {
-                       formData(flags, name, toBeanMap(value), schema, 
serializer);
-               } else if (value instanceof Reader || value instanceof 
InputStream || value instanceof CharSequence || value instanceof HttpEntity) {
-                       formDataCustom(value);
+                       for (Map.Entry<String,Object> e : 
toBeanMap(value).entrySet())
+                               l.add(serializedNameValuePair(e.getKey(), 
e.getValue(), FORMDATA, serializer, schema, flags));
+               } else if (value instanceof Reader || value instanceof 
InputStream || value instanceof CharSequence) {
+                       return formDataCustom(value);
                } else {
                        throw new RestCallException("Invalid name ''{0}'' 
passed to formData() for data type ''{1}''", name, className(value));
                }
-               return this;
-       }
 
-       private RestRequest innerFormData(EnumSet<AddFlag> flags, NameValuePair 
param) {
-               return innerFormData(flags, AList.of(param));
+               return innerFormData(flags, l);
        }
 
        private RestRequest innerFormData(EnumSet<AddFlag> flags, 
List<NameValuePair> params) {
@@ -2533,7 +1890,20 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        
//-----------------------------------------------------------------------------------------------------------------
 
        /**
-        * Sets a header on the request.
+        * Adds a header on the request.
+        *
+        * <h5 class='section'>Example:</h5>
+        * <p class='bcode w800'>
+        *      <jc>// Adds header "Foo: bar|baz".</jc>
+        *      client
+        *              .get(<jsf>URL</jsf>)
+        *              .header(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"Foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>)),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
+        *              .run();
+        * </p>
         *
         * @param flags Instructions on how to add this parameter.
         *      <ul>
@@ -2543,32 +1913,12 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
         * @param value The header value.
         *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
-        * @param schema The schema object that defines the format of the 
output.
+        * @param schema The schema object that defines the format of the 
output.
         *      <ul>
         *              <li>If <jk>null</jk>, defaults to {@link 
HttpPartSchema#DEFAULT}.
         *              <li>Only used if serializer is schema-aware (e.g. 
{@link OpenApiSerializer}).
@@ -2577,55 +1927,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSchema schema) throws RestCallException {
-               return header(flags, name, value, schema, partSerializer);
-       }
-
-       /**
-        * Sets a header on the request.
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
-        * @param value The header value supplier.
-        *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The schema object that defines the format of the 
output.
-        *      <ul>
-        *              <li>If <jk>null</jk>, defaults to {@link 
HttpPartSchema#DEFAULT}.
-        *              <li>Only used if serializer is schema-aware (e.g. 
{@link OpenApiSerializer}).
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest header(EnumSet<AddFlag> flags, String name, 
Supplier<?> value, HttpPartSchema schema) throws RestCallException {
-               return header(flags, name, value, schema, partSerializer);
+               return headers(flags, serializedHeader(name, value, 
partSerializer, schema, flags));
        }
 
        /**
@@ -2633,6 +1935,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds header "Foo: bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
         *              .header(<js>"Foo"</js>, <js>"bar"</js>)
@@ -2640,80 +1943,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * </p>
         *
         * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
         * @param value The header value.
         *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(String name, Object value) throws 
RestCallException {
-               return header(DEFAULT_FLAGS, name, value, null, partSerializer);
-       }
-
-       /**
-        * Appends a header on the request.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .header(<js>"Foo"</js>, ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
-        * @param value The header value.
-        *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest header(String name, Supplier<?> value) throws 
RestCallException {
-               return header(DEFAULT_FLAGS, name, value, null, partSerializer);
+               return headers(serializedHeader(name, value, partSerializer, 
null, null));
        }
 
        /**
@@ -2724,104 +1963,42 @@ public class RestRequest extends BeanSession 
implements HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
-        *      <jc>// Creates header "Foo=bar|baz"</jc>
+        *      <jc>// Adds header "Foo: bar|baz".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .header(<js>"Foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
+        *              .header(
+        *                      <js>"Foo"</js>, 
AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>),
+        *                      HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>
+        *              )
         *              .run();
         * </p>
         *
         * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
         * @param value The header value.
         *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @param schema The HTTP part schema.  Can be <jk>null</jk>.
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(String name, Object value, HttpPartSchema 
schema) throws RestCallException {
-               return header(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
-       }
-
-       /**
-        * Appends a header on the request.
-        *
-        * <p>
-        * The optional schema allows for specifying how part should be 
serialized (as a pipe-delimited list for example).
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      <jc>// Creates header "Foo=bar|baz"</jc>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              .header(<js>"Foo"</js>, 
()-&gt;AList.<jsm>of</jsm>(<js>"bar"</js>,<js>"baz"</js>), 
HttpPartSchema.<jsf>T_ARRAY_PIPES</jsf>)
-        *              .run();
-        * </p>
-        *
-        * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
-        * @param value The header value.
-        *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @param schema The HTTP part schema.  Can be <jk>null</jk>.
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest header(String name, Supplier<?> value, 
HttpPartSchema schema) throws RestCallException {
-               return header(DEFAULT_FLAGS, name, value, schema, 
partSerializer);
+               return headers(serializedHeader(name, value, partSerializer, 
schema, null));
        }
 
        /**
-        * Sets a header on the request.
+        * Adds a header to the request.
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds header "Foo: bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.header(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),<js>"Foo"</js>,
 <js>"bar"</js>)
+        *              .header(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      <js>"Foo"</js>, <js>"bar"</js>
+        *              )
         *              .run();
         * </p>
         *
@@ -2833,87 +2010,16 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
         * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
         * @param value The header value.
         *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
+        *              <li>Value can be any POJO.
+        *              <li>Value converted to a string using the configured 
part serializer.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(EnumSet<AddFlag> flags, String name, Object 
value) throws RestCallException {
-               return header(flags, name, value, null, partSerializer);
-       }
-
-       /**
-        * Sets a header on the request.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              
.header(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),<js>"Foo"</js>,
 ()-&gt;<js>"bar"</js>)
-        *              .run();
-        * </p>
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param name The header name.
-        *      <ul>
-        *              <li>If the name is <js>"*"</js>, the value is assumed 
to be a collection of headers.
-        *      </ul>
-        * @param value The header value supplier.
-        *      <ul>
-        *              <li>For single value headers:
-        *              <ul>
-        *                      <li>Can be any POJO.
-        *                      <li>Converted to a string using the specified 
part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>For multi-value headers:
-        *              <ul>
-        *                      <li>{@link Map} / {@link OMap} / bean
-        *                      <ul>
-        *                              <li>Values can be any POJO.
-        *                              <li>Values converted to a string using 
the configured part serializer.
-        *                              <li>Values are converted to strings at 
runtime to allow them to be modified externally.
-        *                      </ul>
-        *                      <li>{@link NameValuePairs}
-        *                      <ul>
-        *                              <li>Values converted directly to 
strings.
-        *                      </ul>
-        *              </ul>
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest header(EnumSet<AddFlag> flags, String name, 
Supplier<?> value) throws RestCallException {
-               return header(flags, name, value, null, partSerializer);
+               return headers(flags, serializedHeader(name, value, 
partSerializer, null, flags));
        }
 
        /**
@@ -2921,6 +2027,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds header "Foo: bar".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
         *              .header(BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>, 
<js>"bar"</js>))
@@ -2932,17 +2039,18 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(Header header) throws RestCallException {
-               return header(DEFAULT_FLAGS, header);
+               return headers(header);
        }
 
        /**
         * Appends a header on the request.
         *
         * <h5 class='section'>Example:</h5>
+        *      <jc>// Adds header "Foo: bar".</jc>
         * <p class='bcode w800'>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.header(BasicNameValuePair.<jsm>of</jsm>(BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>,
 <js>"bar"</js>)))
+        *              
.header(BasicNameValuePair.<jsm>of</jsm>(<js>"Foo"</js>, <js>"bar"</js>))
         *              .run();
         * </p>
         *
@@ -2951,44 +2059,7 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         * @throws RestCallException Invalid input.
         */
        public RestRequest header(NameValuePair header) throws 
RestCallException {
-               return header(DEFAULT_FLAGS, header);
-       }
-
-       /**
-        * Sets a header on the request.
-        *
-        * <h5 class='section'>Example:</h5>
-        * <p class='bcode w800'>
-        *      client
-        *              .get(<jsf>URL</jsf>)
-        *              
.header(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>,
 <js>"bar"</js>))
-        *              .run();
-        * </p>
-        *
-        * @param flags Instructions on how to add this parameter.
-        *      <ul>
-        *              <li>{@link AddFlag#APPEND APPEND} (default) - Append to 
end.
-        *              <li>{@link AddFlag#PREPEND PREPEND} - Prepend to 
beginning.
-        *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
-        *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
-        *      </ul>
-        * @param header The header to set.
-        *      <br>Can be any of the following types:
-        *      <ul>
-        *              <li>{@link Header} (including any subclasses such as 
{@link Accept})
-        *              <li>{@link NameValuePair}
-        *              <li><jk>null</jk> - Will be a no-op.
-        *      </ul>
-        * @return This object (for method chaining).
-        * @throws RestCallException Invalid input.
-        */
-       public RestRequest header(EnumSet<AddFlag> flags, Object header) throws 
RestCallException {
-               if (header == null)
-                       return this;
-               Header h = toHeader(header);
-               if (h == null)
-                       throw new RestCallException("Invalid type passed to 
header(): " + header.getClass().getName());
-               return innerHeader(flags, h);
+               return headers(header);
        }
 
        /**
@@ -2996,28 +2067,21 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds headers "Foo: bar" and "Baz: qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              .headers(BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>, 
<js>"bar"</js>))
+        *              .headers(
+        *                      BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>, 
<js>"bar"</js>),
+        *                      AMap.<jsm>of</jsm>(<js>"Baz"</js>, 
<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
-        * @param headers The header to set.
+        * @param headers The headers to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link Header} (including any subclasses such as 
{@link Accept})
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link Header} / {@link NameValuePair} / {@link 
NameValuePairs} - Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
@@ -3031,9 +2095,14 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds headers "Foo: bar" and "Baz: qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.headers(EnumSet.<jsm>of</jsm>(<jsf>REPLACE</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>,
 <js>"bar"</js>))
+        *              .headers(
+        *                      
EnumSet.<jsm>of</jsm>(<jsf>APPEND</jsf>,<jsf>SKIP_IF_EMPTY</jsf>),
+        *                      BasicHeader.<jsm>of</jsm>(<js>"Foo"</js>, 
<js>"bar"</js>),
+        *                      AMap.<jsm>of</jsm>(<js>"Baz"</js>, 
<js>"qux"</js>)
+        *              )
         *              .run();
         * </p>
         *
@@ -3044,27 +2113,15 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *              <li>{@link AddFlag#REPLACE REPLACE} - Delete any 
existing with same name and append to end.
         *              <li>{@link AddFlag#SKIP_IF_EMPTY} - Don't add if value 
is an empty string.
         *      </ul>
-        * @param headers The header to set.
+        * @param headers The headers to set.
         *      <br>Can be any of the following types:
         *      <ul>
-        *              <li>{@link Header} (including any subclasses such as 
{@link Accept})
-        *              <li>{@link NameValuePair}
-        *              <li>{@link Map} / {@link OMap} / bean
-        *              <ul>
-        *                      <li>Values can be any POJO.
-        *                      <li>Values converted to a string using the 
configured part serializer.
-        *                      <li>Values are converted to strings at runtime 
to allow them to be modified externally.
-        *              </ul>
-        *              <li>{@link NameValuePairs}
-        *              <ul>
-        *                      <li>Values converted directly to strings.
-        *              </ul>
-        *              <li><jk>null</jk> - Will be a no-op.
+        *              <li>{@link Map} / {@link OMap} / bean - Converted to 
key/value pairs using part serializer.
+        *              <li>{@link Header} / {@link NameValuePair} / {@link 
NameValuePairs} - Converted to key/value pairs directly.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
         */
-       @SuppressWarnings("rawtypes")
        public RestRequest headers(EnumSet<AddFlag> flags, Object...headers) 
throws RestCallException {
                List<Header> l = new ArrayList<>();
                for (Object o : headers) {
@@ -3074,14 +2131,13 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                                for (NameValuePair p : (NameValuePairs)o)
                                        l.add(toHeader(p));
                        } else if (o instanceof Map) {
-                               Map m = (Map)o;
-                               for (Map.Entry e : (Set<Map.Entry>)m.entrySet())
-                                       l.add(new 
SerializedHeader(stringify(e.getKey()), e.getValue(), partSerializer, null, 
flags.contains(SKIP_IF_EMPTY)));
+                               for (Map.Entry<Object,Object> e : 
toMap(o).entrySet())
+                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer, null, flags));
                        } else if (isBean(o)) {
                                for (Map.Entry<String,Object> e : 
toBeanMap(o).entrySet())
-                                       l.add(new 
SerializedHeader(stringify(e.getKey()), e.getValue(), partSerializer, null, 
flags.contains(SKIP_IF_EMPTY)));
+                                       l.add(serializedHeader(e.getKey(), 
e.getValue(), partSerializer, null, flags));
                        } else {
-                               throw new RestCallException("Invalid type 
passed to header(): " + headers.getClass().getName());
+                               throw new RestCallException("Invalid type 
passed to headers(): " + className(o));
                        }
                }
                return innerHeaders(flags, l);
@@ -3092,17 +2148,17 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
         *
         * <h5 class='section'>Example:</h5>
         * <p class='bcode w800'>
+        *      <jc>// Adds headers "Foo: bar" and "Baz: qux".</jc>
         *      client
         *              .get(<jsf>URL</jsf>)
-        *              
.headers(<js>"Header1"</js>,<js>"val1"</js>,<js>"Header2"</js>,<js>"val2"</js>)
+        *              
.headers(<js>"Foo"</js>,<js>"bar"</js>,<js>"Baz"</js>,<js>"qux"</js>)
         *              .run();
         * </p>
         *
-        * @param pairs The header key/value pairs.
+        * @param pairs The form-data key/value pairs.
         *      <ul>
         *              <li>Values can be any POJO.
         *              <li>Values converted to a string using the configured 
part serializer.
-        *              <li>Values are converted to strings at runtime to allow 
them to be modified externally.
         *      </ul>
         * @return This object (for method chaining).
         * @throws RestCallException Invalid input.
@@ -3110,33 +2166,39 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
        public RestRequest headerPairs(Object...pairs) throws RestCallException 
{
                List<Header> l = new ArrayList<>();
                if (pairs.length % 2 != 0)
-                       throw new RestCallException("Odd number of parameters 
passed into headerPairs(Object...)");
+                       throw new RestCallException("Odd number of parameters 
passed into headerPairs()");
                for (int i = 0; i < pairs.length; i+=2)
-                       l.add(new SerializedHeader(stringify(pairs[i]), 
pairs[i+1], partSerializer, null, false));
+                       l.add(serializedHeader(pairs[i], pairs[i+1], 
partSerializer, null, null));
                return innerHeaders(DEFAULT_FLAGS, l);
        }
 
-       @SuppressWarnings("unchecked")
-       RestRequest header(EnumSet<AddFlag> flags, String name, Object value, 
HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
+       RestRequest headerArg(EnumSet<AddFlag> flags, String name, Object 
value, HttpPartSchema schema, HttpPartSerializerSession serializer) throws 
RestCallException {
                serializer = (serializer == null ? partSerializer : serializer);
                flags = AddFlag.orDefault(flags);
                boolean isMulti = isEmpty(name) || "*".equals(name) || value 
instanceof NameValuePairs;
-               if (! isMulti) {
-                       innerHeader(flags, toHeader(flags, name, value, 
serializer, schema));
+
+
+               if (! isMulti)
+                       return innerHeaders(flags, 
AList.of(serializedHeader(name, value, serializer, schema, flags)));
+
+               List<Header> l = AList.of();
+
+               if (value instanceof Headerable) {
+                       l.add(((Headerable)value).asHeader());
                } else if (value instanceof NameValuePairs) {
-                       innerHeaders(flags, toHeaders((NameValuePairs)value));
+                       for (NameValuePair p : (NameValuePairs)value)
+                               l.add(toHeader(p));
                } else if (value instanceof Map) {
-                       innerHeaders(flags, toHeaders(flags, 
(Map<String,Object>)value, serializer, schema));
+                       for (Map.Entry<Object,Object> e : 
toMap(value).entrySet())
+                               l.add(serializedHeader(e.getKey(), 
e.getValue(), serializer, schema, flags));
                } else if (isBean(value)) {
-                       return header(flags, name, toBeanMap(value), schema, 
serializer);
+                       for (Map.Entry<String,Object> e : 
toBeanMap(value).entrySet())
+                               l.add(serializedHeader(e.getKey(), 
e.getValue(), serializer, schema, flags));
                } else {
-                       throw new RestCallException("Invalid name ''{0}'' 
passed to header(name,value,skipIfEmpty) for data type ''{1}''", name, 
className(value));
+                       throw new RestCallException("Invalid name ''{0}'' 
passed to header() for data type ''{1}''", name, className(value));
                }
-               return this;
-       }
 
-       private RestRequest innerHeader(EnumSet<AddFlag> flags, Header header) {
-               return innerHeaders(flags, AList.of(header));
+               return innerHeaders(flags, l);
        }
 
        private RestRequest innerHeaders(EnumSet<AddFlag> flags, 
Collection<Header> headers) {
@@ -4248,8 +3310,31 @@ public class RestRequest extends BeanSession implements 
HttpUriRequest, Configur
                return super.getProperties();
        }
 
-       private static String className(Object o) {
-               return ClassInfo.of(o).getFullName();
+       @SuppressWarnings("unchecked")
+       private static Map<Object,Object> toMap(Object o) {
+               return (Map<Object,Object>)o;
+       }
+
+       private static SerializedNameValuePair serializedNameValuePair(Object 
key, Object value, HttpPartType type, HttpPartSerializerSession serializer, 
HttpPartSchema schema, EnumSet<AddFlag> flags) {
+               return new SerializedNameValuePair(stringify(key), value, type, 
serializer, schema, flags == null ? false : flags.contains(SKIP_IF_EMPTY));
+       }
+
+       private static SerializedHeader serializedHeader(Object key, Object 
value, HttpPartSerializerSession serializer, HttpPartSchema schema, 
EnumSet<AddFlag> flags) {
+               return new SerializedHeader(stringify(key), value, serializer, 
schema, flags == null ? false : flags.contains(SKIP_IF_EMPTY));
+       }
+
+       private static Header toHeader(Object o) {
+               if (o instanceof Header)
+                       return (Header)o;
+               if (o instanceof Headerable)
+                       return ((Headerable)o).asHeader();
+               if (o instanceof NameValuePair)
+                       return BasicHeader.of((NameValuePair)o);
+               throw new BasicRuntimeException("Object cannot be converted to 
a header: {0}", o == null ? null : o.getClass().getName());
+       }
+
+       private static String className(Object value) {
+               return value == null ? null : value.getClass().getName();
        }
 
        
//-----------------------------------------------------------------------------------------------------------------

Reply via email to