Rework UriBuilder for single mode that always encodes. Annotation values now automatically encoded preserving any pct-encoded values within them.

svn path=/trunk/; revision=425
diff --git a/spec/chapters/resources.tex b/spec/chapters/resources.tex
index 5cdaae2..eeb334f 100644
--- a/spec/chapters/resources.tex
+++ b/spec/chapters/resources.tex
@@ -180,15 +180,13 @@
 
 \begin{nnnote}Because \lq\{\rq and \lq\}\rq\ are not part of either the reserved or unreserved productions of URI\cite{uri} they will not appear in a valid URI.\end{nnnote}
 
-The \code{encode} property of \Path\ controls whether the value of the annotation is automatically encoded (the default) or not. E.g. the following two lines are equivalent:
+The value of the annotation is automatically encoded, e.g. the following two lines are equivalent:
 
 \begin{listing}{1}
 @Path("widget list/{id}")
-@Path(value="widget%20list/{id}", encode=false)
+@Path("widget%20list/{id}")
 \end{listing}
 
-When automatic encoding is disabled, care must be taken to ensure that the value of the URI template is valid.
-
 Template parameters can optionally specify the regular expression used to match their values. The default value matches any text and terminates at the end of a path segment but other values can be used to alter this behavior, e.g.:
 
 \begin{listing}{1}
@@ -409,7 +407,7 @@
 
 The function $R(A)$ converts a URI path template annotation $A$ into a regular expression as follows:
 \begin{enumerate}
-\item If $A.\mbox{encode}=\mbox{true}$, URI encode the template, ignoring URI template variable specifications.
+\item URI encode the template, ignoring URI template variable specifications.
 \item Escape any regular expression characters in the URI template, again ignoring URI template variable specifications.
 \item Replace each URI template variable with a capturing group containing the specified regular expression or \lq([\^{ }/]+?)\rq\ if no regular expression is specified.
 \item If the resulting string ends with \lq/\rq\ then remove the final character.
diff --git a/src/jsr311-api/src/javax/ws/rs/FormParam.java b/src/jsr311-api/src/javax/ws/rs/FormParam.java
index 305191b..2e0c445 100644
--- a/src/jsr311-api/src/javax/ws/rs/FormParam.java
+++ b/src/jsr311-api/src/javax/ws/rs/FormParam.java
@@ -63,6 +63,10 @@
      * Defines the name of the form parameter whose value will be used
      * to initialize the value of the annotated method argument, class field or
      * bean property.
+     * 
+     * <p>The supplied value is automatically percent encoded. Note that percent
+     * encoded values are allowed in the value, an implementation will recognize
+     * such values and will not double encode the '%' character.</p>
      */
     String value();
 }
diff --git a/src/jsr311-api/src/javax/ws/rs/MatrixParam.java b/src/jsr311-api/src/javax/ws/rs/MatrixParam.java
index aad20de..fdf89c2 100644
--- a/src/jsr311-api/src/javax/ws/rs/MatrixParam.java
+++ b/src/jsr311-api/src/javax/ws/rs/MatrixParam.java
@@ -63,14 +63,10 @@
      * Defines the name of the URI matrix parameter whose value will be used
      * to initialize the value of the annotated method argument, class field or
      * bean property.
+     * 
+     * <p>The supplied value is automatically percent encoded. Note that percent
+     * encoded values are allowed in the value, an implementation will recognize
+     * such values and will not double encode the '%' character.</p>
      */
     String value();
-    
-    /**
-     * Controls whether the the supplied matrix parameter name is URL encoded. 
-     * If true, any characters in the matrix parameter name that are not valid
-     * URI characters will be automatically encoded. If false then all 
-     * characters in the supplied name must be valid URI characters.
-     */
-    boolean encode() default true;    
 }
diff --git a/src/jsr311-api/src/javax/ws/rs/Path.java b/src/jsr311-api/src/javax/ws/rs/Path.java
index 034f4b6..2e57f7b 100644
--- a/src/jsr311-api/src/javax/ws/rs/Path.java
+++ b/src/jsr311-api/src/javax/ws/rs/Path.java
@@ -26,26 +26,7 @@
 
 /**
  * Identifies the URI path that a resource class or class method will serve 
- * requests for. Embedded template variables are allowed and are of the 
- * form:
- * 
- * <pre> param = "{" *WSP name *WSP [ ":" *WSP regex *WSP ] "}"
- * name = (ALPHA / DIGIT / "_")*(ALPHA / DIGIT / "." / "_" / "-" ) ; \w[\w\.-]*</pre>
- * 
- * <p>See {@link <a href="http://tools.ietf.org/html/rfc2234">RFC 2234</a>} for 
- * a description of the syntax used above and the expansions of {@code WSP}, 
- * {@code ALPHA} and {@code DIGIT}. In the above {@code name} is the template 
- * variable name and the optional {@code regex} specifies the contents of the 
- * capturing group for the parameter. If {@code regex} is not supplied then a 
- * default value of {@code [^/]+} which terminates at a path segment boundary is
- * used. Matching is performed against encoded path values, any literals in 
- * {@code regex} should be escaped according to the rules of
- * {@link <a href="http://tools.ietf.org/html/rfc3986#section-3.3">RFC 3986 section 3.3</a>}.
- * Caution is recommended in the use of {@code regex}, incorrect use can lead
- * to a template parameter matching unexpected URI paths. See 
- * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html">Pattern</a>}
- * for further information on the syntax of regular expressions.
- * Values of template variables may be extracted using {@link PathParam}.
+ * requests for.
  *
  * <p>Paths are relative. For an annotated class the base URI is the 
  * application context. For an annotated method the base URI is the
@@ -84,16 +65,35 @@
     /**
      * Defines a URI template for the resource class or method, must not 
      * include matrix parameters.
+     * 
+     * <p>Embedded template parameters are allowed and are of the form:</p>
+     * 
+     * <pre> param = "{" *WSP name *WSP [ ":" *WSP regex *WSP ] "}"
+     * name = (ALPHA / DIGIT / "_")*(ALPHA / DIGIT / "." / "_" / "-" ) ; \w[\w\.-]*</pre>
+     * 
+     * <p>See {@link <a href="http://tools.ietf.org/html/rfc2234">RFC 2234</a>} for 
+     * a description of the syntax used above and the expansions of {@code WSP}, 
+     * {@code ALPHA} and {@code DIGIT}. In the above {@code name} is the template 
+     * parameter name and the optional {@code regex} specifies the contents of the 
+     * capturing group for the parameter. If {@code regex} is not supplied then a 
+     * default value of {@code [^/]+} which terminates at a path segment boundary is
+     * used. Matching is performed against encoded path values, any literals in 
+     * {@code regex} should be escaped according to the rules of
+     * {@link <a href="http://tools.ietf.org/html/rfc3986#section-3.3">RFC 3986 section 3.3</a>}.
+     * Caution is recommended in the use of {@code regex}, incorrect use can lead
+     * to a template parameter matching unexpected URI paths. See 
+     * {@link <a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html">Pattern</a>}
+     * for further information on the syntax of regular expressions.
+     * Values of template parameters may be extracted using {@link PathParam}.
+     *
+     * <p>The literal part of the supplied value (those characters
+     * that are not part of a template parameter) is automatically percent 
+     * encoded to conform to the {@code path} production of 
+     * {@link <a href="http://tools.ietf.org/html/rfc3986#section-3.3">RFC 3986 section 3.3</a>}.
+     * Note that percent encoded values are allowed in the literal part of the
+     * value, an implementation will recognize such values and will not double
+     * encode the '%' character.</p>
      */
     String value();
     
-    /**
-     * Controls whether the literal part of the supplied value (those characters
-     * that are not part of a template variable) are URL encoded. If true, any 
-     * percent characters or characters that are not valid in a URI path will be
-     * automatically encoded. If false then all characters must be valid URI
-     * path characters.
-     */
-    boolean encode() default true;
-    
 }
diff --git a/src/jsr311-api/src/javax/ws/rs/QueryParam.java b/src/jsr311-api/src/javax/ws/rs/QueryParam.java
index d89bb4c..fc86a22 100644
--- a/src/jsr311-api/src/javax/ws/rs/QueryParam.java
+++ b/src/jsr311-api/src/javax/ws/rs/QueryParam.java
@@ -63,14 +63,10 @@
      * Defines the name of the HTTP query parameter whose value will be used
      * to initialize the value of the annotated method argument, class field or
      * bean property.
+     * 
+     * <p>The supplied value is automatically percent encoded. Note that percent
+     * encoded values are allowed in the value, an implementation will recognize
+     * such values and will not double encode the '%' character.</p>
      */
     String value();
-    
-    /**
-     * Controls whether the the supplied query parameter name is URL encoded. 
-     * If true, any characters in the query parameter name that are not valid
-     * URI characters will be automatically encoded. If false then all 
-     * characters in the supplied name must be valid URI characters.
-     */
-    boolean encode() default true;    
 }
diff --git a/src/jsr311-api/src/javax/ws/rs/core/UriBuilder.java b/src/jsr311-api/src/javax/ws/rs/core/UriBuilder.java
index 03bd25c..01031cc 100644
--- a/src/jsr311-api/src/javax/ws/rs/core/UriBuilder.java
+++ b/src/jsr311-api/src/javax/ws/rs/core/UriBuilder.java
@@ -28,16 +28,16 @@
  * URI template aware utility class for building URIs from their components. See
  * {@link javax.ws.rs.Path#value} for an explanation of URI templates.
  * 
- * <p>Many methods support automatic encoding of illegal characters, see the
- * {@link #encode} method. Encoding and validation of URI
- * components follow the rules of the 
+ * <p>Builder methods perform contextual encoding of characters not permitted in
+ * the corresponding URI component following the rules of the 
  * <a href="http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1">application/x-www-form-urlencoded</a>
  * media type for query parameters and
  * <a href="http://ietf.org/rfc/rfc3986.txt">RFC 3986</a> for all other
- * components. Note that only illegal characters are subject to encoding so, e.g.,
- * a path segment supplied to one of the <code>path</code> methods may
- * contain matrix parameters or multiple path segments since the separators are
- * legal characters and will not be encoded.</p>
+ * components. Note that only characters not permitted in a particular component
+ * are subject to encoding so, e.g., a path supplied to one of the {@code path}
+ * methods may contain matrix parameters or multiple path segments since the
+ * separators are legal characters and will not be encoded. Percent encoded 
+ * values are also recognized where allowed and will not be double encoded.</p>
  * 
  * <p>URI templates are allowed in most components of a URI but their value is
  * restricted to a particular component. E.g. 
@@ -46,7 +46,7 @@
  * "foo%23bar". To create a URI "foo#bar" use
  * <blockquote><code>UriBuilder.fromPath("{arg1}").fragment("{arg2}").build("foo", "bar")</code></blockquote>
  * instead. URI template names and delimiters are never encoded but their 
- * values may be encoded when a URI is built, see the {@link #encode} method.
+ * values are encoded when a URI is built.
  * Template parameter regular expressions are ignored when building a URI, i.e.
  * no validation is performed.
  * 
@@ -62,8 +62,7 @@
     protected UriBuilder() {}
     
     /**
-     * Creates a new instance of UriBuilder with automatic encoding 
-     * (see {@link #encode} method) turned on.
+     * Creates a new instance of UriBuilder.
      * @return a new instance of UriBuilder
      */
     protected static UriBuilder newInstance() {
@@ -72,22 +71,19 @@
     }
     
     /**
-     * Create a new instance initialized from an existing URI with automatic encoding 
-     * (see {@link #encode} method) turned on.
+     * Create a new instance initialized from an existing URI.
      * @param uri a URI that will be used to initialize the UriBuilder.
      * @return a new UriBuilder
      * @throws IllegalArgumentException if uri is null
      */
     public static UriBuilder fromUri(URI uri) throws IllegalArgumentException {
         UriBuilder b = newInstance();
-        b.encode(true);
         b.uri(uri);
         return b;
     }
     
     /**
-     * Create a new instance initialized from an existing URI with automatic encoding 
-     * (see {@link #encode} method) turned on.
+     * Create a new instance initialized from an existing URI.
      * @param uri a URI that will be used to initialize the UriBuilder, may not
      * contain URI parameters.
      * @return a new UriBuilder
@@ -104,51 +100,28 @@
     }
     
     /**
-     * Create a new instance representing a relative URI initialized from an
-     * unencoded URI path, equivalent to <code>fromPath(path, true)</code>.
+     * Create a new instance representing a relative URI initialized from a
+     * URI path.
      * @param path a URI path that will be used to initialize the UriBuilder, 
      * may contain URI template parameters.
      * @return a new UriBuilder
      * @throws IllegalArgumentException if path is null
      */
     public static UriBuilder fromPath(String path) throws IllegalArgumentException {
-        return fromPath(path, true);
-    }
-
-    /**
-     * Create a new instance representing a relative URI initialized from a URI 
-     * path.
-     * @param path a URI path that will be used to initialize the UriBuilder, 
-     * may contain URI template parameters.
-     * @param encode controls whether the supplied value is automatically encoded
-     * (true) or not (false). If false, the value must be valid with all illegal
-     * characters already escaped. The supplied value will remain in force for 
-     * subsequent operations and may be altered by calling the encode method.
-     * @return a new UriBuilder
-     * @throws IllegalArgumentException if path is null, or 
-     * if encode is false and path contains illegal characters
-     */
-    public static UriBuilder fromPath(String path, boolean encode) throws IllegalArgumentException {
         UriBuilder b = newInstance();
-        b.encode(encode);
         b.replacePath(path);
         return b;
     }
 
     /**
      * Create a new instance representing a relative URI initialized from a 
-     * root resource class with automatic encoding (see {@link #encode} method) 
-     * turned on.
+     * root resource class.
      * 
-     * @param resource a root resource whose {@link javax.ws.rs.Path} value will be used 
-     * to initialize the UriBuilder. The value of the encode property of the Path 
-     * annotation will be used when processing the value of the {@link javax.ws.rs.Path} but it
-     * will not be used to modify the state of automaic encoding for the builder.
+     * @param resource a root resource whose {@link javax.ws.rs.Path} value will
+     * be used to initialize the UriBuilder.
      * @return a new UriBuilder
-     * @throws IllegalArgumentException if resource is not annotated with {@link javax.ws.rs.Path} or
-     * if resource.encode is false and resource.value, or
-     * if resource is null
-     * contains illegal characters
+     * @throws IllegalArgumentException if resource is not annotated with 
+     * {@link javax.ws.rs.Path} or resource is null.
      */
     public static UriBuilder fromResource(Class<?> resource) throws IllegalArgumentException {
         UriBuilder b = newInstance();
@@ -166,27 +139,6 @@
     public abstract UriBuilder clone();
     
     /**
-     * Controls whether the UriBuilder will automatically encode URI components
-     * added by subsequent operations or not. Also controls whether template
-     * parameter values are encoded when building a URI using 
-     * {@link #buildFromMap(Map)} or {@link #build(java.lang.Object[])}.
-     * Defaults to true unless overridden during creation or set via this method.
-     * @param enable automatic encoding (true) or disable it (false). 
-     * If false, subsequent components added must be valid with all illegal
-     * characters already escaped.
-     * @return the updated UriBuilder
-     */
-    public abstract UriBuilder encode(boolean enable);
-    
-    /**
-     * Get the current state of automatic encoding. Defaults to true unless
-     * overridden during creation or set via {@link #encode}.
-     * @return true if automatic encoding is enable, false otherwise
-     * @see #encode
-     */
-    public abstract boolean isEncode();
-
-    /**
      * Copies the non-null components of the supplied URI to the UriBuilder replacing
      * any existing values for those components.
      * @param uri the URI to copy components from
@@ -219,10 +171,8 @@
      * @param ui the URI user-info, may contain URI template parameters.
      * A null value will unset userInfo component of the URI.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if automatic encoding is disabled and
-     * ui contains illegal characters.
      */
-    public abstract UriBuilder userInfo(String ui) throws IllegalArgumentException;
+    public abstract UriBuilder userInfo(String ui);
     
     /**
      * Set the URI host.
@@ -243,85 +193,90 @@
     
     /**
      * Set the URI path. This method will overwrite 
-     * any existing path segments and associated matrix parameters. When constructing
-     * the final path, each segment will be separated by '/' if necessary. 
-     * Existing '/' characters are preserved thus a single segment value can 
+     * any existing path and associated matrix parameters. 
+     * Existing '/' characters are preserved thus a single value can 
      * represent multiple URI path segments.
-     * @param segments the path segments, may contain URI template parameters.
+     * @param path the path, may contain URI template parameters.
      * A null value will unset the path component of the URI.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if any element of segments is null, or
-     * if automatic encoding is disabled and
-     * any element of segments contains illegal characters
      */
-    public abstract UriBuilder replacePath(String... segments) throws IllegalArgumentException;
+    public abstract UriBuilder replacePath(String path);
 
     /**
-     * Append path segments to the existing list of segments. When constructing
-     * the final path, each segment will be separated by '/' if necessary. 
-     * Existing '/' characters are preserved thus a single segment value can 
+     * Append path to the existing path. 
+     * When constructing the final path, a '/' separator will be inserted
+     * between the existing path and the supplied path if necessary.
+     * Existing '/' characters are preserved thus a single value can 
      * represent multiple URI path segments.
-     * @param segments the path segments, may contain URI template parameters
+     * @param path the path, may contain URI template parameters
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if any element of segments is null, or
-     * if automatic encoding is disabled and
-     * any element of segments contains illegal characters
+     * @throws IllegalArgumentException if path is null
      */
-    public abstract UriBuilder path(String... segments) throws IllegalArgumentException;
+    public abstract UriBuilder path(String path) throws IllegalArgumentException;
 
     /**
-     * Append path segments from a Path-annotated class to the
-     * existing list of segments. When constructing
-     * the final path, each segment will be separated by '/' if necessary.
-     * The value of the <code>encode</code> property of the {@link javax.ws.rs.Path} 
-     * annotation will be used when processing the value of the {@link javax.ws.rs.Path} but it
-     * will not be used to modify the state of automaic encoding for the builder.
+     * Append the path from a Path-annotated class to the
+     * existing path.
+     * When constructing the final path, a '/' separator will be inserted
+     * between the existing path and the supplied path if necessary.
      * 
      * @param resource a resource whose {@link javax.ws.rs.Path} value will be 
-     * used to obtain the path segment.
+     * used to obtain the path to append.
      * @return the updated UriBuilder
      * @throws IllegalArgumentException if resource is null, or
-     * if resource.encode is false and resource.value contains illegal characters, or
      * if resource is not annotated with {@link javax.ws.rs.Path}
      */
     public abstract UriBuilder path(Class resource) throws IllegalArgumentException;
     
     /**
-     * Append path segments from a Path-annotated method to the
-     * existing list of segments. When constructing
-     * the final path, each segment will be separated by '/' if necessary.
+     * Append the path from a Path-annotated method to the
+     * existing path.
+     * When constructing the final path, a '/' separator will be inserted
+     * between the existing path and the supplied path if necessary.
      * This method is a convenience shortcut to <code>path(Method)</code>, it
      * can only be used in cases where there is a single method with the
      * specified name that is annotated with {@link javax.ws.rs.Path}.
      * 
      * @param resource the resource containing the method
      * @param method the name of the method whose {@link javax.ws.rs.Path} value will be 
-     * used to obtain the path segment
+     * used to obtain the path to append
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if resource or method is null, or
-     * if the specified method does not exist,
+     * @throws IllegalArgumentException if resource or method is null, 
      * or there is more than or less than one variant of the method annotated with 
      * {@link javax.ws.rs.Path}
      */
     public abstract UriBuilder path(Class resource, String method) throws IllegalArgumentException;
     
     /**
-     * Append path segments from a list of Path-annotated methods to the
-     * existing list of segments. When constructing
-     * the final path, each segment will be separated by '/' if necessary.
-     * The value of the encode property of the Path 
-     * annotation will be used when processing the value of the {@link javax.ws.rs.Path} but it
-     * will not be used to modify the state of automatic encoding for the builder.
+     * Append the path from a {@link javax.ws.rs.Path}-annotated method to the
+     * existing path.
+     * When constructing the final path, a '/' separator will be inserted
+     * between the existing path and the supplied path if necessary.
      * 
-     * @param methods a list of methods whose {@link javax.ws.rs.Path} values will be 
-     * used to obtain the path segments
+     * @param method a method whose {@link javax.ws.rs.Path} value will be 
+     * used to obtain the path to append to the existing path
      * @return the updated UriBuilder
      * @throws IllegalArgumentException if any element of methods is null or is
      * not annotated with a {@link javax.ws.rs.Path}
      */
-    public abstract UriBuilder path(Method... methods) throws IllegalArgumentException;
+    public abstract UriBuilder path(Method method) throws IllegalArgumentException;
     
     /**
+     * Append path segments to the existing path.
+     * When constructing the final path, a '/' separator will be inserted
+     * between the existing path and the first path segment if necessary and 
+     * each supplied segment will also be separated by '/'.
+     * Existing '/' characters are encoded thus a single value can 
+     * only represent a single URI path segment.
+     * @param segments the path segment values, each may contain URI template
+     * parameters
+     * @return the updated UriBuilder
+     * @throws IllegalArgumentException if segments or any element of segments
+     * is null
+     */
+    public abstract UriBuilder segment(String... segments) throws IllegalArgumentException;
+
+    /**
      * Set the matrix parameters of the current final segment of the current URI path.
      * This method will overwrite any existing matrix parameters on the current final
      * segment of the current URI path. Note that the matrix parameters
@@ -331,12 +286,10 @@
      * A null value will remove all matrix parameters of the current final segment
      * of the current URI path.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if matrix cannot be parsed, or
-     * if automatic encoding is disabled and
-     * any matrix parameter name or value contains illegal characters
+     * @throws IllegalArgumentException if matrix cannot be parsed
      * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
      */
-    public abstract UriBuilder replaceMatrixParams(String matrix) throws IllegalArgumentException;
+    public abstract UriBuilder replaceMatrix(String matrix) throws IllegalArgumentException;
 
     /**
      * Append a matrix parameter to the existing set of matrix parameters of 
@@ -349,9 +302,7 @@
      * to a {@code String} using its {@code toString()} method. Stringified
      * values may contain URI template parameters.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if name or value is null, or
-     * if automatic encoding is disabled and
-     * the name or any stringified value contains illegal characters
+     * @throws IllegalArgumentException if name or value is null
      * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
      */
     public abstract UriBuilder matrixParam(String name, Object... values) throws IllegalArgumentException;
@@ -368,9 +319,7 @@
      * values may contain URI template parameters. If {@code values} is empty 
      * or null then all current values of the parameter are removed.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if name is null, or
-     * if automatic encoding is disabled and
-     * the name or any stringified value contains illegal characters.
+     * @throws IllegalArgumentException if name is null.
      * @see <a href="http://www.w3.org/DesignIssues/MatrixURIs.html">Matrix URIs</a>
      */
     public abstract UriBuilder replaceMatrixParam(String name, Object... values) throws IllegalArgumentException;
@@ -381,11 +330,9 @@
      * @param query the URI query string, may contain URI template parameters.
      * A null value will remove all query parameters.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if query cannot be parsed, or
-     * if automatic encoding is disabled and
-     * any query parameter name or value contains illegal characters
+     * @throws IllegalArgumentException if query cannot be parsed
      */
-    public abstract UriBuilder replaceQueryParams(String query) throws IllegalArgumentException;
+    public abstract UriBuilder replaceQuery(String query) throws IllegalArgumentException;
 
     /**
      * Append a query parameter to the existing set of query parameters. If
@@ -395,9 +342,7 @@
      * to a {@code String} using its {@code toString()} method. Stringified
      * values may contain URI template parameters.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if name or value is null, or
-     * if automatic encoding is disabled and
-     * name or value contains illegal characters
+     * @throws IllegalArgumentException if name or value is null
      */
     public abstract UriBuilder queryParam(String name, Object... values) throws IllegalArgumentException;
     
@@ -410,65 +355,62 @@
      * values may contain URI template parameters. If {@code values} is empty
      * or null then all current values of the parameter are removed.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if name is null, or
-     * if automatic encoding is disabled and name or value contains illegal 
-     * characters.
+     * @throws IllegalArgumentException if name is null
      */
     public abstract UriBuilder replaceQueryParam(String name, Object... values) throws IllegalArgumentException;
     
     /**
-     * Set the URI fragment using an unencoded value.
+     * Set the URI fragment.
      * @param fragment the URI fragment, may contain URI template parameters.
      * A null value will remove any existing fragment.
      * @return the updated UriBuilder
-     * @throws IllegalArgumentException if fragment is null, or
-     * if automatic encoding is disabled and
-     * fragment contains illegal characters
      */
-    public abstract UriBuilder fragment(String fragment) throws IllegalArgumentException;
+    public abstract UriBuilder fragment(String fragment);
     
     /**
      * Build a URI, any URI template parameters will be replaced by the value in
      * the supplied map. Values are converted to <code>String</code> using
-     * their <code>toString</code> method and are then encoded if 
-     * {@link #isEncode} is <code>true</code>. The <code>build</code> method does
-     * not change the state of the
-     * <code>UriBuilder</code> and it may be called multiple times on the same
-     * builder instance.
+     * their <code>toString</code> method and are then encoded to match the
+     * rules of the URI component to which they pertain. The state of the
+     * builder is unaffected; this method may be called multiple times on the 
+     * same builder instance.
+     * @param isEncoded specifies if the supplied values contain percent
+     * encoded characters. If false then all '%' characters will be encoded, if
+     * true then only % characters that are not followed by two hexadecimal
+     * numbers will be encoded.
      * @param values a map of URI template parameter names and values
      * @return the URI built from the UriBuilder
-     * @throws IllegalArgumentException if automatic encoding is disabled and
-     * a supplied value contains illegal characters, or
-     * if there are any URI template parameters without
-     * a supplied value, or if a template parameter value is null.
+     * @throws IllegalArgumentException if there are any URI template parameters
+     * without a supplied value, or if a template parameter value is null.
      * @throws UriBuilderException if a URI cannot be constructed based on the
      * current state of the builder.
      */
-    public abstract URI buildFromMap(Map<String, ? extends Object> values) 
+    public abstract URI buildFromMap(boolean isEncoded, Map<String, ? extends Object> values) 
             throws IllegalArgumentException, UriBuilderException;
     
     /**
      * Build a URI, using the supplied values in order to replace any URI
      * template parameters. Values are converted to <code>String</code> using
-     * their <code>toString</code> method and are then encoded if 
-     * {@link #isEncode} is <code>true</code>. The <code>build</code> method does 
-     * not change the state of the
-     * <code>UriBuilder</code> and it may be called multiple times on the same
-     * builder instance.
+     * their <code>toString</code> method and are then encoded to match the
+     * rules of the URI component to which they pertain. The state of the
+     * builder is unaffected; this method may be called multiple times on the 
+     * same builder instance.
      * <p>All instances of the same template parameter
      * will be replaced by the same value that corresponds to the position of the
      * first instance of the template parameter. e.g. the template "{a}/{b}/{a}"
      * with values {"x", "y", "z"} will result in the the URI "x/y/x", <i>not</i>
      * "x/y/z".
+     * @param isEncoded specifies if the supplied values contain percent
+     * encoded characters. If false then all '%' characters will be encoded, if
+     * true then only % characters that are not followed by two hexadecimal
+     * numbers will be encoded.
      * @param values a list of URI template parameter values
      * @return the URI built from the UriBuilder
-     * @throws IllegalArgumentException if automatic encoding is disabled and
-     * a supplied value contains illegal characters, or
-     * if there are any URI template parameters without
-     * a supplied value, or if a value is null.
+     * @throws IllegalArgumentException if there are any URI template parameters
+     * without a supplied value, or if a value is null.
      * @throws UriBuilderException if a URI cannot be constructed based on the
      * current state of the builder.
      */
-    public abstract URI build(Object... values) 
+    public abstract URI build(boolean isEncoded, Object... values) 
             throws IllegalArgumentException, UriBuilderException;
 }