You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@juneau.apache.org by ja...@apache.org on 2021/03/03 16:44:08 UTC

[juneau] branch master updated: REST refactoring.

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 187a24d  REST refactoring.
187a24d is described below

commit 187a24d94bf2964acb98bd2e97a68de59011bcb9
Author: JamesBognar <ja...@salesforce.com>
AuthorDate: Wed Mar 3 11:43:31 2021 -0500

    REST refactoring.
---
 .../main/ConfigurablePropertyCodeGenerator.java    |   2 +-
 .../juneau/BasicRuntimeExceptionBuilder.java       |   5 +-
 .../org/apache/juneau/http/BasicHeaderGroup.java   |  19 +-
 .../org/apache/juneau/http/BasicStatusLine.java    |   6 +
 .../apache/juneau/http/exception/BadRequest.java   |  36 +-
 .../org/apache/juneau/http/exception/Conflict.java |  36 +-
 .../juneau/http/exception/ExpectationFailed.java   |  36 +-
 .../juneau/http/exception/FailedDependency.java    |  36 +-
 .../apache/juneau/http/exception/Forbidden.java    |  36 +-
 .../org/apache/juneau/http/exception/Gone.java     |  36 +-
 .../juneau/http/exception/HttpException.java       | 124 +++++--
 .../http/exception/HttpExceptionBuilder.java       | 172 ++++++----
 .../http/exception/HttpVersionNotSupported.java    |  27 +-
 .../juneau/http/exception/InsufficientStorage.java |  36 +-
 .../juneau/http/exception/InternalServerError.java |  36 +-
 .../juneau/http/exception/LengthRequired.java      |  36 +-
 .../org/apache/juneau/http/exception/Locked.java   |  36 +-
 .../apache/juneau/http/exception/LoopDetected.java |  36 +-
 .../juneau/http/exception/MethodNotAllowed.java    |  36 +-
 .../juneau/http/exception/MisdirectedRequest.java  |  36 +-
 .../exception/NetworkAuthenticationRequired.java   |  36 +-
 .../juneau/http/exception/NotAcceptable.java       |  36 +-
 .../apache/juneau/http/exception/NotExtended.java  |  35 +-
 .../org/apache/juneau/http/exception/NotFound.java |  36 +-
 .../juneau/http/exception/NotImplemented.java      |  36 +-
 .../juneau/http/exception/PayloadTooLarge.java     |  36 +-
 .../juneau/http/exception/PreconditionFailed.java  |  36 +-
 .../http/exception/PreconditionRequired.java       |  36 +-
 .../juneau/http/exception/RangeNotSatisfiable.java |  36 +-
 .../exception/RequestHeaderFieldsTooLarge.java     |  36 +-
 .../juneau/http/exception/ServiceUnavailable.java  |  36 +-
 .../juneau/http/exception/TooManyRequests.java     |  36 +-
 .../apache/juneau/http/exception/Unauthorized.java |  36 +-
 .../http/exception/UnavailableForLegalReasons.java |  36 +-
 .../juneau/http/exception/UnprocessableEntity.java |  36 +-
 .../http/exception/UnsupportedMediaType.java       |  36 +-
 .../juneau/http/exception/UpgradeRequired.java     |  36 +-
 .../apache/juneau/http/exception/UriTooLong.java   |  36 +-
 .../http/exception/VariantAlsoNegotiates.java      |  36 +-
 .../org/apache/juneau/http/response/Accepted.java  |  89 ++---
 .../juneau/http/response/AlreadyReported.java      |  89 ++---
 .../juneau/http/response/BasicHttpResponse.java    | 367 ++++++++++++---------
 .../http/response/BasicLocationHttpResponse.java   | 126 -------
 .../org/apache/juneau/http/response/Continue.java  |  89 ++---
 .../org/apache/juneau/http/response/Created.java   |  89 ++---
 .../apache/juneau/http/response/EarlyHints.java    |  89 ++---
 .../org/apache/juneau/http/response/Found.java     | 105 ++----
 .../HttpResponseBuilder.java}                      | 285 ++++++++++------
 .../org/apache/juneau/http/response/IMUsed.java    |  89 ++---
 .../juneau/http/response/MovedPermanently.java     | 105 ++----
 .../apache/juneau/http/response/MultiStatus.java   |  89 ++---
 .../juneau/http/response/MultipleChoices.java      |  89 ++---
 .../org/apache/juneau/http/response/NoContent.java |  89 ++---
 .../http/response/NonAuthoritiveInformation.java   |  89 ++---
 .../apache/juneau/http/response/NotModified.java   |  89 ++---
 .../java/org/apache/juneau/http/response/Ok.java   |  89 ++---
 .../juneau/http/response/PartialContent.java       |  89 ++---
 .../juneau/http/response/PermanentRedirect.java    | 105 ++----
 .../apache/juneau/http/response/Processing.java    |  89 ++---
 .../apache/juneau/http/response/ResetContent.java  |  89 ++---
 .../org/apache/juneau/http/response/SeeOther.java  | 105 ++----
 .../juneau/http/response/StandardResponses.java    |  44 +--
 .../juneau/http/response/SwitchingProtocols.java   |  89 ++---
 .../juneau/http/response/TemporaryRedirect.java    | 105 ++----
 .../org/apache/juneau/http/response/UseProxy.java  |  82 ++---
 .../apache/juneau/rest/client/ResponseBody.java    |   9 +
 .../org/apache/juneau/rest/client/RestClient.java  |  37 ++-
 .../org/apache/juneau/rest/client/RestRequest.java |  50 ++-
 .../rest/client/remote/RemoteOperationMeta.java    |   2 +-
 .../apache/juneau/rest/helper/SeeOtherRoot.java    |   9 +-
 .../juneau/rest/reshandlers/DefaultHandler.java    |   3 +
 .../apache/juneau/http/response/Accepted_Test.java |   4 +-
 .../juneau/http/response/AlreadyReported_Test.java |   4 +-
 .../apache/juneau/http/response/Continue_Test.java |   4 +-
 .../apache/juneau/http/response/Created_Test.java  |   4 +-
 .../juneau/http/response/EarlyHints_Test.java      |   4 +-
 .../apache/juneau/http/response/Found_Test.java    |   6 +-
 .../apache/juneau/http/response/IMUsed_Test.java   |   4 +-
 .../http/response/MovedPermanently_Test.java       |   6 +-
 .../juneau/http/response/MultiStatus_Test.java     |   4 +-
 .../juneau/http/response/MultipleChoices_Test.java |   4 +-
 .../juneau/http/response/NoContent_Test.java       |   4 +-
 .../response/NonAuthoritativeInformation_Test.java |   4 +-
 .../juneau/http/response/NotModified_Test.java     |   4 +-
 .../org/apache/juneau/http/response/Ok_Test.java   |   4 +-
 .../juneau/http/response/PartialContent_Test.java  |   4 +-
 .../http/response/PermanentRedirect_Test.java      |   6 +-
 .../juneau/http/response/Processing_Test.java      |   4 +-
 .../juneau/http/response/ResetContent_Test.java    |   4 +-
 .../apache/juneau/http/response/SeeOther_Test.java |   6 +-
 .../http/response/SwitchingProtocols_Test.java     |   4 +-
 .../http/response/TemporaryRedirect_Test.java      |   6 +-
 .../apache/juneau/http/response/UseProxy_Test.java |   4 +-
 93 files changed, 2022 insertions(+), 2545 deletions(-)

diff --git a/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java b/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
index 2b9030c..6338ea3 100644
--- a/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
+++ b/juneau-all/src/java/main/ConfigurablePropertyCodeGenerator.java
@@ -63,7 +63,7 @@ public class ConfigurablePropertyCodeGenerator {
 		BasicHeaderGroupBuilder.class,
 		BasicHttpEntity.class,
 		BasicHttpResource.class,
-		BasicLocationHttpResponse.class,
+		HttpResponseBuilder.class,
 		BasicNameValuePair.class,
 		BasicRuntimeExceptionBuilder.class,
 		BasicStatusLineBuilder.class,
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeExceptionBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeExceptionBuilder.java
index cc807de..3d50adc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeExceptionBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/BasicRuntimeExceptionBuilder.java
@@ -68,12 +68,11 @@ public class BasicRuntimeExceptionBuilder {
 	/**
 	 * Specifies whether this exception should be unmodifiable after creation.
 	 *
-	 * @param value The new value for this flag.
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public BasicRuntimeExceptionBuilder unmodifiable(boolean value) {
-		unmodifiable = value;
+	public BasicRuntimeExceptionBuilder unmodifiable() {
+		unmodifiable = true;
 		return this;
 	}
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeaderGroup.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeaderGroup.java
index f87e36b..1f7d815 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeaderGroup.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicHeaderGroup.java
@@ -29,6 +29,9 @@ import org.apache.http.util.*;
  */
 public class BasicHeaderGroup {
 
+	/** Predefined instance. */
+	public static final BasicHeaderGroup INSTANCE = create().build();
+
 	private static final Header[] EMPTY = new Header[] {};
 
 	private final List<Header> headers;
@@ -127,18 +130,18 @@ public class BasicHeaderGroup {
 	 * Header name comparison is case insensitive.
 	 *
 	 * @param name The header name.
-	 * @return The first matching header, never <jk>null</jk>.
+	 * @return The first matching header, or <jk>null</jk> if not found.
 	 */
-	public Optional<Header> getFirstHeader(String name) {
+	public Header getFirstHeader(String name) {
 		// HTTPCORE-361 : we don't use the for-each syntax, i.e.
 		//	 for (Header header : headers)
 		// as that creates an Iterator that needs to be garbage-collected
 		for (int i = 0; i < headers.size(); i++) {
 			Header x = headers.get(i);
 			if (x.getName().equalsIgnoreCase(name))
-				return of(x);
+				return x;
 		}
-		return empty();
+		return null;
 	}
 
 	/**
@@ -148,15 +151,15 @@ public class BasicHeaderGroup {
 	 * Header name comparison is case insensitive.
 	 *
 	 * @param name The header name.
-	 * @return The last matching header, never <jk>null</jk>.
+	 * @return The last matching header, or <jk>null</jk> if not found.
 	 */
-	public Optional<Header> getLastHeader(String name) {
+	public Header getLastHeader(String name) {
 		for (int i = headers.size() - 1; i >= 0; i--) {
 			Header x = headers.get(i);
 			if (x.getName().equalsIgnoreCase(name))
-				return of(x);
+				return x;
 		}
-		return empty();
+		return null;
 	}
 
 	/**
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStatusLine.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStatusLine.java
index 6e7f1cd..c9fda7a 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStatusLine.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/BasicStatusLine.java
@@ -18,6 +18,7 @@ import java.util.*;
 
 import org.apache.http.*;
 import org.apache.http.impl.*;
+import org.apache.http.message.*;
 
 /**
  * A basic implementation of the {@link StatusLine} interface.
@@ -90,4 +91,9 @@ public class BasicStatusLine implements StatusLine {
 	public Locale getLocale() {
 		return locale;
 	}
+
+	@Override /* Object */
+	public String toString() {
+		return BasicLineFormatter.INSTANCE.formatStatusLine(null, this).toString();
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/BadRequest.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/BadRequest.java
index e11b756..e645a55 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/BadRequest.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/BadRequest.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.BadRequest.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class BadRequest extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Bad Request";
 
-	/** Reusable unmodifiable instance. */
-	public static final BadRequest INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final BadRequest INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class BadRequest extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<BadRequest> create() {
-		return new HttpExceptionBuilder<>(BadRequest.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(BadRequest.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class BadRequest extends HttpException {
 	 * Constructor.
 	 */
 	public BadRequest() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public BadRequest(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class BadRequest extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public BadRequest(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Conflict.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Conflict.java
index d280ced..44440c4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Conflict.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Conflict.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.Conflict.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class Conflict extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Conflict";
 
-	/** Reusable unmodifiable instance. */
-	public static final Conflict INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Conflict INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class Conflict extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<Conflict> create() {
-		return new HttpExceptionBuilder<>(Conflict.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(Conflict.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class Conflict extends HttpException {
 	 * Constructor.
 	 */
 	public Conflict() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public Conflict(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class Conflict extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public Conflict(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ExpectationFailed.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ExpectationFailed.java
index 332d492..6b48071 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ExpectationFailed.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ExpectationFailed.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.ExpectationFailed.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class ExpectationFailed extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Expectation Failed";
 
-	/** Reusable unmodifiable instance. */
-	public static final ExpectationFailed INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final ExpectationFailed INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class ExpectationFailed extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<ExpectationFailed> create() {
-		return new HttpExceptionBuilder<>(ExpectationFailed.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(ExpectationFailed.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class ExpectationFailed extends HttpException {
 	 * Constructor.
 	 */
 	public ExpectationFailed() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public ExpectationFailed(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class ExpectationFailed extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public ExpectationFailed(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/FailedDependency.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/FailedDependency.java
index 036c34b..19c02ab 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/FailedDependency.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/FailedDependency.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.FailedDependency.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class FailedDependency extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Failed Dependency";
 
-	/** Reusable unmodifiable instance. */
-	public static final FailedDependency INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final FailedDependency INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class FailedDependency extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<FailedDependency> create() {
-		return new HttpExceptionBuilder<>(FailedDependency.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(FailedDependency.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class FailedDependency extends HttpException {
 	 * Constructor.
 	 */
 	public FailedDependency() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public FailedDependency(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class FailedDependency extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public FailedDependency(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Forbidden.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Forbidden.java
index 70f249e..67a6bc5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Forbidden.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Forbidden.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.Forbidden.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class Forbidden extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Forbidden";
 
-	/** Reusable unmodifiable instance. */
-	public static final Forbidden INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Forbidden INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class Forbidden extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<Forbidden> create() {
-		return new HttpExceptionBuilder<>(Forbidden.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(Forbidden.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class Forbidden extends HttpException {
 	 * Constructor.
 	 */
 	public Forbidden() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public Forbidden(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class Forbidden extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public Forbidden(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Gone.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Gone.java
index eecd2a0..242216b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Gone.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Gone.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.Gone.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -38,8 +40,11 @@ public class Gone extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Gone";
 
-	/** Reusable unmodifiable instance. */
-	public static final Gone INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Gone INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -47,7 +52,7 @@ public class Gone extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<Gone> create() {
-		return new HttpExceptionBuilder<>(Gone.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(Gone.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -74,16 +79,7 @@ public class Gone extends HttpException {
 	 * Constructor.
 	 */
 	public Gone() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public Gone(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -106,6 +102,20 @@ public class Gone extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public Gone(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
index 00c5496..8b03545 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpException.java
@@ -12,6 +12,7 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http.exception;
 
+import static org.apache.juneau.assertions.Assertions.*;
 import static org.apache.juneau.internal.StringUtils.*;
 
 import java.io.*;
@@ -31,11 +32,17 @@ import org.apache.juneau.http.BasicStatusLine;
 import org.apache.juneau.http.annotation.*;
 
 /**
- * Exception thrown to trigger an error HTTP status.
+ * Basic implementation of the {@link HttpResponse} interface for error responses.
  *
  * <p>
- * Note that while the {@link HttpResponse} interface allows you to modify the headers and status line on this
- * bean, it is more efficient to do so in the builder.
+ * Although this class implements the various setters defined on the {@link HttpResponse} interface, it's in general
+ * going to be more efficient to set the status/headers/content of this bean through the builder.
+ *
+ * <p>
+ * If the <c>unmodifiable</c> flag is set on this bean, calls to the setters will throw {@link UnsupportedOperationException} exceptions.
+ *
+ * <p>
+ * Beans are not thread safe unless they're marked as unmodifiable.
  */
 @Response
 @BeanIgnore
@@ -43,8 +50,10 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 
 	private static final long serialVersionUID = 1L;
 
-	BasicHeaderGroup headers;
+	BasicHeaderGroup headerGroup;
 	BasicStatusLine statusLine;
+	BasicHeaderGroupBuilder headerGroupBuilder;
+	BasicStatusLineBuilder statusLineBuilder;
 	HttpEntity body;
 
 	/**
@@ -64,8 +73,8 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 	 */
 	public HttpException(HttpExceptionBuilder<?> builder) {
 		super(builder);
-		headers = builder.headers.build();
-		statusLine = builder.statusLine.build();
+		headerGroup = builder.headerGroup();
+		statusLine = builder.statusLine();
 		body = builder.body;
 	}
 
@@ -112,6 +121,18 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response being parsed.
+	 */
+	public HttpException(HttpResponse response) {
+		this(create(null).copyFrom(response));
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this exception.
 	 *
 	 * @param implClass The subclass that the builder is going to create.
@@ -150,7 +171,20 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 	 */
 	@ResponseStatus
 	public int getStatusCode() {
-		return statusLine.getStatusCode();
+		return statusLine().getStatusCode();
+	}
+
+	/**
+	 * Asserts that the specified HTTP response has the same status code as the one on the status line of this bean.
+	 *
+	 * @param response The HTTP response to check.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If status code is not what was expected.
+	 */
+	protected void assertStatusCode(HttpResponse response) throws AssertionError {
+		assertArgNotNull("response", response);
+		int expected = getStatusLine().getStatusCode();
+		int actual = response.getStatusLine().getStatusCode();
+		assertInteger(actual).msg("Unexpected status code.  Expected:[{0}], Actual:[{1}]", expected, actual).is(expected);
 	}
 
 	/**
@@ -193,7 +227,7 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 		if (m == null && getCause() != null)
 			m = getCause().getMessage();
 		if (m == null)
-			m = statusLine.getReasonPhrase();
+			m = statusLine().getReasonPhrase();
 		return m;
 	}
 
@@ -216,78 +250,78 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 
 	@Override /* HttpMessage */
 	public ProtocolVersion getProtocolVersion() {
-		return statusLine.getProtocolVersion();
+		return statusLine().getProtocolVersion();
 	}
 
 	@Override /* HttpMessage */
 	public boolean containsHeader(String name) {
-		return headers.containsHeader(name);
+		return headerGroup().containsHeader(name);
 	}
 
 	@Override /* HttpMessage */
 	public Header[] getHeaders(String name) {
-		return headers.getHeaders(name);
+		return headerGroup().getHeaders(name);
 	}
 
 	@Override /* HttpMessage */
 	public Header getFirstHeader(String name) {
-		return headers.getFirstHeader(name).orElse(null);
+		return headerGroup().getFirstHeader(name);
 	}
 
 	@Override /* HttpMessage */
 	public Header getLastHeader(String name) {
-		return headers.getLastHeader(name).orElse(null);
+		return headerGroup().getLastHeader(name);
 	}
 
 	@Override /* HttpMessage */
 	@ResponseHeader("*")
 	public Header[] getAllHeaders() {
-		return headers.getAllHeaders();
+		return headerGroup().getAllHeaders();
 	}
 
 	@Override /* HttpMessage */
 	public void addHeader(Header value) {
-		headers = headersBuilder().add(value).build();
+		headerGroupBuilder().add(value).build();
 	}
 
 	@Override /* HttpMessage */
 	public void addHeader(String name, String value) {
-		headers = headersBuilder().add(new BasicHeader(name, value)).build();
+		headerGroupBuilder().add(new BasicHeader(name, value)).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setHeader(Header value) {
-		headers = headersBuilder().update(value).build();
+		headerGroupBuilder().update(value).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setHeader(String name, String value) {
-		headers = headersBuilder().update(new BasicHeader(name, value)).build();
+		headerGroupBuilder().update(new BasicHeader(name, value)).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setHeaders(Header[] values) {
-		headers = headersBuilder().set(values).build();
+		headerGroupBuilder().set(values).build();
 	}
 
 	@Override /* HttpMessage */
 	public void removeHeader(Header value) {
-		headers = headersBuilder().remove(value).build();
+		headerGroupBuilder().remove(value).build();
 	}
 
 	@Override /* HttpMessage */
 	public void removeHeaders(String name) {
-		headers = headersBuilder().remove(name).build();
+		headerGroupBuilder().remove(name).build();
 	}
 
 	@Override /* HttpMessage */
 	public HeaderIterator headerIterator() {
-		return headers.iterator();
+		return headerGroup().iterator();
 	}
 
 	@Override /* HttpMessage */
 	public HeaderIterator headerIterator(String name) {
-		return headers.iterator(name);
+		return headerGroup().iterator(name);
 	}
 
 	@SuppressWarnings("deprecation")
@@ -303,7 +337,7 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 
 	@Override /* HttpMessage */
 	public StatusLine getStatusLine() {
-		return statusLine;
+		return statusLine();
 	}
 
 	@Override /* HttpMessage */
@@ -313,22 +347,22 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 
 	@Override /* HttpMessage */
 	public void setStatusLine(ProtocolVersion ver, int code) {
-		statusLine = statusLineBuilder().protocolVersion(ver).statusCode(code).build();
+		statusLineBuilder().protocolVersion(ver).statusCode(code).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setStatusLine(ProtocolVersion ver, int code, String reason) {
-		statusLine = statusLineBuilder().protocolVersion(ver).reasonPhrase(reason).statusCode(code).build();
+		statusLineBuilder().protocolVersion(ver).reasonPhrase(reason).statusCode(code).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setStatusCode(int code) throws IllegalStateException {
-		statusLine = statusLineBuilder().statusCode(code).build();
+		statusLineBuilder().statusCode(code).build();
 	}
 
 	@Override /* HttpMessage */
 	public void setReasonPhrase(String reason) throws IllegalStateException {
-		statusLine = statusLineBuilder().reasonPhrase(reason).build();
+		statusLineBuilder().reasonPhrase(reason).build();
 	}
 
 	@ResponseBody
@@ -353,21 +387,45 @@ public class HttpException extends BasicRuntimeException implements HttpResponse
 
 	@Override /* HttpMessage */
 	public Locale getLocale() {
-		return statusLine.getLocale();
+		return statusLine().getLocale();
 	}
 
 	@Override /* HttpMessage */
 	public void setLocale(Locale loc) {
-		statusLine = statusLineBuilder().locale(loc).build();
+		statusLineBuilder().locale(loc).build();
+	}
+
+	private BasicStatusLine statusLine() {
+		if (statusLine == null) {
+			statusLine = statusLineBuilder.build();
+			statusLineBuilder = null;
+		}
+		return statusLine;
+	}
+
+	private BasicHeaderGroup headerGroup() {
+		if (headerGroup == null) {
+			headerGroup = headerGroupBuilder.build();
+			headerGroupBuilder = null;
+		}
+		return headerGroup;
 	}
 
 	private BasicStatusLineBuilder statusLineBuilder() {
 		assertModifiable();
-		return statusLine.builder();
+		if (statusLineBuilder == null) {
+			statusLineBuilder = statusLine.builder();
+			statusLine = null;
+		}
+		return statusLineBuilder;
 	}
 
-	private BasicHeaderGroupBuilder headersBuilder() {
+	private BasicHeaderGroupBuilder headerGroupBuilder() {
 		assertModifiable();
-		return headers.builder();
+		if (headerGroupBuilder == null) {
+			headerGroupBuilder = headerGroup.builder();
+			headerGroup = null;
+		}
+		return headerGroupBuilder;
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java
index 05fa629..e1f8d87 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java
@@ -23,16 +23,19 @@ import org.apache.juneau.http.*;
 import org.apache.juneau.internal.*;
 
 /**
- * Builder for {@link HttpException} classes.
+ * Builder for {@link HttpException} beans.
  *
  * @param <T> The bean type to create for this builder.
  */
 @FluentSetters(returns="HttpExceptionBuilder<T>")
 public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeExceptionBuilder {
 
-	BasicStatusLineBuilder statusLine = BasicStatusLine.create();
-	BasicHeaderGroupBuilder headers = BasicHeaderGroup.create();
+	BasicStatusLine statusLine;
+	BasicHeaderGroup headerGroup = BasicHeaderGroup.INSTANCE;
+	BasicStatusLineBuilder statusLineBuilder;
+	BasicHeaderGroupBuilder headerGroupBuilder;
 	HttpEntity body;
+
 	private final Class<? extends HttpException> implClass;
 
 	/**
@@ -60,6 +63,49 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 		}
 	}
 
+	/**
+	 * Copies the contents of the specified HTTP response to this builder.
+	 *
+	 * @param response The response to copy from.  Must not be null.
+	 * @return This object (for method chaining).
+	 */
+	public HttpExceptionBuilder<?> copyFrom(HttpResponse response) {
+		Header h = response.getLastHeader("Exception-Message");
+		if (h != null)
+			message(h.getValue());
+		headers(response.getAllHeaders());
+		body(response.getEntity());
+		return this;
+	}
+
+	/**
+	 * Copies the values from the specified exception.
+	 *
+	 * @param value The exception to copy from.
+	 * @return This object (for method chaining).
+	 */
+	public HttpExceptionBuilder<T> copyFrom(HttpException value) {
+		super.copyFrom(value);
+		statusLine = value.statusLine;
+		headerGroup = value.headerGroup;
+		body = value.body;
+		return this;
+	}
+
+	BasicStatusLine statusLine() {
+		if (statusLineBuilder != null)
+			return statusLineBuilder.build();
+		return statusLine;
+	}
+
+	BasicHeaderGroup headerGroup() {
+		if (headerGroupBuilder != null)
+			return headerGroupBuilder.build();
+		if (headerGroup == null)
+			return BasicHeaderGroup.INSTANCE;
+		return headerGroup;
+	}
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// BasicStatusLine setters.
 	//-----------------------------------------------------------------------------------------------------------------
@@ -74,8 +120,24 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
+	public HttpExceptionBuilder<T> statusLine(BasicStatusLine value) {
+		statusLine = value;
+		statusLineBuilder = null;
+		return this;
+	}
+
+	/**
+	 * Sets the protocol version on the status line.
+	 *
+	 * <p>
+	 * If not specified, <js>"HTTP/1.1"</js> will be used.
+	 *
+	 * @param value The new value.
+	 * @return This object (for method chaining).
+	 */
+	@FluentSetter
 	public HttpExceptionBuilder<T> protocolVersion(ProtocolVersion value) {
-		statusLine.protocolVersion(value);
+		statusLineBuilder().protocolVersion(value);
 		return this;
 	}
 
@@ -90,7 +152,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 */
 	@FluentSetter
 	public HttpExceptionBuilder<T> statusCode(int value) {
-		statusLine.statusCode(value);
+		statusLineBuilder().statusCode(value);
 		return this;
 	}
 
@@ -106,7 +168,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 */
 	@FluentSetter
 	public HttpExceptionBuilder<T> reasonPhrase(String value) {
-		statusLine.reasonPhrase(value);
+		statusLineBuilder().reasonPhrase(value);
 		return this;
 	}
 
@@ -121,7 +183,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 */
 	@FluentSetter
 	public HttpExceptionBuilder<T> reasonPhraseCatalog(ReasonPhraseCatalog value) {
-		statusLine.reasonPhraseCatalog(value);
+		statusLineBuilder().reasonPhraseCatalog(value);
 		return this;
 	}
 
@@ -136,59 +198,37 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 */
 	@FluentSetter
 	public HttpExceptionBuilder<T> locale(Locale value) {
-		statusLine.locale(value);
+		statusLineBuilder().locale(value);
 		return this;
 	}
 
-	/**
-	 * Copies the values from the specified exception.
-	 *
-	 * @param value The exception to copy from.
-	 * @return This object (for method chaining).
-	 */
-	public HttpExceptionBuilder<T> copyFrom(HttpException value) {
-		super.copyFrom(value);
-		statusLine = value.statusLine.builder();
-		headers = value.headers.builder();
-		body = value.body;
-		return this;
-	}
+	//-----------------------------------------------------------------------------------------------------------------
+	// BasicHeaderGroup setters.
+	//-----------------------------------------------------------------------------------------------------------------
 
 	/**
-	 * Sets the status line builder for this builder.
+	 * Sets the protocol version on the status line.
 	 *
-	 * @param value The new status line builder.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public HttpExceptionBuilder<T> statusLineBuilder(BasicStatusLineBuilder value) {
-		statusLine = value;
-		return this;
-	}
-
-	/**
-	 * Sets the header group builder for this builder.
+	 * <p>
+	 * If not specified, <js>"HTTP/1.1"</js> will be used.
 	 *
-	 * @param value The new header group builder.
+	 * @param value The new value.
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> headerGroupBuilder(BasicHeaderGroupBuilder value) {
-		headers = value;
+	public HttpExceptionBuilder<T> headerGroup(BasicHeaderGroup value) {
+		headerGroup = value;
+		headerGroupBuilder = null;
 		return this;
 	}
 
-	//-----------------------------------------------------------------------------------------------------------------
-	// BasicHeaderGroup setters.
-	//-----------------------------------------------------------------------------------------------------------------
-
 	/**
 	 * Removes any headers already in this builder.
 	 *
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> clearHeaders() {
-		headers.clear();
+		headerGroupBuilder().clear();
 		return this;
 	}
 
@@ -199,7 +239,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> header(Header value) {
-		headers.add(value);
+		headerGroupBuilder().add(value);
 		return this;
 	}
 
@@ -211,7 +251,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> header(String name, String value) {
-		headers.add(name, value);
+		headerGroupBuilder().add(name, value);
 		return this;
 	}
 
@@ -222,7 +262,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> headers(Header...values) {
-		headers.add(values);
+		headerGroupBuilder().add(values);
 		return this;
 	}
 
@@ -233,7 +273,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> headers(List<Header> values) {
-		headers.add(values);
+		headerGroupBuilder().add(values);
 		return this;
 	}
 
@@ -244,7 +284,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> removeHeader(Header value) {
-		headers.remove(value);
+		headerGroupBuilder().remove(value);
 		return this;
 	}
 
@@ -255,7 +295,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> removeHeaders(Header...values) {
-		headers.remove(values);
+		headerGroupBuilder().remove(values);
 		return this;
 	}
 
@@ -266,7 +306,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> removeHeaders(List<Header> values) {
-		headers.remove(values);
+		headerGroupBuilder().remove(values);
 		return this;
 	}
 
@@ -280,7 +320,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> updateHeader(Header value) {
-		headers.update(value);
+		headerGroupBuilder().update(value);
 		return this;
 	}
 
@@ -294,7 +334,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> updateHeaders(Header...values) {
-		headers.update(values);
+		headerGroupBuilder().update(values);
 		return this;
 	}
 
@@ -308,7 +348,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> updateHeaders(List<Header> values) {
-		headers.update(values);
+		headerGroupBuilder().update(values);
 		return this;
 	}
 
@@ -322,7 +362,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> setHeaders(Header...values) {
-		headers.set(values);
+		headerGroupBuilder().set(values);
 		return this;
 	}
 
@@ -336,7 +376,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	public HttpExceptionBuilder<T> setHeaders(List<Header> values) {
-		headers.set(values);
+		headerGroupBuilder().set(values);
 		return this;
 	}
 
@@ -368,6 +408,26 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 		return this;
 	}
 
+	//-----------------------------------------------------------------------------------------------------------------
+	// Other methods.
+	//-----------------------------------------------------------------------------------------------------------------
+
+	private BasicStatusLineBuilder statusLineBuilder() {
+		if (statusLineBuilder == null) {
+			statusLineBuilder = statusLine == null ? BasicStatusLine.create() : statusLine.builder();
+			statusLine = null;
+		}
+		return statusLineBuilder;
+	}
+
+	private BasicHeaderGroupBuilder headerGroupBuilder() {
+		if (headerGroupBuilder == null) {
+			headerGroupBuilder = headerGroup == null ? BasicHeaderGroup.create() : headerGroup.builder();
+			headerGroup = null;
+		}
+		return headerGroupBuilder;
+	}
+
 	// <FluentSetters>
 
 	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
@@ -389,10 +449,10 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	}
 
 	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
-	public HttpExceptionBuilder<T> unmodifiable(boolean value) {
-		super.unmodifiable(value);
+	public HttpExceptionBuilder<T> unmodifiable() {
+		super.unmodifiable();
 		return this;
-	}
+	}
 
 	// </FluentSetters>
 
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpVersionNotSupported.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpVersionNotSupported.java
index ba8a67b..fcd6f0b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpVersionNotSupported.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpVersionNotSupported.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.HttpVersionNotSupported.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class HttpVersionNotSupported extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "HTTP Version Not Supported";
 
-	/** Reusable unmodifiable instance. */
-	public static final HttpVersionNotSupported INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final HttpVersionNotSupported INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class HttpVersionNotSupported extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<HttpVersionNotSupported> create() {
-		return new HttpExceptionBuilder<>(HttpVersionNotSupported.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(HttpVersionNotSupported.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,7 +75,7 @@ public class HttpVersionNotSupported extends HttpException {
 	 * Constructor.
 	 */
 	public HttpVersionNotSupported() {
-		this(create().build());
+		this(create());
 	}
 
 	/**
@@ -102,6 +107,20 @@ public class HttpVersionNotSupported extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public HttpVersionNotSupported(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InsufficientStorage.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InsufficientStorage.java
index 9c326e3..cc90748 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InsufficientStorage.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InsufficientStorage.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.InsufficientStorage.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class InsufficientStorage extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Insufficient Storage";
 
-	/** Reusable unmodifiable instance. */
-	public static final InsufficientStorage INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final InsufficientStorage INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class InsufficientStorage extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<InsufficientStorage> create() {
-		return new HttpExceptionBuilder<>(InsufficientStorage.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(InsufficientStorage.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class InsufficientStorage extends HttpException {
 	 * Constructor.
 	 */
 	public InsufficientStorage() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public InsufficientStorage(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class InsufficientStorage extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public InsufficientStorage(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InternalServerError.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InternalServerError.java
index 112d0b9..74d3402 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InternalServerError.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/InternalServerError.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.InternalServerError.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class InternalServerError extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Internal Server Error";
 
-	/** Reusable unmodifiable instance. */
-	public static final InternalServerError INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final InternalServerError INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class InternalServerError extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<InternalServerError> create() {
-		return new HttpExceptionBuilder<>(InternalServerError.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(InternalServerError.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class InternalServerError extends HttpException {
 	 * Constructor.
 	 */
 	public InternalServerError() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public InternalServerError(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class InternalServerError extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public InternalServerError(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LengthRequired.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LengthRequired.java
index af590a4..8e8eb0b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LengthRequired.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LengthRequired.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.LengthRequired.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class LengthRequired extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Length Required";
 
-	/** Reusable unmodifiable instance. */
-	public static final LengthRequired INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final LengthRequired INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class LengthRequired extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<LengthRequired> create() {
-		return new HttpExceptionBuilder<>(LengthRequired.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(LengthRequired.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class LengthRequired extends HttpException {
 	 * Constructor.
 	 */
 	public LengthRequired() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public LengthRequired(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class LengthRequired extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public LengthRequired(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Locked.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Locked.java
index d68d5e4..33bd1eb 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Locked.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Locked.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.Locked.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class Locked extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Locked";
 
-	/** Reusable unmodifiable instance. */
-	public static final Locked INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Locked INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class Locked extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<Locked> create() {
-		return new HttpExceptionBuilder<>(Locked.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(Locked.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class Locked extends HttpException {
 	 * Constructor.
 	 */
 	public Locked() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public Locked(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class Locked extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public Locked(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LoopDetected.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LoopDetected.java
index 7218c4c..d37aed7 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LoopDetected.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/LoopDetected.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.LoopDetected.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class LoopDetected extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Loop Detected";
 
-	/** Reusable unmodifiable instance. */
-	public static final LoopDetected INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final LoopDetected INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class LoopDetected extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<LoopDetected> create() {
-		return new HttpExceptionBuilder<>(LoopDetected.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(LoopDetected.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class LoopDetected extends HttpException {
 	 * Constructor.
 	 */
 	public LoopDetected() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public LoopDetected(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class LoopDetected extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public LoopDetected(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MethodNotAllowed.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MethodNotAllowed.java
index 3abfa08..5b76c1c 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MethodNotAllowed.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MethodNotAllowed.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.MethodNotAllowed.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class MethodNotAllowed extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Method Not Allowed";
 
-	/** Reusable unmodifiable instance. */
-	public static final MethodNotAllowed INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final MethodNotAllowed INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class MethodNotAllowed extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<MethodNotAllowed> create() {
-		return new HttpExceptionBuilder<>(MethodNotAllowed.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(MethodNotAllowed.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class MethodNotAllowed extends HttpException {
 	 * Constructor.
 	 */
 	public MethodNotAllowed() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public MethodNotAllowed(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class MethodNotAllowed extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public MethodNotAllowed(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MisdirectedRequest.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MisdirectedRequest.java
index ed1d557..fc36ab1 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MisdirectedRequest.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/MisdirectedRequest.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.MisdirectedRequest.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class MisdirectedRequest extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Misdirected Request";
 
-	/** Reusable unmodifiable instance. */
-	public static final MisdirectedRequest INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final MisdirectedRequest INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class MisdirectedRequest extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<MisdirectedRequest> create() {
-		return new HttpExceptionBuilder<>(MisdirectedRequest.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(MisdirectedRequest.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class MisdirectedRequest extends HttpException {
 	 * Constructor.
 	 */
 	public MisdirectedRequest() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public MisdirectedRequest(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class MisdirectedRequest extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public MisdirectedRequest(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NetworkAuthenticationRequired.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NetworkAuthenticationRequired.java
index 511a4f5..71e8d05 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NetworkAuthenticationRequired.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NetworkAuthenticationRequired.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.NetworkAuthenticationRequired.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class NetworkAuthenticationRequired extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Network Authentication Required";
 
-	/** Reusable unmodifiable instance. */
-	public static final NetworkAuthenticationRequired INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NetworkAuthenticationRequired INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class NetworkAuthenticationRequired extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<NetworkAuthenticationRequired> create() {
-		return new HttpExceptionBuilder<>(NetworkAuthenticationRequired.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(NetworkAuthenticationRequired.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class NetworkAuthenticationRequired extends HttpException {
 	 * Constructor.
 	 */
 	public NetworkAuthenticationRequired() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public NetworkAuthenticationRequired(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class NetworkAuthenticationRequired extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public NetworkAuthenticationRequired(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotAcceptable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotAcceptable.java
index 7770707..cde5e92 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotAcceptable.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotAcceptable.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.NotAcceptable.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class NotAcceptable extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Not Acceptable";
 
-	/** Reusable unmodifiable instance. */
-	public static final NotAcceptable INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NotAcceptable INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class NotAcceptable extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<NotAcceptable> create() {
-		return new HttpExceptionBuilder<>(NotAcceptable.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(NotAcceptable.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class NotAcceptable extends HttpException {
 	 * Constructor.
 	 */
 	public NotAcceptable() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public NotAcceptable(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class NotAcceptable extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public NotAcceptable(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotExtended.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotExtended.java
index f5029fd..54ea4a5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotExtended.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotExtended.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.NotExtended.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,9 +36,11 @@ public class NotExtended extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Not Extended";
 
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
 
-	/** Reusable unmodifiable instance. */
-	public static final NotExtended INSTANCE = create().unmodifiable(true).build();
+	/** Reusable unmodifiable instance */
+	public static final NotExtended INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +48,7 @@ public class NotExtended extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<NotExtended> create() {
-		return new HttpExceptionBuilder<>(NotExtended.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(NotExtended.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +75,7 @@ public class NotExtended extends HttpException {
 	 * Constructor.
 	 */
 	public NotExtended() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public NotExtended(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +98,20 @@ public class NotExtended extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public NotExtended(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotFound.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotFound.java
index bdadb09..c9e209f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotFound.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotFound.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.NotFound.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class NotFound extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Not Found";
 
-	/** Reusable unmodifiable instance. */
-	public static final NotFound INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NotFound INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class NotFound extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<NotFound> create() {
-		return new HttpExceptionBuilder<>(NotFound.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(NotFound.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class NotFound extends HttpException {
 	 * Constructor.
 	 */
 	public NotFound() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public NotFound(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class NotFound extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public NotFound(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotImplemented.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotImplemented.java
index 6d002c7..70f4c8d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotImplemented.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/NotImplemented.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.NotImplemented.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class NotImplemented extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Not Implemented";
 
-	/** Reusable unmodifiable instance. */
-	public static final NotImplemented INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NotImplemented INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class NotImplemented extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<NotImplemented> create() {
-		return new HttpExceptionBuilder<>(NotImplemented.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(NotImplemented.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class NotImplemented extends HttpException {
 	 * Constructor.
 	 */
 	public NotImplemented() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public NotImplemented(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class NotImplemented extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public NotImplemented(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PayloadTooLarge.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PayloadTooLarge.java
index d1d5f20..08faada 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PayloadTooLarge.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PayloadTooLarge.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.PayloadTooLarge.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class PayloadTooLarge extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Payload Too Large";
 
-	/** Reusable unmodifiable instance. */
-	public static final PayloadTooLarge INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final PayloadTooLarge INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class PayloadTooLarge extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<PayloadTooLarge> create() {
-		return new HttpExceptionBuilder<>(PayloadTooLarge.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(PayloadTooLarge.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class PayloadTooLarge extends HttpException {
 	 * Constructor.
 	 */
 	public PayloadTooLarge() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public PayloadTooLarge(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class PayloadTooLarge extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public PayloadTooLarge(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionFailed.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionFailed.java
index fb29c1e..4d7d3bc 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionFailed.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionFailed.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.PreconditionFailed.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class PreconditionFailed extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Precondition Failed";
 
-	/** Reusable unmodifiable instance. */
-	public static final PreconditionFailed INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final PreconditionFailed INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class PreconditionFailed extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<PreconditionFailed> create() {
-		return new HttpExceptionBuilder<>(PreconditionFailed.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(PreconditionFailed.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class PreconditionFailed extends HttpException {
 	 * Constructor.
 	 */
 	public PreconditionFailed() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public PreconditionFailed(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class PreconditionFailed extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public PreconditionFailed(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionRequired.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionRequired.java
index 8e74676..9c98a83 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionRequired.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/PreconditionRequired.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.PreconditionRequired.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class PreconditionRequired extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Precondition Required";
 
-	/** Reusable unmodifiable instance. */
-	public static final PreconditionRequired INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final PreconditionRequired INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class PreconditionRequired extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<PreconditionRequired> create() {
-		return new HttpExceptionBuilder<>(PreconditionRequired.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(PreconditionRequired.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class PreconditionRequired extends HttpException {
 	 * Constructor.
 	 */
 	public PreconditionRequired() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public PreconditionRequired(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class PreconditionRequired extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public PreconditionRequired(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RangeNotSatisfiable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RangeNotSatisfiable.java
index a8739c8..9284642 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RangeNotSatisfiable.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RangeNotSatisfiable.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.RangeNotSatisfiable.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class RangeNotSatisfiable extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Range Not Satisfiable";
 
-	/** Reusable unmodifiable instance. */
-	public static final RangeNotSatisfiable INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final RangeNotSatisfiable INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class RangeNotSatisfiable extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<RangeNotSatisfiable> create() {
-		return new HttpExceptionBuilder<>(RangeNotSatisfiable.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(RangeNotSatisfiable.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class RangeNotSatisfiable extends HttpException {
 	 * Constructor.
 	 */
 	public RangeNotSatisfiable() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public RangeNotSatisfiable(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class RangeNotSatisfiable extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public RangeNotSatisfiable(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RequestHeaderFieldsTooLarge.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RequestHeaderFieldsTooLarge.java
index 91ef8d9..9e1bb46 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RequestHeaderFieldsTooLarge.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/RequestHeaderFieldsTooLarge.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.RequestHeaderFieldsTooLarge.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class RequestHeaderFieldsTooLarge extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Request Header Fields Too Large";
 
-	/** Reusable unmodifiable instance. */
-	public static final RequestHeaderFieldsTooLarge INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final RequestHeaderFieldsTooLarge INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class RequestHeaderFieldsTooLarge extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<RequestHeaderFieldsTooLarge> create() {
-		return new HttpExceptionBuilder<>(RequestHeaderFieldsTooLarge.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(RequestHeaderFieldsTooLarge.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class RequestHeaderFieldsTooLarge extends HttpException {
 	 * Constructor.
 	 */
 	public RequestHeaderFieldsTooLarge() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public RequestHeaderFieldsTooLarge(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class RequestHeaderFieldsTooLarge extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public RequestHeaderFieldsTooLarge(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ServiceUnavailable.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ServiceUnavailable.java
index fadcbaf..b14a9d8 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ServiceUnavailable.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/ServiceUnavailable.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.ServiceUnavailable.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class ServiceUnavailable extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Service Unavailable";
 
-	/** Reusable unmodifiable instance. */
-	public static final ServiceUnavailable INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final ServiceUnavailable INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class ServiceUnavailable extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<ServiceUnavailable> create() {
-		return new HttpExceptionBuilder<>(ServiceUnavailable.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(ServiceUnavailable.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class ServiceUnavailable extends HttpException {
 	 * Constructor.
 	 */
 	public ServiceUnavailable() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public ServiceUnavailable(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class ServiceUnavailable extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public ServiceUnavailable(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/TooManyRequests.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/TooManyRequests.java
index 29e5c21..fc4b691 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/TooManyRequests.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/TooManyRequests.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.TooManyRequests.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class TooManyRequests extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Too Many Requests";
 
-	/** Reusable unmodifiable instance. */
-	public static final TooManyRequests INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final TooManyRequests INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class TooManyRequests extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<TooManyRequests> create() {
-		return new HttpExceptionBuilder<>(TooManyRequests.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(TooManyRequests.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class TooManyRequests extends HttpException {
 	 * Constructor.
 	 */
 	public TooManyRequests() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public TooManyRequests(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class TooManyRequests extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public TooManyRequests(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Unauthorized.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Unauthorized.java
index 9f1a971..b095eef 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Unauthorized.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/Unauthorized.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.Unauthorized.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -37,8 +39,11 @@ public class Unauthorized extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Unauthorized";
 
-	/** Reusable unmodifiable instance. */
-	public static final Unauthorized INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Unauthorized INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -46,7 +51,7 @@ public class Unauthorized extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<Unauthorized> create() {
-		return new HttpExceptionBuilder<>(Unauthorized.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(Unauthorized.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -73,16 +78,7 @@ public class Unauthorized extends HttpException {
 	 * Constructor.
 	 */
 	public Unauthorized() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public Unauthorized(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -105,6 +101,20 @@ public class Unauthorized extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public Unauthorized(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnavailableForLegalReasons.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnavailableForLegalReasons.java
index 6054641..005fca0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnavailableForLegalReasons.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnavailableForLegalReasons.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.UnavailableForLegalReasons.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class UnavailableForLegalReasons extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Unavailable For Legal Reasons";
 
-	/** Reusable unmodifiable instance. */
-	public static final UnavailableForLegalReasons INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final UnavailableForLegalReasons INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class UnavailableForLegalReasons extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<UnavailableForLegalReasons> create() {
-		return new HttpExceptionBuilder<>(UnavailableForLegalReasons.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(UnavailableForLegalReasons.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class UnavailableForLegalReasons extends HttpException {
 	 * Constructor.
 	 */
 	public UnavailableForLegalReasons() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public UnavailableForLegalReasons(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class UnavailableForLegalReasons extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public UnavailableForLegalReasons(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnprocessableEntity.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnprocessableEntity.java
index e334ebc..286b571 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnprocessableEntity.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnprocessableEntity.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.UnprocessableEntity.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class UnprocessableEntity extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Unprocessable Entity";
 
-	/** Reusable unmodifiable instance. */
-	public static final UnprocessableEntity INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final UnprocessableEntity INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class UnprocessableEntity extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<UnprocessableEntity> create() {
-		return new HttpExceptionBuilder<>(UnprocessableEntity.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(UnprocessableEntity.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class UnprocessableEntity extends HttpException {
 	 * Constructor.
 	 */
 	public UnprocessableEntity() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public UnprocessableEntity(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class UnprocessableEntity extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public UnprocessableEntity(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnsupportedMediaType.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnsupportedMediaType.java
index 3264f95..8649aff 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnsupportedMediaType.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UnsupportedMediaType.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.UnsupportedMediaType.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class UnsupportedMediaType extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Unsupported Media Type";
 
-	/** Reusable unmodifiable instance. */
-	public static final UnsupportedMediaType INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final UnsupportedMediaType INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class UnsupportedMediaType extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<UnsupportedMediaType> create() {
-		return new HttpExceptionBuilder<>(UnsupportedMediaType.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(UnsupportedMediaType.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class UnsupportedMediaType extends HttpException {
 	 * Constructor.
 	 */
 	public UnsupportedMediaType() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public UnsupportedMediaType(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class UnsupportedMediaType extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public UnsupportedMediaType(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UpgradeRequired.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UpgradeRequired.java
index b14b341..d09a1c3 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UpgradeRequired.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UpgradeRequired.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.UpgradeRequired.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class UpgradeRequired extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Upgrade Required";
 
-	/** Reusable unmodifiable instance. */
-	public static final UpgradeRequired INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final UpgradeRequired INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class UpgradeRequired extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<UpgradeRequired> create() {
-		return new HttpExceptionBuilder<>(UpgradeRequired.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(UpgradeRequired.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class UpgradeRequired extends HttpException {
 	 * Constructor.
 	 */
 	public UpgradeRequired() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public UpgradeRequired(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class UpgradeRequired extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public UpgradeRequired(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UriTooLong.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UriTooLong.java
index 3137752..dbc1d34 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UriTooLong.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/UriTooLong.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.UriTooLong.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -35,8 +37,11 @@ public class UriTooLong extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "URI Too Long";
 
-	/** Reusable unmodifiable instance. */
-	public static final UriTooLong INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final UriTooLong INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -44,7 +49,7 @@ public class UriTooLong extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<UriTooLong> create() {
-		return new HttpExceptionBuilder<>(UriTooLong.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(UriTooLong.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -71,16 +76,7 @@ public class UriTooLong extends HttpException {
 	 * Constructor.
 	 */
 	public UriTooLong() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public UriTooLong(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -103,6 +99,20 @@ public class UriTooLong extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public UriTooLong(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/VariantAlsoNegotiates.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/VariantAlsoNegotiates.java
index 48686a1..c4d6ed2 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/VariantAlsoNegotiates.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/VariantAlsoNegotiates.java
@@ -16,6 +16,8 @@ import static org.apache.juneau.http.exception.VariantAlsoNegotiates.*;
 
 import java.text.*;
 
+import org.apache.http.*;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 
 /**
@@ -34,8 +36,11 @@ public class VariantAlsoNegotiates extends HttpException {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Variant Also Negotiates";
 
-	/** Reusable unmodifiable instance. */
-	public static final VariantAlsoNegotiates INSTANCE = create().unmodifiable(true).build();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final VariantAlsoNegotiates INSTANCE = create().unmodifiable().build();
 
 	/**
 	 * Creates a builder for this class.
@@ -43,7 +48,7 @@ public class VariantAlsoNegotiates extends HttpException {
 	 * @return A new builder bean.
 	 */
 	public static HttpExceptionBuilder<VariantAlsoNegotiates> create() {
-		return new HttpExceptionBuilder<>(VariantAlsoNegotiates.class).statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE);
+		return new HttpExceptionBuilder<>(VariantAlsoNegotiates.class).statusLine(STATUS_LINE);
 	}
 
 	/**
@@ -70,16 +75,7 @@ public class VariantAlsoNegotiates extends HttpException {
 	 * Constructor.
 	 */
 	public VariantAlsoNegotiates() {
-		this(create().build());
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param msg The message.  Can be <jk>null</jk>.
-	 */
-	public VariantAlsoNegotiates(String msg) {
-		this(create().message(msg));
+		this(create());
 	}
 
 	/**
@@ -102,6 +98,20 @@ public class VariantAlsoNegotiates extends HttpException {
 	}
 
 	/**
+	 * Constructor.
+	 *
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
+	 */
+	public VariantAlsoNegotiates(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
+	}
+
+	/**
 	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
 	 * @return A new builder bean.
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Accepted.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Accepted.java
index 5113997..d7c32d4 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Accepted.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Accepted.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.Accepted.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,41 @@ public class Accepted extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Accepted";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Accepted INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Default unmodifiable instance */
+	public static final Accepted INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Accepted create() {
-		return new Accepted();
+	public static HttpResponseBuilder<Accepted> create() {
+		return new HttpResponseBuilder<>(Accepted.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Accepted() {
-		this(null);
+	public Accepted(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Accepted(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public Accepted(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Accepted unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/AlreadyReported.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/AlreadyReported.java
index 5dd6991..3493631 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/AlreadyReported.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/AlreadyReported.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.AlreadyReported.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class AlreadyReported extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Already Reported";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final AlreadyReported INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final AlreadyReported INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static AlreadyReported create() {
-		return new AlreadyReported();
+	public static HttpResponseBuilder<AlreadyReported> create() {
+		return new HttpResponseBuilder<>(AlreadyReported.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public AlreadyReported() {
-		this(null);
+	public AlreadyReported(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public AlreadyReported(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public AlreadyReported(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public AlreadyReported unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
index 40c9d8c..8d5379f 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicHttpResponse.java
@@ -12,253 +12,304 @@
 // ***************************************************************************************************************************
 package org.apache.juneau.http.response;
 
+import static org.apache.juneau.assertions.Assertions.*;
+
 import java.io.*;
 import java.util.*;
 
 import org.apache.http.*;
 import org.apache.http.Header;
 import org.apache.http.entity.*;
-import org.apache.http.message.*;
+import org.apache.http.params.*;
 import org.apache.juneau.annotation.*;
-import org.apache.juneau.http.BasicHeader;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.internal.*;
 
 /**
- * Superclass of all predefined responses in this package.
+ * Basic implementation of the {@link HttpResponse} interface.
+ *
+ * <p>
+ * Although this class implements the various setters defined on the {@link HttpResponse} interface, it's in general
+ * going to be more efficient to set the status/headers/content of this bean through the builder.
+ *
+ * <p>
+ * If the <c>unmodifiable</c> flag is set on this bean, calls to the setters will throw {@link UnsupportedOperationException} exceptions.
+ *
+ * <p>
+ * Beans are not thread safe unless they're marked as unmodifiable.
  */
 @Response
 @BeanIgnore
-@FluentSetters
-public abstract class BasicHttpResponse extends org.apache.http.message.BasicHttpResponse {
+public class BasicHttpResponse implements HttpResponse {
 
-	private boolean unmodifiable;
+	BasicHeaderGroup headerGroup;
+	BasicStatusLine statusLine;
+	BasicHeaderGroupBuilder headerGroupBuilder;
+	BasicStatusLineBuilder statusLineBuilder;
+	HttpEntity body;
+	final boolean unmodifiable;
 
 	/**
-	 * Constructor.
+	 * Creates a builder for this class.
 	 *
-	 * @param statusCode The HTTP status code.
-	 * @param reasonPhrase The HTTP status reason phrase.
+	 * @param implClass The subclass that the builder is going to create.
+	 * @return A new builder bean.
 	 */
-	protected BasicHttpResponse(int statusCode, String reasonPhrase) {
-		this(new BasicStatusLine(new ProtocolVersion("HTTP",1,1), statusCode, reasonPhrase));
+	public static <T extends BasicHttpResponse> HttpResponseBuilder<T> create(Class<T> implClass) {
+		return new HttpResponseBuilder<>(implClass);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param statusLine The HTTP status line.
+	 * @param builder The builder containing the arguments for this bean.
 	 */
-	protected BasicHttpResponse(StatusLine statusLine) {
-		super(statusLine);
+	public BasicHttpResponse(HttpResponseBuilder<?> builder) {
+		headerGroup = builder.headerGroup();
+		statusLine = builder.statusLine();
+		body = builder.body;
+		unmodifiable = builder.unmodifiable;
 	}
 
 	/**
-	 * Overrides the status code on this response.
+	 * Constructor.
 	 *
-	 * @param value The new status code value.
-	 * @return This object (for method chaining).
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
 	 */
-	@FluentSetter
-	public BasicHttpResponse statusCode(int value) {
-		setStatusCode(value);
-		return this;
+	public BasicHttpResponse(HttpResponse response) {
+		this(create(null).copyFrom(response));
 	}
 
 	/**
-	 * Overrides the reason phrase on this response.
+	 * Creates a builder for this class initialized with the contents of this bean.
 	 *
-	 * @param value The new reason value.
-	 * @return This object (for method chaining).
+	 * @param implClass The subclass that the builder is going to create.
+	 * @return A new builder bean.
 	 */
-	@FluentSetter
-	public BasicHttpResponse reasonPhrase(String value) {
-		setReasonPhrase(value);
-		return this;
+	public <T extends BasicHttpResponse> HttpResponseBuilder<T> builder(Class<T> implClass) {
+		return create(implClass).copyFrom(this);
 	}
 
 	/**
-	 * Adds a header to this response.
+	 * Returns the HTTP status code of this response.
 	 *
-	 * @param name The header name.
-	 * @param value The header value.
-	 * @return This object (for method chaining).
+	 * @return The HTTP status code of this response.
 	 */
-	@FluentSetter
-	public BasicHttpResponse header(String name, Object value) {
-		addHeader(new BasicHeader(name, value));
-		return this;
+	@ResponseStatus
+	public int getStatusCode() {
+		return statusLine().getStatusCode();
 	}
 
 	/**
-	 * Adds headers to this response.
+	 * Asserts that the specified HTTP response has the same status code as the one on the status line of this bean.
 	 *
-	 * @param values The header values.
-	 * @return This object (for method chaining).
+	 * @param response The HTTP response to check.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If status code is not what was expected.
 	 */
-	@FluentSetter
-	public BasicHttpResponse headers(Header...values) {
-		for (Header h : values)
-			if (h != null)
-				addHeader(h);
-		return this;
+	protected void assertStatusCode(HttpResponse response) throws AssertionError {
+		assertArgNotNull("response", response);
+		int expected = getStatusLine().getStatusCode();
+		int actual = response.getStatusLine().getStatusCode();
+		assertInteger(actual).msg("Unexpected status code.  Expected:[{0}], Actual:[{1}]", expected, actual).is(expected);
 	}
 
-	/**
-	 * Sets the entity on this response.
-	 *
-	 * @param value The entity on this response.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public BasicHttpResponse body(HttpEntity value) {
-		setEntity(value);
-		return this;
+	@Override /* Object */
+	public String toString() {
+		StringBuilder sb = new StringBuilder().append(statusLine()).append(' ').append(headerGroup());
+		if (body != null)
+			sb.append(' ').append(body);
+		return sb.toString();
 	}
 
-	/**
-	 * Sets the entity on this response.
-	 *
-	 * @param value The entity on this response.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public BasicHttpResponse body(String value) {
-		try {
-			setEntity(value == null ? null : new StringEntity(value));
-		} catch (UnsupportedEncodingException e) { /* Not possible */ }
-		return this;
+	@Override /* HttpMessage */
+	public ProtocolVersion getProtocolVersion() {
+		return statusLine().getProtocolVersion();
 	}
 
-	/**
-	 * Causes any modifications to this bean to throw an {@link UnsupportedOperationException}.
-	 *
-	 * <p>
-	 * TODO - Need to make sure headers are not modifiable through various getters.
-	 *
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public BasicHttpResponse unmodifiable() {
-		this.unmodifiable = true;
-		return this;
+	@Override /* HttpMessage */
+	public boolean containsHeader(String name) {
+		return headerGroup().containsHeader(name);
 	}
 
-	/**
-	 * Throws an {@link UnsupportedOperationException} if the unmodifiable flag is set on this bean.
-	 */
-	protected void assertModifiable() {
-		if (unmodifiable)
-			throw new UnsupportedOperationException("Bean is read-only");
+	@Override /* HttpMessage */
+	public Header[] getHeaders(String name) {
+		return headerGroup().getHeaders(name);
 	}
 
-	@Override
-	public void setStatusLine(StatusLine value) {
-		assertModifiable();
-		super.setStatusLine(value);
+	@Override /* HttpMessage */
+	public Header getFirstHeader(String name) {
+		return headerGroup().getFirstHeader(name);
 	}
 
-	@Override
-	public void setStatusLine(ProtocolVersion ver, int code) {
-		assertModifiable();
-		super.setStatusLine(ver, code);
+	@Override /* HttpMessage */
+	public Header getLastHeader(String name) {
+		return headerGroup().getLastHeader(name);
 	}
 
-	@Override
-	public void setStatusLine(ProtocolVersion ver, int code, String reason) {
-		assertModifiable();
-		super.setStatusLine(ver, code, reason);
+	@Override /* HttpMessage */
+	@ResponseHeader("*")
+	public Header[] getAllHeaders() {
+		return headerGroup().getAllHeaders();
 	}
 
-	@Override
-	public void setStatusCode(int value) {
-		assertModifiable();
-		super.setStatusCode(value);
+	@Override /* HttpMessage */
+	public void addHeader(Header value) {
+		headerGroupBuilder().add(value).build();
 	}
 
-	@Override
-	public void setReasonPhrase(String value) {
-		assertModifiable();
-		super.setReasonPhrase(value);
+	@Override /* HttpMessage */
+	public void addHeader(String name, String value) {
+		headerGroupBuilder().add(new BasicHeader(name, value)).build();
 	}
 
-	@Override
-	public void setEntity(HttpEntity value) {
-		assertModifiable();
-		super.setEntity(value);
+	@Override /* HttpMessage */
+	public void setHeader(Header value) {
+		headerGroupBuilder().update(value).build();
 	}
 
-	@Override
-	public void setLocale(Locale value) {
-		assertModifiable();
-		super.setLocale(value);
+	@Override /* HttpMessage */
+	public void setHeader(String name, String value) {
+		headerGroupBuilder().update(new BasicHeader(name, value)).build();
 	}
 
-	@Override
-	public void addHeader(Header value) {
-		assertModifiable();
-		super.addHeader(value);
+	@Override /* HttpMessage */
+	public void setHeaders(Header[] values) {
+		headerGroupBuilder().set(values).build();
 	}
 
-	@Override
-	public void addHeader(String name, String value) {
-		assertModifiable();
-		super.addHeader(name, value);
+	@Override /* HttpMessage */
+	public void removeHeader(Header value) {
+		headerGroupBuilder().remove(value).build();
 	}
 
-	@Override
-	public void setHeader(Header value) {
-		assertModifiable();
-		super.setHeader(value);
+	@Override /* HttpMessage */
+	public void removeHeaders(String name) {
+		headerGroupBuilder().remove(name).build();
 	}
 
-	@Override
-	public void setHeader(String name, String value) {
-		assertModifiable();
-		super.setHeader(name, value);
+	@Override /* HttpMessage */
+	public HeaderIterator headerIterator() {
+		return headerGroup().iterator();
 	}
 
-	@Override
-	public void setHeaders(Header[] value) {
-		assertModifiable();
-		super.setHeaders(value);
+	@Override /* HttpMessage */
+	public HeaderIterator headerIterator(String name) {
+		return headerGroup().iterator(name);
 	}
 
-	@Override
-	public void removeHeader(Header value) {
-		assertModifiable();
-		super.removeHeader(value);
+	@SuppressWarnings("deprecation")
+	@Override /* HttpMessage */
+	public HttpParams getParams() {
+		return null;
 	}
 
-	@Override
-	public void removeHeaders(String name) {
-		assertModifiable();
-		super.removeHeaders(name);
+	@SuppressWarnings("deprecation")
+	@Override /* HttpMessage */
+	public void setParams(HttpParams params) {
 	}
 
-	@ResponseHeader("*")
-	@Override /* Resource */
-	public Header[] getAllHeaders() {
-		return super.getAllHeaders();
+	@Override /* HttpMessage */
+	public StatusLine getStatusLine() {
+		return statusLine();
 	}
 
-	/**
-	 * Returns the status code on this response.
-	 *
-	 * @return The status code on this response.
-	 */
-	@ResponseStatus
-	public int getStatusCode() {
-		return super.getStatusLine().getStatusCode();
+	@Override /* HttpMessage */
+	public void setStatusLine(StatusLine value) {
+		setStatusLine(value.getProtocolVersion(), value.getStatusCode(), value.getReasonPhrase());
+	}
+
+	@Override /* HttpMessage */
+	public void setStatusLine(ProtocolVersion ver, int code) {
+		statusLineBuilder().protocolVersion(ver).statusCode(code).build();
+	}
+
+	@Override /* HttpMessage */
+	public void setStatusLine(ProtocolVersion ver, int code, String reason) {
+		statusLineBuilder().protocolVersion(ver).reasonPhrase(reason).statusCode(code).build();
+	}
+
+	@Override /* HttpMessage */
+	public void setStatusCode(int code) throws IllegalStateException {
+		statusLineBuilder().statusCode(code).build();
+	}
+
+	@Override /* HttpMessage */
+	public void setReasonPhrase(String reason) throws IllegalStateException {
+		statusLineBuilder().reasonPhrase(reason).build();
 	}
 
-	@Override
 	@ResponseBody
+	@Override /* HttpMessage */
 	public HttpEntity getEntity() {
-		return super.getEntity();
+		// Constructing a StringEntity is somewhat expensive, so don't create it unless it's needed.
+		if (body == null) {
+			try {
+				String msg = getStatusLine().getReasonPhrase();
+				if (msg != null)
+					body = new StringEntity(msg);
+			} catch (UnsupportedEncodingException e) {}
+		}
+		return body;
+	}
+
+	@Override /* HttpMessage */
+	public void setEntity(HttpEntity entity) {
+		assertModifiable();
+		this.body = entity;
+	}
+
+	@Override /* HttpMessage */
+	public Locale getLocale() {
+		return statusLine().getLocale();
 	}
 
-	// <FluentSetters>
+	@Override /* HttpMessage */
+	public void setLocale(Locale loc) {
+		statusLineBuilder().locale(loc).build();
+	}
+
+	private BasicStatusLine statusLine() {
+		if (statusLine == null) {
+			statusLine = statusLineBuilder.build();
+			statusLineBuilder = null;
+		}
+		return statusLine;
+	}
 
-	// </FluentSetters>
+	private BasicHeaderGroup headerGroup() {
+		if (headerGroup == null) {
+			headerGroup = headerGroupBuilder.build();
+			headerGroupBuilder = null;
+		}
+		return headerGroup;
+	}
+
+	private BasicStatusLineBuilder statusLineBuilder() {
+		assertModifiable();
+		if (statusLineBuilder == null) {
+			statusLineBuilder = statusLine.builder();
+			statusLine = null;
+		}
+		return statusLineBuilder;
+	}
+
+	private BasicHeaderGroupBuilder headerGroupBuilder() {
+		assertModifiable();
+		if (headerGroupBuilder == null) {
+			headerGroupBuilder = headerGroup.builder();
+			headerGroup = null;
+		}
+		return headerGroupBuilder;
+	}
+
+	/**
+	 * Throws an {@link UnsupportedOperationException} if the unmodifiable flag is set on this bean.
+	 */
+	protected final void assertModifiable() {
+		if (unmodifiable)
+			throw new UnsupportedOperationException("Bean is read-only");
+	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicLocationHttpResponse.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicLocationHttpResponse.java
deleted file mode 100644
index ec9dd3e..0000000
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/BasicLocationHttpResponse.java
+++ /dev/null
@@ -1,126 +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.http.response;
-
-import java.net.*;
-
-import org.apache.http.*;
-import org.apache.http.Header;
-import org.apache.juneau.http.annotation.*;
-import org.apache.juneau.internal.*;
-
-/**
- * Superclass of all predefined responses in this package that typically include a <c>Location</c> header.
- */
-@FluentSetters
-public abstract class BasicLocationHttpResponse extends BasicHttpResponse {
-
-	private URI location;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param statusCode The HTTP status code.
-	 * @param reasonPhrase The HTTP status reason phrase.
-	 */
-	protected BasicLocationHttpResponse(int statusCode, String reasonPhrase) {
-		super(statusCode, reasonPhrase);
-	}
-
-	/**
-	 * Constructor.
-	 *
-	 * @param statusLine The HTTP status line.
-	 */
-	protected BasicLocationHttpResponse(StatusLine statusLine) {
-		super(statusLine);
-	}
-
-	/**
-	 * Specifies the value for the <c>Location</c> header.
-	 *
-	 * @param value The new header location.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public BasicLocationHttpResponse location(URI value) {
-		assertModifiable();
-		this.location = value;
-		return this;
-	}
-
-	/**
-	 * Specifies the value for the <c>Location</c> header.
-	 *
-	 * @param value The new header location.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public BasicLocationHttpResponse location(String value) {
-		return location(URI.create(value));
-	}
-
-	/**
-	 * @return <c>Location</c> header value.
-	 */
-	@ResponseHeader(name="Location", description="Location of resource.")
-	public URI getLocation() {
-		return location;
-	}
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public BasicLocationHttpResponse unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
-}
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Continue.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Continue.java
index 59f638d..743c786 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Continue.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Continue.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.Continue.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -39,86 +39,41 @@ public class Continue extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Continue";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Continue INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Continue INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Continue create() {
-		return new Continue();
+	public static HttpResponseBuilder<Continue> create() {
+		return new HttpResponseBuilder<>(Continue.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Continue() {
-		this(null);
+	public Continue(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Continue(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public Continue(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Continue unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Created.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Created.java
index 1974c68..fa38002 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Created.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Created.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.Created.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class Created extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Created";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Created INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Created INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Created create() {
-		return new Created();
+	public static HttpResponseBuilder<Created> create() {
+		return new HttpResponseBuilder<>(Created.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Created() {
-		this(null);
+	public Created(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Created(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public Created(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Created unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/EarlyHints.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/EarlyHints.java
index 0f5f7ef..3d6f75d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/EarlyHints.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/EarlyHints.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.EarlyHints.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class EarlyHints extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Early Hints";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final EarlyHints INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final EarlyHints INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static EarlyHints create() {
-		return new EarlyHints();
+	public static HttpResponseBuilder<EarlyHints> create() {
+		return new HttpResponseBuilder<>(EarlyHints.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public EarlyHints() {
-		this(null);
+	public EarlyHints(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public EarlyHints(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public EarlyHints(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public EarlyHints unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Found.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Found.java
index 15f4d83..3c11b91 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Found.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Found.java
@@ -14,10 +14,8 @@ package org.apache.juneau.http.response;
 
 import static org.apache.juneau.http.response.Found.*;
 
-import java.net.*;
-
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -33,7 +31,7 @@ import org.apache.juneau.internal.*;
  */
 @Response(code=STATUS_CODE, description=REASON_PHRASE)
 @FluentSetters
-public class Found extends BasicLocationHttpResponse {
+public class Found extends BasicHttpResponse {
 
 	/** HTTP status code */
 	public static final int STATUS_CODE = 302;
@@ -41,98 +39,41 @@ public class Found extends BasicLocationHttpResponse {
 	/** Default message */
 	public static final String REASON_PHRASE = "Found";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Found INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Found INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Found create() {
-		return new Found();
+	public static HttpResponseBuilder<Found> create() {
+		return new HttpResponseBuilder<>(Found.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Found() {
-		this(null);
+	public Found(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Found(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found statusCode(int value) {
-		super.statusCode(value);
-		return this;
+	public Found(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Found unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public Found location(String value) {
-		super.location(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public Found location(URI value) {
-		super.location(value);
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/HttpResponseBuilder.java
similarity index 58%
copy from juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java
copy to juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/HttpResponseBuilder.java
index 05fa629..23f7fda 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/exception/HttpExceptionBuilder.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/HttpResponseBuilder.java
@@ -10,56 +10,111 @@
 // * "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.exception;
+package org.apache.juneau.http.response;
 
 import java.io.*;
+import java.net.*;
 import java.util.*;
 
 import org.apache.http.*;
 import org.apache.http.entity.*;
 import org.apache.http.impl.*;
-import org.apache.juneau.*;
 import org.apache.juneau.http.*;
+import org.apache.juneau.http.header.*;
 import org.apache.juneau.internal.*;
 
 /**
- * Builder for {@link HttpException} classes.
+ * Builder for {@link HttpResponse} beans.
  *
  * @param <T> The bean type to create for this builder.
  */
-@FluentSetters(returns="HttpExceptionBuilder<T>")
-public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeExceptionBuilder {
+@FluentSetters(returns="HttpResponseBuilder<T>")
+public class HttpResponseBuilder<T extends BasicHttpResponse> {
 
-	BasicStatusLineBuilder statusLine = BasicStatusLine.create();
-	BasicHeaderGroupBuilder headers = BasicHeaderGroup.create();
+	BasicStatusLine statusLine;
+	BasicHeaderGroup headerGroup = BasicHeaderGroup.INSTANCE;
+	BasicStatusLineBuilder statusLineBuilder;
+	BasicHeaderGroupBuilder headerGroupBuilder;
 	HttpEntity body;
-	private final Class<? extends HttpException> implClass;
+	boolean unmodifiable;
+	
+	private final Class<? extends BasicHttpResponse> implClass;
 
 	/**
 	 * Constructor.
 	 *
 	 * @param implClass
-	 * 	The subclass of {@link HttpException} to create.
-	 * 	<br>This must contain a public constructor that takes in an {@link HttpExceptionBuilder} object.
+	 * 	The subclass of {@link HttpResponse} to create.
+	 * 	<br>This must contain a public constructor that takes in an {@link HttpResponseBuilder} object.
 	 */
-	public HttpExceptionBuilder(Class<T> implClass) {
+	public HttpResponseBuilder(Class<T> implClass) {
 		this.implClass = implClass;
 	}
 
 	/**
 	 * Instantiates the exception bean from the settings in this builder.
 	 *
-	 * @return A new {@link HttpException} bean.
+	 * @return A new {@link HttpResponse} bean.
 	 */
 	@SuppressWarnings("unchecked")
 	public T build() {
 		try {
-			return (T) implClass.getConstructor(HttpExceptionBuilder.class).newInstance(this);
+			return (T) implClass.getConstructor(HttpResponseBuilder.class).newInstance(this);
 		} catch (Exception e) {
 			throw new RuntimeException(e);
 		}
 	}
 
+	/**
+	 * Copies the contents of the specified HTTP response to this builder.
+	 *
+	 * @param response The response to copy from.  Must not be null.
+	 * @return This object (for method chaining).
+	 */
+	public HttpResponseBuilder<?> copyFrom(HttpResponse response) {
+		headers(response.getAllHeaders());
+		body(response.getEntity());
+		return this;
+	}
+
+	/**
+	 * Copies the values from the specified exception.
+	 *
+	 * @param value The exception to copy from.
+	 * @return This object (for method chaining).
+	 */
+	public HttpResponseBuilder<T> copyFrom(BasicHttpResponse value) {
+		statusLine = value.statusLine;
+		headerGroup = value.headerGroup;
+		body = value.body;
+		return this;
+	}
+
+	BasicStatusLine statusLine() {
+		if (statusLineBuilder != null)
+			return statusLineBuilder.build();
+		return statusLine;
+	}
+
+	BasicHeaderGroup headerGroup() {
+		if (headerGroupBuilder != null)
+			return headerGroupBuilder.build();
+		if (headerGroup == null)
+			return BasicHeaderGroup.INSTANCE;
+		return headerGroup;
+	}
+
+	/**
+	 * Specifies whether this exception should be unmodifiable after creation.
+	 *
+	 * @return This object (for method chaining).
+	 */
+	@FluentSetter
+	public HttpResponseBuilder<T> unmodifiable() {
+		unmodifiable = true;
+		return this;
+	}
+
 	//-----------------------------------------------------------------------------------------------------------------
 	// BasicStatusLine setters.
 	//-----------------------------------------------------------------------------------------------------------------
@@ -74,8 +129,24 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> protocolVersion(ProtocolVersion value) {
-		statusLine.protocolVersion(value);
+	public HttpResponseBuilder<T> statusLine(BasicStatusLine value) {
+		statusLine = value;
+		statusLineBuilder = null;
+		return this;
+	}
+
+	/**
+	 * Sets the protocol version on the status line.
+	 *
+	 * <p>
+	 * If not specified, <js>"HTTP/1.1"</js> will be used.
+	 *
+	 * @param value The new value.
+	 * @return This object (for method chaining).
+	 */
+	@FluentSetter
+	public HttpResponseBuilder<T> protocolVersion(ProtocolVersion value) {
+		statusLineBuilder().protocolVersion(value);
 		return this;
 	}
 
@@ -89,8 +160,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> statusCode(int value) {
-		statusLine.statusCode(value);
+	public HttpResponseBuilder<T> statusCode(int value) {
+		statusLineBuilder().statusCode(value);
 		return this;
 	}
 
@@ -105,8 +176,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> reasonPhrase(String value) {
-		statusLine.reasonPhrase(value);
+	public HttpResponseBuilder<T> reasonPhrase(String value) {
+		statusLineBuilder().reasonPhrase(value);
 		return this;
 	}
 
@@ -120,8 +191,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> reasonPhraseCatalog(ReasonPhraseCatalog value) {
-		statusLine.reasonPhraseCatalog(value);
+	public HttpResponseBuilder<T> reasonPhraseCatalog(ReasonPhraseCatalog value) {
+		statusLineBuilder().reasonPhraseCatalog(value);
 		return this;
 	}
 
@@ -135,60 +206,38 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> locale(Locale value) {
-		statusLine.locale(value);
+	public HttpResponseBuilder<T> locale(Locale value) {
+		statusLineBuilder().locale(value);
 		return this;
 	}
 
-	/**
-	 * Copies the values from the specified exception.
-	 *
-	 * @param value The exception to copy from.
-	 * @return This object (for method chaining).
-	 */
-	public HttpExceptionBuilder<T> copyFrom(HttpException value) {
-		super.copyFrom(value);
-		statusLine = value.statusLine.builder();
-		headers = value.headers.builder();
-		body = value.body;
-		return this;
-	}
+	//-----------------------------------------------------------------------------------------------------------------
+	// BasicHeaderGroup setters.
+	//-----------------------------------------------------------------------------------------------------------------
 
 	/**
-	 * Sets the status line builder for this builder.
+	 * Sets the protocol version on the status line.
 	 *
-	 * @param value The new status line builder.
-	 * @return This object (for method chaining).
-	 */
-	@FluentSetter
-	public HttpExceptionBuilder<T> statusLineBuilder(BasicStatusLineBuilder value) {
-		statusLine = value;
-		return this;
-	}
-
-	/**
-	 * Sets the header group builder for this builder.
+	 * <p>
+	 * If not specified, <js>"HTTP/1.1"</js> will be used.
 	 *
-	 * @param value The new header group builder.
+	 * @param value The new value.
 	 * @return This object (for method chaining).
 	 */
 	@FluentSetter
-	public HttpExceptionBuilder<T> headerGroupBuilder(BasicHeaderGroupBuilder value) {
-		headers = value;
+	public HttpResponseBuilder<T> headerGroup(BasicHeaderGroup value) {
+		headerGroup = value;
+		headerGroupBuilder = null;
 		return this;
 	}
 
-	//-----------------------------------------------------------------------------------------------------------------
-	// BasicHeaderGroup setters.
-	//-----------------------------------------------------------------------------------------------------------------
-
 	/**
 	 * Removes any headers already in this builder.
 	 *
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> clearHeaders() {
-		headers.clear();
+	public HttpResponseBuilder<T> clearHeaders() {
+		headerGroupBuilder().clear();
 		return this;
 	}
 
@@ -198,8 +247,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The header to add.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> header(Header value) {
-		headers.add(value);
+	public HttpResponseBuilder<T> header(Header value) {
+		headerGroupBuilder().add(value);
 		return this;
 	}
 
@@ -210,8 +259,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The header value.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> header(String name, String value) {
-		headers.add(name, value);
+	public HttpResponseBuilder<T> header(String name, String value) {
+		headerGroupBuilder().add(name, value);
 		return this;
 	}
 
@@ -221,8 +270,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to add.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> headers(Header...values) {
-		headers.add(values);
+	public HttpResponseBuilder<T> headers(Header...values) {
+		headerGroupBuilder().add(values);
 		return this;
 	}
 
@@ -232,8 +281,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to add.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> headers(List<Header> values) {
-		headers.add(values);
+	public HttpResponseBuilder<T> headers(List<Header> values) {
+		headerGroupBuilder().add(values);
 		return this;
 	}
 
@@ -243,8 +292,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The header to remove.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> removeHeader(Header value) {
-		headers.remove(value);
+	public HttpResponseBuilder<T> removeHeader(Header value) {
+		headerGroupBuilder().remove(value);
 		return this;
 	}
 
@@ -254,8 +303,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to remove.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> removeHeaders(Header...values) {
-		headers.remove(values);
+	public HttpResponseBuilder<T> removeHeaders(Header...values) {
+		headerGroupBuilder().remove(values);
 		return this;
 	}
 
@@ -265,8 +314,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to remove.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> removeHeaders(List<Header> values) {
-		headers.remove(values);
+	public HttpResponseBuilder<T> removeHeaders(List<Header> values) {
+		headerGroupBuilder().remove(values);
 		return this;
 	}
 
@@ -279,8 +328,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The headers to replace.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> updateHeader(Header value) {
-		headers.update(value);
+	public HttpResponseBuilder<T> updateHeader(Header value) {
+		headerGroupBuilder().update(value);
 		return this;
 	}
 
@@ -293,8 +342,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to replace.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> updateHeaders(Header...values) {
-		headers.update(values);
+	public HttpResponseBuilder<T> updateHeaders(Header...values) {
+		headerGroupBuilder().update(values);
 		return this;
 	}
 
@@ -307,8 +356,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to replace.  <jk>null</jk> values are ignored.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> updateHeaders(List<Header> values) {
-		headers.update(values);
+	public HttpResponseBuilder<T> updateHeaders(List<Header> values) {
+		headerGroupBuilder().update(values);
 		return this;
 	}
 
@@ -321,8 +370,8 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to set
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> setHeaders(Header...values) {
-		headers.set(values);
+	public HttpResponseBuilder<T> setHeaders(Header...values) {
+		headerGroupBuilder().set(values);
 		return this;
 	}
 
@@ -335,8 +384,32 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param values The headers to set
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> setHeaders(List<Header> values) {
-		headers.set(values);
+	public HttpResponseBuilder<T> setHeaders(List<Header> values) {
+		headerGroupBuilder().set(values);
+		return this;
+	}
+
+	/**
+	 * Specifies the value for the <c>Location</c> header.
+	 *
+	 * @param value The new header location.
+	 * @return This object (for method chaining).
+	 */
+	@FluentSetter
+	public HttpResponseBuilder<T> location(URI value) {
+		updateHeader(Location.of(value));
+		return this;
+	}
+
+	/**
+	 * Specifies the value for the <c>Location</c> header.
+	 *
+	 * @param value The new header location.
+	 * @return This object (for method chaining).
+	 */
+	@FluentSetter
+	public HttpResponseBuilder<T> location(String value) {
+		updateHeader(Location.of(value));
 		return this;
 	}
 
@@ -350,7 +423,7 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The body on this response.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> body(String value) {
+	public HttpResponseBuilder<T> body(String value) {
 		try {
 			body(new StringEntity(value));
 		} catch (UnsupportedEncodingException e) { /* Not possible */ }
@@ -363,37 +436,33 @@ public class HttpExceptionBuilder<T extends HttpException> extends BasicRuntimeE
 	 * @param value The body on this response.
 	 * @return This object (for method chaining).
 	 */
-	public HttpExceptionBuilder<T> body(HttpEntity value) {
+	public HttpResponseBuilder<T> body(HttpEntity value) {
 		this.body = value;
 		return this;
 	}
 
+	//-----------------------------------------------------------------------------------------------------------------
+	// Other methods.
+	//-----------------------------------------------------------------------------------------------------------------
+
+	private BasicStatusLineBuilder statusLineBuilder() {
+		if (statusLineBuilder == null) {
+			statusLineBuilder = statusLine == null ? BasicStatusLine.create() : statusLine.builder();
+			statusLine = null;
+		}
+		return statusLineBuilder;
+	}
+
+	private BasicHeaderGroupBuilder headerGroupBuilder() {
+		if (headerGroupBuilder == null) {
+			headerGroupBuilder = headerGroup == null ? BasicHeaderGroup.create() : headerGroup.builder();
+			headerGroup = null;
+		}
+		return headerGroupBuilder;
+	}
+
 	// <FluentSetters>
-
-	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
-	public HttpExceptionBuilder<T> causedBy(Throwable value) {
-		super.causedBy(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
-	public HttpExceptionBuilder<T> copyFrom(BasicRuntimeException value) {
-		super.copyFrom(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
-	public HttpExceptionBuilder<T> message(String msg, Object...args) {
-		super.message(msg, args);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicRuntimeExceptionBuilder */
-	public HttpExceptionBuilder<T> unmodifiable(boolean value) {
-		super.unmodifiable(value);
-		return this;
-	}
-
+
 	// </FluentSetters>
 
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/IMUsed.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/IMUsed.java
index 315e15a..643e083 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/IMUsed.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/IMUsed.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.IMUsed.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class IMUsed extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "IM Used";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final IMUsed INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final IMUsed INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static IMUsed create() {
-		return new IMUsed();
+	public static HttpResponseBuilder<IMUsed> create() {
+		return new HttpResponseBuilder<>(IMUsed.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public IMUsed() {
-		this(null);
+	public IMUsed(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public IMUsed(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public IMUsed(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public IMUsed unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MovedPermanently.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MovedPermanently.java
index bbfdddc..eaa3e19 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MovedPermanently.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MovedPermanently.java
@@ -14,10 +14,8 @@ package org.apache.juneau.http.response;
 
 import static org.apache.juneau.http.response.MovedPermanently.*;
 
-import java.net.*;
-
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -29,7 +27,7 @@ import org.apache.juneau.internal.*;
  */
 @Response(code=STATUS_CODE, description=REASON_PHRASE)
 @FluentSetters
-public class MovedPermanently extends BasicLocationHttpResponse {
+public class MovedPermanently extends BasicHttpResponse {
 
 	/** HTTP status code */
 	public static final int STATUS_CODE = 301;
@@ -37,98 +35,41 @@ public class MovedPermanently extends BasicLocationHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Moved Permanently";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final MovedPermanently INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final MovedPermanently INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static MovedPermanently create() {
-		return new MovedPermanently();
+	public static HttpResponseBuilder<MovedPermanently> create() {
+		return new HttpResponseBuilder<>(MovedPermanently.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public MovedPermanently() {
-		this(null);
+	public MovedPermanently(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public MovedPermanently(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently statusCode(int value) {
-		super.statusCode(value);
-		return this;
+	public MovedPermanently(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MovedPermanently unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public MovedPermanently location(String value) {
-		super.location(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public MovedPermanently location(URI value) {
-		super.location(value);
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultiStatus.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultiStatus.java
index 873f32e..4652a4b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultiStatus.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultiStatus.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.MultiStatus.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class MultiStatus extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Multi-Status";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final MultiStatus INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final MultiStatus INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static MultiStatus create() {
-		return new MultiStatus();
+	public static HttpResponseBuilder<MultiStatus> create() {
+		return new HttpResponseBuilder<>(MultiStatus.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public MultiStatus() {
-		this(null);
+	public MultiStatus(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public MultiStatus(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public MultiStatus(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultiStatus unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultipleChoices.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultipleChoices.java
index cbcc731..54fb524 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultipleChoices.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/MultipleChoices.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.MultipleChoices.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,41 @@ public class MultipleChoices extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Multiple Choices";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final MultipleChoices INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final MultipleChoices INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static MultipleChoices create() {
-		return new MultipleChoices();
+	public static HttpResponseBuilder<MultipleChoices> create() {
+		return new HttpResponseBuilder<>(MultipleChoices.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public MultipleChoices() {
-		this(null);
+	public MultipleChoices(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public MultipleChoices(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public MultipleChoices(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public MultipleChoices unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NoContent.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NoContent.java
index c40a793..f0c648e 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NoContent.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NoContent.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.NoContent.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class NoContent extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "No Content";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final NoContent INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NoContent INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static NoContent create() {
-		return new NoContent();
+	public static HttpResponseBuilder<NoContent> create() {
+		return new HttpResponseBuilder<>(NoContent.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public NoContent() {
-		this(null);
+	public NoContent(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public NoContent(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public NoContent(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NoContent unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NonAuthoritiveInformation.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NonAuthoritiveInformation.java
index f5e3f7e..a9f6458 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NonAuthoritiveInformation.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NonAuthoritiveInformation.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.NonAuthoritiveInformation.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class NonAuthoritiveInformation extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Non-Authoritative Information";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final NonAuthoritiveInformation INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NonAuthoritiveInformation INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static NonAuthoritiveInformation create() {
-		return new NonAuthoritiveInformation();
+	public static HttpResponseBuilder<NonAuthoritiveInformation> create() {
+		return new HttpResponseBuilder<>(NonAuthoritiveInformation.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public NonAuthoritiveInformation() {
-		this(null);
+	public NonAuthoritiveInformation(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public NonAuthoritiveInformation(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public NonAuthoritiveInformation(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NonAuthoritiveInformation unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NotModified.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NotModified.java
index fb3760d..5288c30 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NotModified.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/NotModified.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.NotModified.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,41 @@ public class NotModified extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Not Modified";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final NotModified INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final NotModified INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static NotModified create() {
-		return new NotModified();
+	public static HttpResponseBuilder<NotModified> create() {
+		return new HttpResponseBuilder<>(NotModified.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public NotModified() {
-		this(null);
+	public NotModified(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public NotModified(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public NotModified(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public NotModified unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Ok.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Ok.java
index 70704e3..55579e5 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Ok.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Ok.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.Ok.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -37,86 +37,41 @@ public class Ok extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "OK";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Ok INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Ok INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Ok create() {
-		return new Ok();
+	public static HttpResponseBuilder<Ok> create() {
+		return new HttpResponseBuilder<>(Ok.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Ok() {
-		this(null);
+	public Ok(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Ok(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public Ok(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Ok unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PartialContent.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PartialContent.java
index 0e87b4c..51985ef 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PartialContent.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PartialContent.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.PartialContent.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,41 @@ public class PartialContent extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Partial Content";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final PartialContent INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final PartialContent INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static PartialContent create() {
-		return new PartialContent();
+	public static HttpResponseBuilder<PartialContent> create() {
+		return new HttpResponseBuilder<>(PartialContent.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public PartialContent() {
-		this(null);
+	public PartialContent(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public PartialContent(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public PartialContent(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PartialContent unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PermanentRedirect.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PermanentRedirect.java
index e209960..2af717d 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PermanentRedirect.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/PermanentRedirect.java
@@ -14,10 +14,8 @@ package org.apache.juneau.http.response;
 
 import static org.apache.juneau.http.response.PermanentRedirect.*;
 
-import java.net.*;
-
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -30,7 +28,7 @@ import org.apache.juneau.internal.*;
  */
 @Response(code=STATUS_CODE, description=REASON_PHRASE)
 @FluentSetters
-public class PermanentRedirect extends BasicLocationHttpResponse {
+public class PermanentRedirect extends BasicHttpResponse {
 
 	/** HTTP status code */
 	public static final int STATUS_CODE = 308;
@@ -38,98 +36,41 @@ public class PermanentRedirect extends BasicLocationHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Permanent Redirect";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final PermanentRedirect INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final PermanentRedirect INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static PermanentRedirect create() {
-		return new PermanentRedirect();
+	public static HttpResponseBuilder<PermanentRedirect> create() {
+		return new HttpResponseBuilder<>(PermanentRedirect.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public PermanentRedirect() {
-		this(null);
+	public PermanentRedirect(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public PermanentRedirect(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect statusCode(int value) {
-		super.statusCode(value);
-		return this;
+	public PermanentRedirect(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public PermanentRedirect unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public PermanentRedirect location(String value) {
-		super.location(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public PermanentRedirect location(URI value) {
-		super.location(value);
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Processing.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Processing.java
index 29d025d..b7cb968 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Processing.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/Processing.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.Processing.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -37,86 +37,41 @@ public class Processing extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Processing";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final Processing INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final Processing INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static Processing create() {
-		return new Processing();
+	public static HttpResponseBuilder<Processing> create() {
+		return new HttpResponseBuilder<>(Processing.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public Processing() {
-		this(null);
+	public Processing(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public Processing(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public Processing(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public Processing unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/ResetContent.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/ResetContent.java
index b76a9fe..dd72d22 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/ResetContent.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/ResetContent.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.ResetContent.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,41 @@ public class ResetContent extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Reset Content";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final ResetContent INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final ResetContent INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static ResetContent create() {
-		return new ResetContent();
+	public static HttpResponseBuilder<ResetContent> create() {
+		return new HttpResponseBuilder<>(ResetContent.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public ResetContent() {
-		this(null);
+	public ResetContent(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public ResetContent(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public ResetContent(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public ResetContent unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SeeOther.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SeeOther.java
index 5ee80c1..a31c187 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SeeOther.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SeeOther.java
@@ -14,10 +14,8 @@ package org.apache.juneau.http.response;
 
 import static org.apache.juneau.http.response.SeeOther.*;
 
-import java.net.*;
-
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -30,7 +28,7 @@ import org.apache.juneau.internal.*;
  */
 @Response(code=STATUS_CODE, description=REASON_PHRASE)
 @FluentSetters
-public class SeeOther extends BasicLocationHttpResponse {
+public class SeeOther extends BasicHttpResponse {
 
 	/** HTTP status code */
 	public static final int STATUS_CODE = 303;
@@ -38,98 +36,41 @@ public class SeeOther extends BasicLocationHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "See Other";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final SeeOther INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final SeeOther INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static SeeOther create() {
-		return new SeeOther();
+	public static HttpResponseBuilder<SeeOther> create() {
+		return new HttpResponseBuilder<>(SeeOther.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public SeeOther() {
-		this(null);
+	public SeeOther(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public SeeOther(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther statusCode(int value) {
-		super.statusCode(value);
-		return this;
+	public SeeOther(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SeeOther unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public SeeOther location(String value) {
-		super.location(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public SeeOther location(URI value) {
-		super.location(value);
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/StandardResponses.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/StandardResponses.java
index 11d5812..e0a2c1b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/StandardResponses.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/StandardResponses.java
@@ -132,7 +132,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static Accepted accepted() {
+	public static HttpResponseBuilder<Accepted> accepted() {
 		return Accepted.create();
 	}
 
@@ -141,7 +141,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static AlreadyReported alreadyReported() {
+	public static HttpResponseBuilder<AlreadyReported> alreadyReported() {
 		return AlreadyReported.create();
 	}
 
@@ -150,7 +150,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static Continue _continue() {
+	public static HttpResponseBuilder<Continue> _continue() {
 		return Continue.create();
 	}
 
@@ -159,7 +159,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static Created created() {
+	public static HttpResponseBuilder<Created> created() {
 		return Created.create();
 	}
 
@@ -168,7 +168,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static EarlyHints earlyHints() {
+	public static HttpResponseBuilder<EarlyHints> earlyHints() {
 		return EarlyHints.create();
 	}
 
@@ -178,7 +178,7 @@ public class StandardResponses {
 	 * @param location The value for the Location header.
 	 * @return A new bean.
 	 */
-	public static Found found(String location) {
+	public static HttpResponseBuilder<Found> found(String location) {
 		return Found.create().location(location);
 	}
 
@@ -187,7 +187,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static IMUsed imUsed() {
+	public static HttpResponseBuilder<IMUsed> imUsed() {
 		return IMUsed.create();
 	}
 
@@ -197,7 +197,7 @@ public class StandardResponses {
 	 * @param location The value for the Location header.
 	 * @return A new bean.
 	 */
-	public static MovedPermanently movedPermanently(String location) {
+	public static HttpResponseBuilder<MovedPermanently> movedPermanently(String location) {
 		return MovedPermanently.create().location(location);
 	}
 
@@ -206,7 +206,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static MultipleChoices multipleChoices() {
+	public static HttpResponseBuilder<MultipleChoices> multipleChoices() {
 		return MultipleChoices.create();
 	}
 
@@ -215,7 +215,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static MultiStatus multiStatus() {
+	public static HttpResponseBuilder<MultiStatus> multiStatus() {
 		return MultiStatus.create();
 	}
 
@@ -224,7 +224,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static NoContent noContent() {
+	public static HttpResponseBuilder<NoContent> noContent() {
 		return NoContent.create();
 	}
 
@@ -233,7 +233,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static NonAuthoritiveInformation nonAuthoritiveInformation() {
+	public static HttpResponseBuilder<NonAuthoritiveInformation> nonAuthoritiveInformation() {
 		return NonAuthoritiveInformation.create();
 	}
 
@@ -242,7 +242,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static NotModified notModified() {
+	public static HttpResponseBuilder<NotModified> notModified() {
 		return NotModified.create();
 	}
 
@@ -251,7 +251,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static Ok ok() {
+	public static HttpResponseBuilder<Ok> ok() {
 		return Ok.create();
 	}
 
@@ -260,7 +260,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static PartialContent partialContent() {
+	public static HttpResponseBuilder<PartialContent> partialContent() {
 		return PartialContent.create();
 	}
 
@@ -270,7 +270,7 @@ public class StandardResponses {
 	 * @param location The value for the Location header.
 	 * @return A new bean.
 	 */
-	public static PermanentRedirect permanentRedirect(String location) {
+	public static HttpResponseBuilder<PermanentRedirect> permanentRedirect(String location) {
 		return PermanentRedirect.create().location(location);
 	}
 
@@ -279,7 +279,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static Processing processing() {
+	public static HttpResponseBuilder<Processing> processing() {
 		return Processing.create();
 	}
 
@@ -288,7 +288,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static ResetContent resetContent() {
+	public static HttpResponseBuilder<ResetContent> resetContent() {
 		return ResetContent.create();
 	}
 
@@ -298,7 +298,7 @@ public class StandardResponses {
 	 * @param location The value for the Location header.
 	 * @return A new bean.
 	 */
-	public static SeeOther seeOther(String location) {
+	public static HttpResponseBuilder<SeeOther> seeOther(String location) {
 		return SeeOther.create().location(location);
 	}
 
@@ -307,7 +307,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static SwitchingProtocols switchingProtocols() {
+	public static HttpResponseBuilder<SwitchingProtocols> switchingProtocols() {
 		return SwitchingProtocols.create();
 	}
 
@@ -317,7 +317,7 @@ public class StandardResponses {
 	 * @param location The value for the Location header.
 	 * @return A new bean.
 	 */
-	public static TemporaryRedirect temporaryRedirect(String location) {
+	public static HttpResponseBuilder<TemporaryRedirect> temporaryRedirect(String location) {
 		return TemporaryRedirect.create().location(location);
 	}
 
@@ -326,7 +326,7 @@ public class StandardResponses {
 	 *
 	 * @return A new bean.
 	 */
-	public static UseProxy useProxy() {
+	public static HttpResponseBuilder<UseProxy> useProxy() {
 		return UseProxy.create();
 	}
 }
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SwitchingProtocols.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SwitchingProtocols.java
index 222767b..d63d3c0 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SwitchingProtocols.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/SwitchingProtocols.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.SwitchingProtocols.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -35,86 +35,41 @@ public class SwitchingProtocols extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Switching Protocols";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final SwitchingProtocols INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final SwitchingProtocols INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static SwitchingProtocols create() {
-		return new SwitchingProtocols();
+	public static HttpResponseBuilder<SwitchingProtocols> create() {
+		return new HttpResponseBuilder<>(SwitchingProtocols.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public SwitchingProtocols() {
-		this(null);
+	public SwitchingProtocols(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public SwitchingProtocols(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols body(HttpEntity value) {
-		super.body(value);
-		return this;
+	public SwitchingProtocols(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public SwitchingProtocols unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/TemporaryRedirect.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/TemporaryRedirect.java
index b63ed1d..d15720b 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/TemporaryRedirect.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/TemporaryRedirect.java
@@ -14,10 +14,8 @@ package org.apache.juneau.http.response;
 
 import static org.apache.juneau.http.response.TemporaryRedirect.*;
 
-import java.net.*;
-
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -31,7 +29,7 @@ import org.apache.juneau.internal.*;
  */
 @Response(code=STATUS_CODE, description=REASON_PHRASE)
 @FluentSetters
-public class TemporaryRedirect extends BasicLocationHttpResponse {
+public class TemporaryRedirect extends BasicHttpResponse {
 
 	/** HTTP status code */
 	public static final int STATUS_CODE = 307;
@@ -39,98 +37,41 @@ public class TemporaryRedirect extends BasicLocationHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Temporary Redirect";
 
-	/**
-	 * Default unmodifiable instance.
-	 *
-	 * <br>Response body contains the reason phrase.
-	 */
-	public static final TemporaryRedirect INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	/** Default status line */
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
+	/** Reusable unmodifiable instance */
+	public static final TemporaryRedirect INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static TemporaryRedirect create() {
-		return new TemporaryRedirect();
+	public static HttpResponseBuilder<TemporaryRedirect> create() {
+		return new HttpResponseBuilder<>(TemporaryRedirect.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public TemporaryRedirect() {
-		this(null);
+	public TemporaryRedirect(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public TemporaryRedirect(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect statusCode(int value) {
-		super.statusCode(value);
-		return this;
+	public TemporaryRedirect(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public TemporaryRedirect unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public TemporaryRedirect location(String value) {
-		super.location(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicLocationHttpResponse */
-	public TemporaryRedirect location(URI value) {
-		super.location(value);
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/UseProxy.java b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/UseProxy.java
index 39eb00c..112dc85 100644
--- a/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/UseProxy.java
+++ b/juneau-core/juneau-marshall/src/main/java/org/apache/juneau/http/response/UseProxy.java
@@ -15,7 +15,7 @@ package org.apache.juneau.http.response;
 import static org.apache.juneau.http.response.UseProxy.*;
 
 import org.apache.http.*;
-import org.apache.http.Header;
+import org.apache.juneau.http.*;
 import org.apache.juneau.http.annotation.*;
 import org.apache.juneau.internal.*;
 
@@ -36,86 +36,44 @@ public class UseProxy extends BasicHttpResponse {
 	/** Reason phrase */
 	public static final String REASON_PHRASE = "Use Proxy";
 
+	private static final BasicStatusLine STATUS_LINE = BasicStatusLine.create().statusCode(STATUS_CODE).reasonPhrase(REASON_PHRASE).build();
+
 	/**
 	 * Default unmodifiable instance.
 	 *
 	 * <br>Response body contains the reason phrase.
 	 */
-	public static final UseProxy INSTANCE = create().body(REASON_PHRASE).unmodifiable();
+	public static final UseProxy INSTANCE = create().unmodifiable().build();
 
 	/**
-	 * Static creator.
+	 * Creates a builder for this class.
 	 *
-	 * @return A new instance of this bean.
+	 * @return A new builder bean.
 	 */
-	public static UseProxy create() {
-		return new UseProxy();
+	public static HttpResponseBuilder<UseProxy> create() {
+		return new HttpResponseBuilder<>(UseProxy.class).statusLine(STATUS_LINE);
 	}
 
 	/**
 	 * Constructor.
+	 *
+	 * @param builder The builder containing the settings for this exception.
 	 */
-	public UseProxy() {
-		this(null);
+	public UseProxy(HttpResponseBuilder<?> builder) {
+		super(builder);
 	}
 
 	/**
 	 * Constructor.
 	 *
-	 * @param body Body of the response.  Can be <jk>null</jk>.
+	 * <p>
+	 * This is the constructor used when parsing an HTTP response.
+	 *
+	 * @param response The HTTP response to copy from.  Must not be <jk>null</jk>.
+	 * @throws AssertionError If HTTP response status code does not match what was expected.
 	 */
-	public UseProxy(String body) {
-		super(STATUS_CODE, REASON_PHRASE);
-		body(body);
-	}
-
-	//------------------------------------------------------------------------------------------------------------------
-	// Fluent setters.
-	//------------------------------------------------------------------------------------------------------------------
-
-	// <FluentSetters>
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy body(String value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy body(HttpEntity value) {
-		super.body(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy header(String name, Object value) {
-		super.header(name, value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy headers(Header...values) {
-		super.headers(values);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy reasonPhrase(String value) {
-		super.reasonPhrase(value);
-		return this;
+	public UseProxy(HttpResponse response) {
+		this(create().copyFrom(response));
+		assertStatusCode(response);
 	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy statusCode(int value) {
-		super.statusCode(value);
-		return this;
-	}
-
-	@Override /* GENERATED - BasicHttpResponse */
-	public UseProxy unmodifiable() {
-		super.unmodifiable();
-		return this;
-	}
-
-	// </FluentSetters>
 }
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
index f01b595..671ccdc 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/ResponseBody.java
@@ -660,6 +660,15 @@ public class ResponseBody implements HttpEntity {
 			if (type.is(HttpResponse.class))
 				return (T)response;
 
+			ConstructorInfo ci = type.getInfo().getPublicConstructor(HttpResponse.class);
+			if (ci != null) {
+				try {
+					return (T)ci.invoke(response);
+				} catch (ExecutableException e) {
+					throw new RuntimeException(e);
+				}
+			}
+
 			if (type.isChildOf(HttpResource.class)) {
 				BasicHttpResource r = BasicHttpResource.of(asInputStream());
 				for (Header h : response.getAllHeaders()) {
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
index cc1a502..42149f3 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestClient.java
@@ -3167,6 +3167,7 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re
 		try {
 			Object ret = null;
 			RestResponse res = null;
+			rc.rethrow(RuntimeException.class).rethrow(rom.getExceptions());
 			if (ror.getReturnValue() == RemoteReturn.NONE) {
 				res = rc.complete();
 			} else if (ror.getReturnValue() == RemoteReturn.STATUS) {
@@ -3191,15 +3192,16 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re
 				Object v = res.getBody().asType(ror.getReturnType());
 				if (v == null && rt.isPrimitive())
 					v = ClassInfo.of(rt).getPrimitiveDefault();
-				if (rt.getName().equals(res.getStringHeader("Exception-Name").orElse(null)))
-					res.removeHeaders("Exception-Name");
 				ret = v;
 			}
-
-			ThrowableUtils.throwException(res.getStringHeader("Exception-Name").orElse(null), res.getStringHeader("Exception-Message").orElse(null), rom.getExceptions());
 			return ret;
 		} catch (RestCallException e) {
-			ThrowableUtils.throwException(e.getServerExceptionName(), e.getServerExceptionMessage(), rom.getExceptions());
+			Throwable t = e.getCause();
+			if (t instanceof RuntimeException)
+				throw t;
+			for (Class<?> t2 : method.getExceptionTypes())
+				if (t2.isInstance(t))
+					throw t;
 			throw new RuntimeException(e);
 		}
 	}
@@ -3304,18 +3306,33 @@ public class RestClient extends BeanContext implements HttpClient, Closeable, Re
 					RrpcInterfaceMethodMeta rim = rm.getMethodMeta(method);
 
 					String uri = rim.getUri();
+					RestResponse res = null;
 
 					try {
-						RestRequest rc = request("POST", uri, true).serializer(serializer).body(args);
+						RestRequest rc = request("POST", uri, true)
+							.serializer(serializer)
+							.body(args)
+							.rethrow(RuntimeException.class)
+							.rethrow(method.getExceptionTypes());
+
+						res = rc.run();
 
-						Object v = rc.run().getBody().asType(method.getGenericReturnType());
+						Object v = res.getBody().asType(method.getGenericReturnType());
 						if (v == null && method.getReturnType().isPrimitive())
 							v = ClassInfo.of(method.getReturnType()).getPrimitiveDefault();
 						return v;
 
-					} catch (RestCallException e) {
-						// Try to throw original exception if possible.
-						ThrowableUtils.throwException(e.getServerExceptionName(), e.getServerExceptionMessage(), method.getExceptionTypes());
+					} catch (Throwable e) {
+						if (e instanceof RestCallException) {
+							Throwable t = e.getCause();
+							if (t != null)
+								e = t;
+						}
+						if (e instanceof RuntimeException)
+							throw e;
+						for (Class<?> t2 : method.getExceptionTypes())
+							if (t2.isInstance(e))
+								throw e;
 						throw new RuntimeException(e);
 					}
 				}
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
index 33c7a05..16128a8 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/RestRequest.java
@@ -49,6 +49,7 @@ 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.*;
@@ -87,6 +88,7 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 	private Predicate<Integer> errorCodes;
 	private HttpHost target;
 	private HttpContext context;
+	private List<Class<? extends Throwable>> rethrow;
 
 	/**
 	 * Constructs a REST call with the specified method name.
@@ -691,6 +693,30 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 	}
 
 	/**
+	 * Rethrow any of the specified exception types if a matching <c>Exception-Name</c> header is found.
+	 *
+	 * <p>
+	 * Rethrown exceptions will be set on the caused-by exception of {@link RestCallException} when
+	 * thrown from the {@link #run()} method.
+	 *
+	 * <p>
+	 * Can be called multiple times to append multiple rethrows.
+	 *
+	 * @param values The classes to rethrow.
+	 * @return This object (for method chaining).
+	 */
+	@SuppressWarnings("unchecked")
+	public RestRequest rethrow(Class<?>...values) {
+		if (rethrow == null)
+			rethrow = new ArrayList<>();
+		for (Class<?> v : values) {
+			if (v != null && Throwable.class.isAssignableFrom(v))
+				rethrow.add((Class<? extends Throwable>)v);
+		}
+		return this;
+	}
+
+	/**
 	 * Sets <c>Debug: value</c> header on this request.
 	 *
 	 * @return This object (for method chaining).
@@ -2909,6 +2935,28 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 			String method = getMethod();
 			int sc = response.getStatusCode();
 
+			if (response.containsHeader("Exception-Name") && rethrow != null) {
+				String exceptionName = response.getStringHeader("Exception-Name").orElse(null);
+				for (Class<? extends Throwable> t : rethrow) {
+					if (t.getName().equals(exceptionName)) {
+						ConstructorInfo c = null;
+						ClassInfo ci = ClassInfo.of(t);
+						c = ci.getPublicConstructor(HttpResponse.class);
+						if (c != null)
+							throw c.<Throwable>invoke(response);
+						c = ci.getPublicConstructor(String.class);
+						if (c != null)
+							throw c.<Throwable>invoke(response.getStringHeader("Exception-Message").orElse(response.getBody().asString()));
+						c = ci.getPublicConstructor(String.class,Throwable.class);
+						if (c != null)
+							throw c.<Throwable>invoke(response.getStringHeader("Exception-Message").orElse(response.getBody().asString()), null);
+						c = ci.getPublicConstructor();
+						if (c != null)
+							throw c.<Throwable>invoke();
+					}
+				}
+			}
+
 			if (errorCodes.test(sc) && ! ignoreErrors) {
 				throw new RestCallException(response, null, "HTTP method ''{0}'' call to ''{1}'' caused response code ''{2}, {3}''.\nResponse: \n{4}",
 					method, getURI(), sc, response.getReasonPhrase(), response.getBody().asAbbreviatedString(1000));
@@ -2918,7 +2966,7 @@ public class RestRequest extends BeanSession implements HttpUriRequest, Configur
 			if (response != null)
 				response.close();
 			throw e;
-		} catch (Exception e) {
+		} catch (Throwable e) {
 			if (response != null)
 				response.close();
 			throw new RestCallException(response, e, "Call failed.");
diff --git a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
index 2dbdfa7..73374b7 100644
--- a/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
+++ b/juneau-rest/juneau-rest-client/src/main/java/org/apache/juneau/rest/client/remote/RemoteOperationMeta.java
@@ -92,7 +92,7 @@ public class RemoteOperationMeta {
 
 			String value1 = al.filter(x->x.isType(RemoteOp.class)).getValues(String.class, "value").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
 			String value2 = al.filter(x->!x.isType(RemoteOp.class)).getValues(String.class, "value").stream().filter(x -> isNotEmpty(x)).findFirst().orElse("").trim();
-			
+
 			if (isNotEmpty(value1)) {
 				int i = value1.indexOf(' ');
 				if (i == -1) {
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/SeeOtherRoot.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/SeeOtherRoot.java
index f14db58..0f06d9b 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/SeeOtherRoot.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/helper/SeeOtherRoot.java
@@ -30,8 +30,7 @@ public class SeeOtherRoot extends SeeOther {
 	 * Constructor.
 	 */
 	public SeeOtherRoot() {
-		super();
-		location("servlet:/");
+		super(create().location("servlet:/"));
 	}
 
 	/**
@@ -39,9 +38,9 @@ public class SeeOtherRoot extends SeeOther {
 	 * <p>
 	 * Used for end-to-end interfaces.
 	 *
-	 * @param message Message to send as the response.
+	 * @param body Message to send as the response.
 	 */
-	public SeeOtherRoot(String message) {
-		super(message);
+	public SeeOtherRoot(String body) {
+		super(create().location("servlet:/").body(body));
 	}
 }
\ No newline at end of file
diff --git a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
index 0d56c6f..c480030 100644
--- a/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
+++ b/juneau-rest/juneau-rest-server/src/main/java/org/apache/juneau/rest/reshandlers/DefaultHandler.java
@@ -112,6 +112,9 @@ public class DefaultHandler implements ResponseHandler {
 								SerializedNameValuePair x = ((SerializedNameValuePair)ho2).copy().serializerIfNotSet(ps);
 								x.schemaIfNotSet(partSchema.getProperty(x.getName()));
 								res.setHeader(x.getName(), x.getValue());
+							} else if (ho2 instanceof BasicUriHeader) {
+								BasicUriHeader x = (BasicUriHeader)ho2;
+								res.setHeader(x.getName(), req.getUriResolver().resolve(x.getValue()));
 							} else if (ho2 instanceof Header) {
 								Header x = (Header)ho2;
 								res.setHeader(x.getName(), x.getValue());
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Accepted_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Accepted_Test.java
index 6b47a55..8950325 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Accepted_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Accepted_Test.java
@@ -25,8 +25,8 @@ public class Accepted_Test {
 	@Rest
 	public static class A {
 		@RestGet public Accepted a1() { return ACCEPTED; }
-		@RestGet public Accepted a2() { return accepted().body("foo"); }
-		@RestGet public Accepted a3() { return accepted().header("Foo","bar"); }
+		@RestGet public Accepted a2() { return accepted().body("foo").build(); }
+		@RestGet public Accepted a3() { return accepted().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/AlreadyReported_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/AlreadyReported_Test.java
index 88cf67b..a7527e2 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/AlreadyReported_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/AlreadyReported_Test.java
@@ -25,8 +25,8 @@ public class AlreadyReported_Test {
 	@Rest
 	public static class A {
 		@RestGet public AlreadyReported a1() { return ALREADY_REPORTED; }
-		@RestGet public AlreadyReported a2() { return alreadyReported().body("foo"); }
-		@RestGet public AlreadyReported a3() { return alreadyReported().header("Foo","bar"); }
+		@RestGet public AlreadyReported a2() { return alreadyReported().body("foo").build(); }
+		@RestGet public AlreadyReported a3() { return alreadyReported().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Continue_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Continue_Test.java
index fac8ebd..77bf1f4 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Continue_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Continue_Test.java
@@ -25,8 +25,8 @@ public class Continue_Test {
 	@Rest
 	public static class A {
 		@RestGet public Continue a1() { return CONTINUE; }
-		@RestGet public Continue a2() { return _continue().body("foo"); }
-		@RestGet public Continue a3() { return _continue().header("Foo","bar"); }
+		@RestGet public Continue a2() { return _continue().body("foo").build(); }
+		@RestGet public Continue a3() { return _continue().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Created_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Created_Test.java
index affca7e..fe7d131 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Created_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Created_Test.java
@@ -25,8 +25,8 @@ public class Created_Test {
 	@Rest
 	public static class A {
 		@RestGet public Created a1() { return CREATED; }
-		@RestGet public Created a2() { return created().body("foo"); }
-		@RestGet public Created a3() { return created().header("Foo","bar"); }
+		@RestGet public Created a2() { return created().body("foo").build(); }
+		@RestGet public Created a3() { return created().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/EarlyHints_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/EarlyHints_Test.java
index 1b76405..2c3d13b 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/EarlyHints_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/EarlyHints_Test.java
@@ -25,8 +25,8 @@ public class EarlyHints_Test {
 	@Rest
 	public static class A {
 		@RestGet public EarlyHints a1() { return EARLY_HINTS; }
-		@RestGet public EarlyHints a2() { return earlyHints().body("foo"); }
-		@RestGet public EarlyHints a3() { return earlyHints().header("Foo","bar"); }
+		@RestGet public EarlyHints a2() { return earlyHints().body("foo").build(); }
+		@RestGet public EarlyHints a3() { return earlyHints().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Found_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Found_Test.java
index 099c9f2..b28253f 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Found_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Found_Test.java
@@ -25,9 +25,9 @@ public class Found_Test {
 	@Rest
 	public static class A {
 		@RestGet public Found a1() { return FOUND; }
-		@RestGet public Found a2() { return found("servlet:/foo").body("foo"); }
-		@RestGet public Found a3() { return found("servlet:/foo"); }
-		@RestGet public Found a4() { return found("servlet:/foo").header("Foo","bar"); }
+		@RestGet public Found a2() { return found("servlet:/foo").body("foo").build(); }
+		@RestGet public Found a3() { return found("servlet:/foo").build(); }
+		@RestGet public Found a4() { return found("servlet:/foo").header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/IMUsed_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/IMUsed_Test.java
index ac21ab0..089ac70 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/IMUsed_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/IMUsed_Test.java
@@ -25,8 +25,8 @@ public class IMUsed_Test {
 	@Rest
 	public static class A {
 		@RestGet public IMUsed a1() { return IM_USED; }
-		@RestGet public IMUsed a2() { return imUsed().body("foo"); }
-		@RestGet public IMUsed a3() { return imUsed().header("Foo","bar"); }
+		@RestGet public IMUsed a2() { return imUsed().body("foo").build(); }
+		@RestGet public IMUsed a3() { return imUsed().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/MovedPermanently_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/MovedPermanently_Test.java
index c8868a7..e1426c8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/MovedPermanently_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/MovedPermanently_Test.java
@@ -25,9 +25,9 @@ public class MovedPermanently_Test {
 	@Rest
 	public static class A {
 		@RestGet public MovedPermanently a1() { return MOVED_PERMANENTLY; }
-		@RestGet public MovedPermanently a2() { return movedPermanently("servlet:/foo").body("foo"); }
-		@RestGet public MovedPermanently a3() { return movedPermanently("servlet:/foo").location("servlet:/foo"); }
-		@RestGet public MovedPermanently a4() { return movedPermanently("servlet:/foo").header("Foo","bar"); }
+		@RestGet public MovedPermanently a2() { return movedPermanently("servlet:/foo").body("foo").build(); }
+		@RestGet public MovedPermanently a3() { return movedPermanently("servlet:/foo").location("servlet:/foo").build(); }
+		@RestGet public MovedPermanently a4() { return movedPermanently("servlet:/foo").header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/MultiStatus_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/MultiStatus_Test.java
index 5dd2c7b..721c187 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/MultiStatus_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/MultiStatus_Test.java
@@ -25,8 +25,8 @@ public class MultiStatus_Test {
 	@Rest
 	public static class A {
 		@RestGet public MultiStatus a1() { return MULTI_STATUS; }
-		@RestGet public MultiStatus a2() { return multiStatus().body("foo"); }
-		@RestGet public MultiStatus a3() { return multiStatus().header("Foo","bar"); }
+		@RestGet public MultiStatus a2() { return multiStatus().body("foo").build(); }
+		@RestGet public MultiStatus a3() { return multiStatus().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/MultipleChoices_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/MultipleChoices_Test.java
index 2a1e3e1..4d1179d 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/MultipleChoices_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/MultipleChoices_Test.java
@@ -25,8 +25,8 @@ public class MultipleChoices_Test {
 	@Rest
 	public static class A {
 		@RestGet public MultipleChoices a1() { return MULTIPLE_CHOICES; }
-		@RestGet public MultipleChoices a2() { return multipleChoices().body("foo"); }
-		@RestGet public MultipleChoices a3() { return multipleChoices().header("Foo","bar"); }
+		@RestGet public MultipleChoices a2() { return multipleChoices().body("foo").build(); }
+		@RestGet public MultipleChoices a3() { return multipleChoices().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/NoContent_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/NoContent_Test.java
index ec1d58e..42ae571 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/NoContent_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/NoContent_Test.java
@@ -25,8 +25,8 @@ public class NoContent_Test {
 	@Rest
 	public static class A {
 		@RestGet public NoContent a1() { return NO_CONTENT; }
-		@RestGet public NoContent a2() { return noContent().body("foo"); }
-		@RestGet public NoContent a3() { return noContent().header("Foo","bar"); }
+		@RestGet public NoContent a2() { return noContent().body("foo").build(); }
+		@RestGet public NoContent a3() { return noContent().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/NonAuthoritativeInformation_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/NonAuthoritativeInformation_Test.java
index 0f692c1..a38a718 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/NonAuthoritativeInformation_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/NonAuthoritativeInformation_Test.java
@@ -25,8 +25,8 @@ public class NonAuthoritativeInformation_Test {
 	@Rest
 	public static class A {
 		@RestGet public NonAuthoritiveInformation a1() { return NON_AUTHORATIVE_INFORMATION; }
-		@RestGet public NonAuthoritiveInformation a2() { return nonAuthoritiveInformation().body("foo"); }
-		@RestGet public NonAuthoritiveInformation a3() { return nonAuthoritiveInformation().header("Foo","bar"); }
+		@RestGet public NonAuthoritiveInformation a2() { return nonAuthoritiveInformation().body("foo").build(); }
+		@RestGet public NonAuthoritiveInformation a3() { return nonAuthoritiveInformation().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/NotModified_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/NotModified_Test.java
index 5f79301..14d0cb7 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/NotModified_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/NotModified_Test.java
@@ -25,8 +25,8 @@ public class NotModified_Test {
 	@Rest
 	public static class A {
 		@RestGet public NotModified a1() { return NOT_MODIFIED; }
-		@RestGet public NotModified a2() { return notModified().body("foo"); }
-		@RestGet public NotModified a3() { return notModified().header("Foo","bar"); }
+		@RestGet public NotModified a2() { return notModified().body("foo").build(); }
+		@RestGet public NotModified a3() { return notModified().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Ok_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Ok_Test.java
index 892cf96..189ebbd 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Ok_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Ok_Test.java
@@ -25,8 +25,8 @@ public class Ok_Test {
 	@Rest
 	public static class A {
 		@RestGet public Ok a1() { return OK; }
-		@RestGet public Ok a2() { return ok().body("foo"); }
-		@RestGet public Ok a3() { return ok().header("Foo","bar"); }
+		@RestGet public Ok a2() { return ok().body("foo").build(); }
+		@RestGet public Ok a3() { return ok().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/PartialContent_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/PartialContent_Test.java
index 69ac016..156c509 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/PartialContent_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/PartialContent_Test.java
@@ -25,8 +25,8 @@ public class PartialContent_Test {
 	@Rest
 	public static class A {
 		@RestGet public PartialContent a1() { return PARTIAL_CONTENT; }
-		@RestGet public PartialContent a2() { return partialContent().body("foo"); }
-		@RestGet public PartialContent a3() { return partialContent().header("Foo","bar"); }
+		@RestGet public PartialContent a2() { return partialContent().body("foo").build(); }
+		@RestGet public PartialContent a3() { return partialContent().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/PermanentRedirect_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/PermanentRedirect_Test.java
index 9d484ea..b3b9cf8 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/PermanentRedirect_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/PermanentRedirect_Test.java
@@ -25,9 +25,9 @@ public class PermanentRedirect_Test {
 	@Rest
 	public static class A {
 		@RestGet public PermanentRedirect a1() { return PERMANENT_REDIRECT; }
-		@RestGet public PermanentRedirect a2() { return permanentRedirect("servlet:/foo").body("foo"); }
-		@RestGet public PermanentRedirect a3() { return permanentRedirect("servlet:/foo"); }
-		@RestGet public PermanentRedirect a4() { return permanentRedirect("servlet:/foo").header("Foo","bar"); }
+		@RestGet public PermanentRedirect a2() { return permanentRedirect("servlet:/foo").body("foo").build(); }
+		@RestGet public PermanentRedirect a3() { return permanentRedirect("servlet:/foo").build(); }
+		@RestGet public PermanentRedirect a4() { return permanentRedirect("servlet:/foo").header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/Processing_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/Processing_Test.java
index e7bc533..d11015c 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/Processing_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/Processing_Test.java
@@ -25,8 +25,8 @@ public class Processing_Test {
 	@Rest
 	public static class A {
 		@RestGet public Processing a1() { return PROCESSING; }
-		@RestGet public Processing a2() { return processing().body("foo"); }
-		@RestGet public Processing a3() { return processing().header("Foo","bar"); }
+		@RestGet public Processing a2() { return processing().body("foo").build(); }
+		@RestGet public Processing a3() { return processing().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/ResetContent_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/ResetContent_Test.java
index a8f2c96..d71dcb5 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/ResetContent_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/ResetContent_Test.java
@@ -25,8 +25,8 @@ public class ResetContent_Test {
 	@Rest
 	public static class A {
 		@RestGet public ResetContent a1() { return RESET_CONTENT; }
-		@RestGet public ResetContent a2() { return resetContent().body("foo"); }
-		@RestGet public ResetContent a3() { return resetContent().header("Foo","bar"); }
+		@RestGet public ResetContent a2() { return resetContent().body("foo").build(); }
+		@RestGet public ResetContent a3() { return resetContent().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/SeeOther_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/SeeOther_Test.java
index db22305..0fd3bc2 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/SeeOther_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/SeeOther_Test.java
@@ -25,9 +25,9 @@ public class SeeOther_Test {
 	@Rest
 	public static class A {
 		@RestGet public SeeOther a1() { return SEE_OTHER; }
-		@RestGet public SeeOther a2() { return seeOther("servlet:/foo").body("foo"); }
-		@RestGet public SeeOther a3() { return seeOther("servlet:/foo"); }
-		@RestGet public SeeOther a4() { return seeOther("servlet:/foo").header("Foo","bar"); }
+		@RestGet public SeeOther a2() { return seeOther("servlet:/foo").body("foo").build(); }
+		@RestGet public SeeOther a3() { return seeOther("servlet:/foo").build(); }
+		@RestGet public SeeOther a4() { return seeOther("servlet:/foo").header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/SwitchingProtocols_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/SwitchingProtocols_Test.java
index d5e8d61..a32f924 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/SwitchingProtocols_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/SwitchingProtocols_Test.java
@@ -25,8 +25,8 @@ public class SwitchingProtocols_Test {
 	@Rest
 	public static class A {
 		@RestGet public SwitchingProtocols a1() { return SWITCHING_PROTOCOLS; }
-		@RestGet public SwitchingProtocols a2() { return switchingProtocols().body("foo"); }
-		@RestGet public SwitchingProtocols a3() { return switchingProtocols().header("Foo","bar"); }
+		@RestGet public SwitchingProtocols a2() { return switchingProtocols().body("foo").build(); }
+		@RestGet public SwitchingProtocols a3() { return switchingProtocols().header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/TemporaryRedirect_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/TemporaryRedirect_Test.java
index 1abbc95..79678f3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/TemporaryRedirect_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/TemporaryRedirect_Test.java
@@ -25,9 +25,9 @@ public class TemporaryRedirect_Test {
 	@Rest
 	public static class A {
 		@RestGet public TemporaryRedirect a1() { return TEMPORARY_REDIRECT; }
-		@RestGet public TemporaryRedirect a2() { return temporaryRedirect("servlet:/foo").body("foo"); }
-		@RestGet public TemporaryRedirect a3() { return temporaryRedirect("servlet:/foo"); }
-		@RestGet public TemporaryRedirect a4() { return temporaryRedirect("servlet:/foo").header("Foo","bar"); }
+		@RestGet public TemporaryRedirect a2() { return temporaryRedirect("servlet:/foo").body("foo").build(); }
+		@RestGet public TemporaryRedirect a3() { return temporaryRedirect("servlet:/foo").build(); }
+		@RestGet public TemporaryRedirect a4() { return temporaryRedirect("servlet:/foo").header("Foo","bar").build(); }
 	}
 
 	@Test
diff --git a/juneau-utest/src/test/java/org/apache/juneau/http/response/UseProxy_Test.java b/juneau-utest/src/test/java/org/apache/juneau/http/response/UseProxy_Test.java
index b997674..cd9b8d3 100644
--- a/juneau-utest/src/test/java/org/apache/juneau/http/response/UseProxy_Test.java
+++ b/juneau-utest/src/test/java/org/apache/juneau/http/response/UseProxy_Test.java
@@ -25,8 +25,8 @@ public class UseProxy_Test {
 	@Rest
 	public static class A {
 		@RestGet public UseProxy a1() { return USE_PROXY; }
-		@RestGet public UseProxy a2() { return useProxy().body("foo"); }
-		@RestGet public UseProxy a3() { return useProxy().header("Foo","bar"); }
+		@RestGet public UseProxy a2() { return useProxy().body("foo").build(); }
+		@RestGet public UseProxy a3() { return useProxy().header("Foo","bar").build(); }
 	}
 
 	@Test