diff --git a/jaxrs-tck/pom.xml b/jaxrs-tck/pom.xml
index c7ee0a9..cb39cad 100644
--- a/jaxrs-tck/pom.xml
+++ b/jaxrs-tck/pom.xml
@@ -17,7 +17,8 @@
 
 -->
 
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>jakarta.ws.rs</groupId>
@@ -29,8 +30,9 @@
     <url>https://github.com/eclipse-ee4j/jaxrs-api</url>
 
     <properties>
-        <maven.compiler.source>1.8</maven.compiler.source>
-        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <junit.jupiter.version>[5.7.2, 5.8-A00)</junit.jupiter.version>
     </properties>
 
     <organization>
@@ -78,6 +80,20 @@
         <tag>HEAD</tag>
     </scm>
 
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.3.2</version>
+            </plugin>
+            <plugin>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>3.0.0-M5</version>
+            </plugin>
+
+        </plugins>
+    </build>
+
     <dependencies>
         <dependency>
             <groupId>jakarta.ws.rs</groupId>
@@ -87,8 +103,21 @@
 
         <dependency>
             <groupId>org.junit.jupiter</groupId>
-            <artifactId>junit-jupiter-api</artifactId>
-            <version>[5.5.2, 5.6-A00)</version>
+            <artifactId>junit-jupiter</artifactId>
+            <version>${junit.jupiter.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.junit.platform</groupId>
+            <artifactId>junit-platform-launcher</artifactId>
+            <version>1.7.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+            <version>3.1</version>
         </dependency>
 
         <dependency>
@@ -96,5 +125,18 @@
             <artifactId>hamcrest-library</artifactId>
             <version>[2.2, 2.3-A00)</version>
         </dependency>
+
+        <dependency>
+            <groupId>org.jboss.arquillian.junit5</groupId>
+            <artifactId>arquillian-junit5-container</artifactId>
+            <version>1.7.0.Alpha10</version>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.annotation</groupId>
+            <artifactId>jakarta.annotation-api</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+
     </dependencies>
 </project>
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder/BuilderClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder/BuilderClientIT.java
new file mode 100644
index 0000000..caf9d47
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responsebuilder/BuilderClientIT.java
@@ -0,0 +1,437 @@
+/*
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.responsebuilder;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.text.DateFormat;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.TreeSet;
+
+import jakarta.ws.rs.tck.api.rs.core.responseclient.VerificationResult;
+import jakarta.ws.rs.tck.common.impl.SinglevaluedMap;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.Invocation.Builder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+public class BuilderClientIT
+    extends jakarta.ws.rs.tck.api.rs.core.responseclient.JAXRSClientIT {
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+  
+  /*
+   * @testName: statusTest1
+   *
+   * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:153; JAXRS:JAVADOC:141;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:125; JAXRS:JAVADOC:124;
+   *
+   * @test_Strategy: Create an instance of ResponseBuilder Response.ok();
+   * Setting status using ResponseBuilder.status(int); verify that correct
+   * status code is returned
+   */
+  @Test
+  public void statusTest1() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+    ResponseBuilder respb = null;
+    for (int status : status_codes) {
+      respb = Response.ok();
+      respb = respb.status(status);
+      resp = respb.build();
+      result.append(verifyStatus(resp, status));
+    }
+    logMsg(result);
+    assertTrue(result.pass);
+  }
+
+  /*
+   * @testName: statusTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:154; JAXRS:JAVADOC:141;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of ResponseBuilder Response.ok();
+   * Setting status using ResponseBuilder.status(Status); verify that correct
+   * status code is returned
+   */
+  @Test
+  public void statusTest2() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+    ResponseBuilder respb = null;
+    for (int i = 0; i < status_codes.length - 1; i++) {
+      respb = Response.ok();
+      respb = respb.status(resp_status[i]);
+      resp = respb.build();
+      result.append(verifyStatus(resp, status_codes[i]));
+    }
+    logMsg(result);
+    assertTrue(result.pass);
+  }
+
+  /*
+   * @testName: expiresTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:147;
+   * 
+   * @test_Strategy: Set Expires to ResponseBuilder, build a response and check
+   * expires timestamp.
+   */
+  @Test
+  public void expiresTest() throws Fault {
+    Date now = Calendar.getInstance().getTime();
+    ResponseBuilder rs = Response.ok();
+    rs.expires(now);
+    Response response = rs.build();
+    MultivaluedMap<String, Object> metadata = response.getMetadata();
+    if (metadata == null)
+      fail("No metadata in response");
+    List<Object> expires = response.getMetadata().get("Expires");
+    if (expires == null || expires.isEmpty())
+      fail("No Expires property in metadata");
+    boolean condition = false;
+    Object fetched = expires.iterator().next();
+    if (Date.class.isInstance(fetched))
+      condition = ((Date) fetched).compareTo(now) == 0;
+    else if (String.class.isInstance(fetched))
+      condition = formats(now).contains(fetched.toString());
+    else
+      fail("Fetched object not recognised");
+
+    assertTrue(condition, "Expires value not matched, set: " + now.toString()+
+        "fetched:"+ fetched.toString());
+    logMsg("Set and fetched expire dates matched");
+  }
+
+  /*
+   * @testName: allowStringArrayTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:875;
+   * 
+   * @test_Strategy: Set the list of allowed methods for the resource.
+   */
+  @Test
+  public void allowStringArrayTest() throws Fault {
+    String[] methods = { Request.OPTIONS.name(), Request.TRACE.name() };
+    ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+    Response response = rb.allow(methods).build();
+    Set<String> set = response.getAllowedMethods();
+    String responseMethods = JaxrsUtil.iterableToString(" ", set);
+
+    for (String method : methods) {
+      assertContains(responseMethods, method, "Expected allow method", method,
+          "was not found in response allowed methods", responseMethods);
+      logMsg("Found expected allowed method", method);
+    }
+  }
+
+  /*
+   * @testName: allowStringArrayTruncateDuplicatesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:875;
+   * 
+   * @test_Strategy: Set the list of allowed methods for the resource.
+   */
+  @Test
+  public void allowStringArrayTruncateDuplicatesTest() throws Fault {
+    String[] methods = { Request.OPTIONS.name(), Request.OPTIONS.name() };
+    ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+    Response response = rb.allow(methods).build();
+    Set<String> set = response.getAllowedMethods();
+    assertEqualsInt(1, set.size(), "Only one allow method should be present");
+    assertEquals(set.iterator().next(), Request.OPTIONS.name(),
+        Request.OPTIONS.name(), "has not been found in allowed methods");
+    logMsg(Request.OPTIONS.name(), "has been found in allowed methods");
+  }
+
+  /*
+   * @testName: allowStringArrayNullRemovesAllTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:875;
+   * 
+   * @test_Strategy: if null any existing allowed method list will be removed.
+   */
+  @Test
+  public void allowStringArrayNullRemovesAllTest() throws Fault {
+    String[] methods = { Request.OPTIONS.name(), Request.GET.name() };
+    ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+    Response response = rb.allow(methods).allow((String[]) null).build();
+    Set<String> set = response.getAllowedMethods();
+    assertEqualsInt(0, set.size(), "No one allow method should be present");
+    logMsg("Allowed methods has been removed by null value as expected");
+  }
+
+  /*
+   * @testName: allowStringSetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:876;
+   * 
+   * @test_Strategy: Set the list of allowed methods for the resource.
+   */
+  @Test
+  public void allowStringSetTest() throws Fault {
+    Set<String> methods = new TreeSet<String>();
+    methods.add(Request.OPTIONS.name());
+    methods.add(Request.TRACE.name());
+
+    ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+    Response response = rb.allow(methods).build();
+    Set<String> set = response.getAllowedMethods();
+    String responseMethods = JaxrsUtil.iterableToString(" ", set);
+
+    for (String method : methods) {
+      assertContains(responseMethods, method, "Expected allow method", method,
+          "was not found in response allowed methods", responseMethods);
+      logMsg("Found expected allowed method", method);
+    }
+  }
+
+  /*
+   * @testName: allowStringSetNullRemovesAllTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:876;
+   * 
+   * @test_Strategy: if null any existing allowed method list will be removed.
+   */
+  @Test
+  public void allowStringSetNullRemovesAllTest() throws Fault {
+    Set<String> methods = new TreeSet<String>();
+    methods.add(Request.OPTIONS.name());
+    methods.add(Request.TRACE.name());
+
+    ResponseBuilder rb = RuntimeDelegate.getInstance().createResponseBuilder();
+    Response response = rb.allow(methods).allow((Set<String>) null).build();
+    Set<String> set = response.getAllowedMethods();
+    assertEqualsInt(0, set.size(), "No one allow method should be present");
+    logMsg("Allowed methods has been removed by null value as expected");
+  }
+
+  /*
+   * @testName: encodingTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:878;
+   * 
+   * @test_Strategy: Set the message entity content encoding.
+   */
+  @Test
+  public void encodingTest() throws Fault {
+    String[] encodings = { "gzip", "ccitt", "pic" };
+    VerificationResult vr = new VerificationResult();
+    for (String encoding : encodings) {
+      Response response = Response.ok().encoding(encoding).build();
+      vr.append(verifyEncoding(response, Collections.singletonList(encoding)));
+    }
+    logMsg(vr.message);
+    assertTrue(vr.pass);
+    logMsg("Found expected encodings");
+  }
+
+  /*
+   * @testName: linkUriStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:880;
+   * 
+   * @test_Strategy: Add a link header.
+   */
+  @Test
+  public void linkUriStringTest() throws Fault {
+    URI uri = null;
+    try {
+      uri = new URI(URL);
+    } catch (URISyntaxException e) {
+      fail(e.getMessage());
+    }
+    String rel = "REL";
+    Response response = Response.ok().link(uri, rel).build();
+    Link link = response.getLink(rel);
+    assertTrue(link != null, "link is null");
+    assertTrue(link.toString().contains(URL), "link"+ link+
+        "does not contain expected"+ URL);
+    logMsg("Found expected link", link);
+  }
+
+  /*
+   * @testName: linkStringStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:881;
+   * 
+   * @test_Strategy: Add a link header.
+   */
+  @Test
+  public void linkStringStringTest() throws Fault {
+    String rel = "REL";
+    Response response = Response.ok().link(URL, rel).build();
+    Link link = response.getLink(rel);
+    assertTrue(link != null, "link is null");
+    assertTrue(link.toString().contains(URL), "link"+ link+
+        "does not contain expected"+ URL);
+    logMsg("Found expected link", link);
+  }
+
+  /*
+   * @testName: linksTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:882;
+   * 
+   * @test_Strategy: Add one or more link headers.
+   */
+  @Test
+  public void linksTest() throws Fault {
+    String rel = "REL";
+    Link link1 = Link.fromUri(URL).rel(rel + "1").build();
+    Link link11 = Link.fromUri(URL).rel(rel + "11").build();
+    Link link2 = Link.fromUri(URL + "/link2").rel(rel + "2").build();
+
+    Response response = Response.ok().links(link1, link11, link2).build();
+    Link link = response.getLink(rel + "1");
+    assertTrue(link != null, "link is null");
+    assertTrue(link.toString().contains(URL), "link"+ link+
+        "does not contain expected"+ URL);
+    link = response.getLink(rel + "11");
+    assertTrue(link != null, "link is null");
+    assertTrue(link.toString().contains(URL), "link"+ link+
+        "does not contain expected"+ URL);
+    link = response.getLink(rel + "2");
+    assertTrue(link != null, "link is null");
+    assertTrue(link.toString().contains(URL + "/link2"), "link"+ link+
+        "does not contain expected"+ URL + "/link2");
+
+    logMsg("Found expected links");
+  }
+
+  /*
+   * @testName: replaceAllTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:883;
+   * 
+   * @test_Strategy: Replaces all existing headers with the newly supplied
+   * headers.
+   */
+  @Test
+  public void replaceAllTest() throws Fault {
+    String[] headers = { "header1", "header2", "header3" };
+    String header99 = "header99";
+    MultivaluedMap<String, Object> mv = new SinglevaluedMap<String, Object>();
+    mv.add(header99, header99);
+    Response response = Response.ok().header(headers[0], headers[0])
+        .header(headers[1], headers[1]).header(headers[2], headers[2])
+        .replaceAll(mv).build();
+    for (String header : headers)
+      assertTrue(response.getHeaderString(header) == null,
+          "response contains non replaced header" + header);
+
+    assertTrue(response.getHeaderString(header99).equals(header99),
+        "response does not contain header from replacedAll map"+ header99);
+  }
+
+  /*
+   * @testName: replaceAllByNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:883;
+   * 
+   * @test_Strategy: Replaces all existing headers with the newly supplied
+   * headers. if null all existing headers will be removed.
+   */
+  @Test
+  public void replaceAllByNullTest() throws Fault {
+    String[] headers = { "header1", "header2", "header3" };
+    Response response = Response.ok().header(headers[0], headers[0])
+        .header(headers[1], headers[1]).header(headers[2], headers[2])
+        .replaceAll(null).build();
+    for (String header : headers)
+      assertTrue(response.getHeaderString(header) == null,
+          "response contains non replaced header"+ header);
+  }
+
+  /*
+   * @testName: variantsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:884;
+   * 
+   * @test_Strategy: Add a Vary header that lists the available variants.
+   */
+  @Test
+  public void variantsTest() throws Fault {
+    List<String> encoding = Arrays.asList("gzip", "compress");
+    List<String> vars = Arrays.asList(HttpHeaders.ACCEPT_LANGUAGE,
+        HttpHeaders.ACCEPT_ENCODING);
+    MediaType mt = MediaType.APPLICATION_JSON_TYPE;
+    ResponseBuilder rb = Response.ok();
+    rb = rb.variants(getVariantList(encoding, mt).toArray(new Variant[0]));
+    Response response = rb.build();
+    VerificationResult result = new VerificationResult();
+    result.append(verifyVary(response, vars));
+    logMsg(result.message);
+    assertTrue(result.pass);
+  }
+
+  // //////////////////////////////////////////////////////////////////
+
+  private static String formats(Date date) {
+    DateFormat format;
+    TestUtil.logMsg("Creating possible string format list");
+    StringBuilder sb = new StringBuilder();
+    for (String tz : TimeZone.getAvailableIDs()) {
+      format = JaxrsUtil.createDateFormat(TimeZone.getTimeZone(tz));
+      sb.append(format.format(date));
+    }
+    return sb.toString();
+  }
+
+  protected Invocation.Builder invocation() {
+    Client client = ClientBuilder.newClient();
+    WebTarget target = client.target(URL);
+    Builder b = target.request();
+    return b;
+  }
+
+  static final String URL = "http://localhost:888/noUrl";
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java
new file mode 100644
index 0000000..00ebe0b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/JAXRSClientIT.java
@@ -0,0 +1,2565 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.responseclient;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.Link.Builder;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Response.StatusType;
+import jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = -2343034378084516380L;
+
+  // name it to ensure sorting
+  protected final Response.Status[] resp_status = { Response.Status.OK,
+      Response.Status.CREATED, Response.Status.ACCEPTED,
+      Response.Status.NO_CONTENT, Response.Status.RESET_CONTENT,
+      Response.Status.PARTIAL_CONTENT, Response.Status.MOVED_PERMANENTLY,
+      Response.Status.FOUND, Response.Status.SEE_OTHER,
+      Response.Status.NOT_MODIFIED, Response.Status.USE_PROXY,
+      Response.Status.TEMPORARY_REDIRECT, Response.Status.BAD_REQUEST,
+      Response.Status.UNAUTHORIZED, Response.Status.PAYMENT_REQUIRED,
+      Response.Status.FORBIDDEN, Response.Status.NOT_FOUND,
+      Response.Status.METHOD_NOT_ALLOWED, Response.Status.NOT_ACCEPTABLE,
+      Response.Status.PROXY_AUTHENTICATION_REQUIRED,
+      Response.Status.REQUEST_TIMEOUT, Response.Status.CONFLICT,
+      Response.Status.GONE, Response.Status.LENGTH_REQUIRED,
+      Response.Status.PRECONDITION_FAILED,
+      Response.Status.REQUEST_ENTITY_TOO_LARGE,
+      Response.Status.REQUEST_URI_TOO_LONG,
+      Response.Status.UNSUPPORTED_MEDIA_TYPE,
+      Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE,
+      Response.Status.EXPECTATION_FAILED, Response.Status.PRECONDITION_REQUIRED,
+      Response.Status.TOO_MANY_REQUESTS,
+      Response.Status.REQUEST_HEADER_FIELDS_TOO_LARGE,
+      Response.Status.INTERNAL_SERVER_ERROR, Response.Status.NOT_IMPLEMENTED,
+      Response.Status.BAD_GATEWAY, Response.Status.SERVICE_UNAVAILABLE,
+      Response.Status.GATEWAY_TIMEOUT,
+      Response.Status.HTTP_VERSION_NOT_SUPPORTED,
+      Response.Status.NETWORK_AUTHENTICATION_REQUIRED };
+
+  // name it to ensure sorting
+  protected final int[] status_codes = { 200, 201, 202, 204, 205, 206, 301, 302,
+      303, 304, 305, 307, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410,
+      411, 412, 413, 414, 415, 416, 417, 428, 429, 431, 500, 501, 502, 503, 504,
+      505, 511 };
+
+  // name it to ensure sorting
+  protected final Response.Status.Family[] status_family = {
+      Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+      Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+      Response.Status.Family.SUCCESSFUL, Response.Status.Family.SUCCESSFUL,
+      Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+      Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+      Response.Status.Family.REDIRECTION, Response.Status.Family.REDIRECTION,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.CLIENT_ERROR,
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.SERVER_ERROR,
+      Response.Status.Family.SERVER_ERROR, Response.Status.Family.SERVER_ERROR,
+      Response.Status.Family.SERVER_ERROR, Response.Status.Family.SERVER_ERROR,
+      Response.Status.Family.SERVER_ERROR,
+      Response.Status.Family.SERVER_ERROR };
+
+  protected final Response.Status.Family[] status_family_list = {
+      Response.Status.Family.CLIENT_ERROR, Response.Status.Family.INFORMATIONAL,
+      Response.Status.Family.OTHER, Response.Status.Family.REDIRECTION,
+      Response.Status.Family.SERVER_ERROR, Response.Status.Family.SUCCESSFUL };
+
+  protected final String[] status = { "OK", "Created", "Accepted", "No Content",
+      "Reset Content", "Partial Content", "Moved Permanently", "Found",
+      "See Other", "Not Modified", "Use Proxy", "Temporary Redirect",
+      "Bad Request", "Unauthorized", "Payment Required", "Forbidden",
+      "Not Found", "Method Not Allowed", "Not Acceptable",
+      "Proxy Authentication Required", "Request Timeout", "Conflict", "Gone",
+      "Length Required", "Precondition Failed", "Request Entity Too Large",
+      "Request-URI Too Long", "Unsupported Media Type",
+      "Requested Range Not Satisfiable", "Expectation Failed",
+      "Precondition Required", "Too Many Requests",
+      "Request Header Fields Too Large", "Internal Server Error",
+      "Not Implemented", "Bad Gateway", "Service Unavailable",
+      "Gateway Timeout", "HTTP Version Not Supported",
+      "Network Authentication Required" };
+
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /*
+   * @class.setup_props: webServerHost; webServerPort; 
+   */
+  /* Run test */
+
+  /*
+   * @testName: okTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:131; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using Response.ok().build()
+   * verify that correct status code is returned
+   */
+  @Test
+  public void okTest1() throws Fault {
+    VerificationResult result;
+    Response response = null;
+    int status = 200;
+    response = Response.ok().build();
+    result = verifyStatus(response, status);
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: okTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:132; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ok(String).build() verify that correct status code is returned
+   */
+  @Test
+  public void okTest2() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 200;
+    String content = "Test only";
+    resp = Response.ok(content).build();
+    result = verifyContent(resp, content);
+    result.append(verifyStatus(resp, status));
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: okTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:134; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using Response.ok(String,
+   * String).build() verify that correct status code is returned
+   */
+  @Test
+  public void okTest3() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 200;
+    String content = "Test only";
+    String type = MediaType.TEXT_PLAIN;
+    resp = Response.ok(content, type).build();
+    result = verifyContent(resp, content);
+    result.append(verifyStatus(resp, status));
+    result.append(verifyContentType(resp, Collections.singletonList(type)));
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: okTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:133; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using Response.ok(String,
+   * MediaType).build() verify that correct status code is returned
+   */
+  @Test
+  public void okTest4() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 200;
+    String content = "Test only";
+    String type = MediaType.TEXT_PLAIN;
+    MediaType mt = new MediaType(MediaType.TEXT_PLAIN_TYPE.getType(),
+        MediaType.TEXT_PLAIN_TYPE.getSubtype());
+    resp = Response.ok(content, mt).build();
+    result = verifyContent(resp, content);
+    result.append(verifyStatus(resp, status));
+    result.append(verifyContentType(resp, Collections.singletonList(type)));
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: okTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:135; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:91; JAXRS:JAVADOC:268;
+   * JAXRS:JAVADOC:267; JAXRS:JAVADOC:266; JAXRS:JAVADOC:265; JAXRS:JAVADOC:263;
+   * JAXRS:JAVADOC:264;
+   * 
+   * @test_Strategy: Create an instance of Response using Response.ok(String,
+   * Variant).build() verify that correct status code is returned
+   */
+  @Test
+  public void okTest5() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+    int status = 200;
+    String content = "Test Only";
+    List<String> encoding = Arrays.asList("gzip", "compress");
+
+    MediaType mt = new MediaType("text", "plain");
+    List<Variant> vts = getVariantList(encoding, mt);
+
+    for (int i = 0; i < vts.size(); i++) {
+      Variant vt = vts.get(i);
+      resp = Response.ok(content, vt).build();
+      result.append(verifyContent(resp, content));
+      result.append(verifyStatus(resp, status));
+      result.append(verifyEncoding(resp, encoding));
+      result.append(verifyLanguage(resp, getLangList()));
+      result.append(
+          verifyContentType(resp, Collections.singletonList(mt.toString())));
+    }
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: noContentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:126; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.noContent().build() verify that correct status code is returned
+   */
+  @Test
+  public void noContentTest() throws Fault {
+    VerificationResult result;
+
+    Response resp = null;
+    int status = 204;
+
+    resp = Response.noContent().build();
+    result = verifyStatus(resp, status);
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: notAcceptableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:127; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:91; JAXRS:JAVADOC:268;
+   * JAXRS:JAVADOC:267; JAXRS:JAVADOC:266; JAXRS:JAVADOC:265; JAXRS:JAVADOC:263;
+   * JAXRS:JAVADOC:264;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.notAcceptable(vts).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void notAcceptableTest() throws Fault {
+    VerificationResult result;
+
+    Response resp = null;
+    int status = 406;
+
+    List<String> encoding = Arrays.asList("gzip", "compress");
+
+    MediaType mt = new MediaType("text", "plain");
+    List<Variant> vts = getVariantList(encoding, mt);
+
+    resp = Response.notAcceptable(vts).build();
+    result = verifyStatus(resp, status);
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: notModifiedTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:128; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.notModified().build() verify that correct status code is returned
+   */
+  @Test
+  public void notModifiedTest1() throws Fault {
+    VerificationResult result;
+
+    Response resp = null;
+    int status = 304;
+    resp = Response.notModified().build();
+
+    result = verifyStatus(resp, status);
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: notModifiedTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:130; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.notModified(String).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void notModifiedTest2() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 304;
+    String tags = "TestOnly";
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("ETAG", tags);
+
+    resp = Response.notModified(tags).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: notModifiedTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:129; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.notModified(EntityTag).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void notModifiedTest3() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 304;
+    String value = "TestOnly";
+
+    EntityTag et = new EntityTag(value);
+
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("ETAG", value);
+
+    resp = Response.notModified(et).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:123; JAXRS:JAVADOC:124;
+   * JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(int).build() verify that correct status code is returned
+   */
+  @Test
+  public void statusTest1() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+
+    for (int status : status_codes) {
+      resp = Response.status(status).build();
+      result.append(verifyStatus(resp, status));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:138; JAXRS:JAVADOC:123; JAXRS:JAVADOC:124;
+   * JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(Response.Status).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void statusTest2() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+
+    for (int i = 0; i < status_codes.length; i++) {
+      resp = Response.status(resp_status[i]).build();
+      result.append(verifyStatus(resp, status_codes[i]));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:131; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.status(int).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void statusTest3() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+
+    for (int status : status_codes) {
+      resp = Response.ok().status(status).build();
+      result.append(verifyStatus(resp, status));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:138; JAXRS:JAVADOC:131; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:SPEC:14.2;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.status(Response.Status).build() verify that
+   * correct status code is returned
+   */
+  @Test
+  public void statusTest4() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+
+    for (int i = 0; i < status_codes.length; i++) {
+      resp = Response.ok().status(resp_status[i]).build();
+      result.append(verifyStatus(resp, status_codes[i]));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: createdTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:121; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.created(URI).build() verify that correct status code is returned
+   */
+  @Test
+  public void createdTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+        "news:comp.lang.java", "urn:isbn:096139210x",
+        "http://java.sun.com/j2se/1.3/",
+        "docs/guide/collections/designfaq.html#28",
+        "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+    URI test_uri = null;
+    for (String uri_string : uri_expected) {
+      try {
+        test_uri = new URI(uri_string);
+      } catch (URISyntaxException ex) {
+        result.message.append("Unexpected exception thrown:")
+            .append(ex.getMessage());
+        result.pass = false;
+      }
+      Response resp = Response.created(test_uri).build();
+
+      HashMap<String, String> expected_map = new HashMap<String, String>();
+      expected_map.put("Location", uri_string);
+      result.append(verifyStatus(resp, 201));
+      result.append(verifyHeaders(resp, expected_map));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: serverErrorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:137; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.serverError().build() verify that correct status code is returned
+   */
+  @Test
+  public void serverErrorTest() throws Fault {
+    VerificationResult result;
+
+    Response resp = Response.serverError().build();
+    result = verifyStatus(resp, 500);
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: seeOtherTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:136; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.seeOther(URI).build() verify that correct status code is returned
+   */
+  @Test
+  public void seeOtherTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    URI test_uri = null;
+    try {
+      test_uri = new URI("http://java.sun.com/j2se/1.3/");
+    } catch (URISyntaxException ex) {
+      result.message.append("Unexpected exception thrown:")
+          .append(ex.getMessage());
+      result.pass = false;
+    }
+    Response resp = Response.seeOther(test_uri).build();
+
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("Location", "http://java.sun.com/j2se/1.3/");
+    result.append(verifyStatus(resp, 303));
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: temporaryRedirectTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:140; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.temporaryRedirect(URI).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void temporaryRedirectTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    URI test_uri = null;
+    try {
+      test_uri = new URI("http://java.sun.com/j2se/1.3/");
+    } catch (URISyntaxException ex) {
+      result.message.append("Unexpected exception thrown:")
+          .append(ex.getMessage());
+      result.pass = false;
+    }
+    Response resp = Response.temporaryRedirect(test_uri).build();
+
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("Location", "http://java.sun.com/j2se/1.3/");
+    result.append(verifyStatus(resp, 307));
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: fromResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:122; JAXRS:JAVADOC:141; JAXRS:JAVADOC:123;
+   * JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.fromResponse(Response).build() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void fromResponseTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    int status = 200;
+    String content = "Test Only";
+    List<String> type = Arrays.asList("text/plain", "text/html");
+    List<String> encoding = Arrays.asList("gzip", "compress");
+
+    MediaType mt1 = new MediaType("text", "plain");
+    MediaType mt2 = new MediaType("text", "html");
+    List<Variant> vts = getVariantList(encoding, mt1, mt2);
+
+    for (int i = 0; i < vts.size(); i++) {
+      Variant vt = vts.get(i);
+      Response resp1 = Response.ok(content, vt).build();
+      Response resp = Response.fromResponse(resp1).build();
+      result.append(verifyContent(resp, content));
+      result.append(verifyStatus(resp, status));
+      result.append(verifyEncoding(resp, encoding));
+      result.append(verifyLanguage(resp, getLangList()));
+      result.append(verifyContentType(resp, type));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: entityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:146;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.entity(String).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void entityTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    int status = 200;
+    String content = "Test Only";
+
+    Response resp = Response.status(status).entity(content).build();
+    result.append(verifyContent(resp, content));
+    result.append(verifyStatus(resp, status));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: languageTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:149;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.language(String).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void languageTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+
+    int status = 200;
+    List<String> lang = getLangList();
+
+    for (String language : lang) {
+      Response resp = Response.status(status).language(language).build();
+      result.append(verifyStatus(resp, status));
+      result.append(verifyLanguage(resp, lang));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: languageTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:150;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.language(Locale).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void languageTest1() throws Fault {
+    VerificationResult result = new VerificationResult();
+    int status = 200;
+
+    for (String language : getLangList()) {
+      Response resp = Response.status(status).language(language).build();
+      result.append(verifyStatus(resp, status));
+      result.append(verifyLanguage(resp, Arrays.asList(language)));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: typeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:158;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.type(String).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void typeTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    int status = 200;
+    String type = MediaType.TEXT_PLAIN;
+
+    Response resp = Response.status(status).type(type).build();
+    result.append(verifyStatus(resp, status));
+    result.append(verifyContentType(resp, Arrays.asList(type)));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: typeTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:157;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.type(MediaType).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void typeTest1() throws Fault {
+    VerificationResult result;
+
+    int status = 200;
+    List<String> types = Arrays.asList("text/plain", "text/html");
+
+    MediaType mt1 = new MediaType("text", "plain");
+    MediaType mt2 = new MediaType("text", "html");
+
+    Response resp = Response.status(status).type(mt1).type(mt2).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyContentType(resp, types));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: tagTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:156;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.tag(String).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void tagTest1() throws Fault {
+    VerificationResult result;
+
+    int status = 200;
+    String tag = "TestOnly";
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("ETAG", tag);
+
+    Response resp = Response.status(status).tag(tag).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: tagTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:155;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.tag(EntityTag).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void tagTest2() throws Fault {
+    VerificationResult result;
+    int status = 200;
+    EntityTag et1 = new EntityTag("StrongEntityTagTest", true);
+    EntityTag et2 = new EntityTag("TestOnly", false);
+
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("ETAG", "TestOnly");
+
+    Response resp = Response.status(status).tag(et1).tag(et2).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: variantTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:159;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(int).variant(Variant).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void variantTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response resp = null;
+    int status = 200;
+    List<String> encoding = Arrays.asList("gzip", "compress");
+
+    MediaType mt = new MediaType("text", "plain");
+    List<Variant> vts = getVariantList(encoding, mt);
+
+    for (int i = 0; i < vts.size(); i++) {
+      Variant vt = vts.get(i);
+      resp = Response.status(status).variant(vt).build();
+      verifyStatus(resp, status);
+      verifyEncoding(resp, encoding);
+      verifyLanguage(resp, getLangList());
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: variantsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:160;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(int).variants(List<Variant>).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void variantsTest() throws Fault {
+    VerificationResult result;
+    Response resp = null;
+    int status = 200;
+    // String type = "text/plain";
+    List<String> encoding = Arrays.asList("gzip", "compress");
+    List<String> vars = Arrays.asList("accept-language", "accept-encoding");
+
+    MediaType mt = new MediaType("text", "plain");
+    List<Variant> vts = getVariantList(encoding, mt);
+    resp = Response.status(status).variants(vts).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyVary(resp, vars));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: locationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:152;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(status).location(URI).build() verify that correct status
+   * code is returned
+   */
+  @Test
+  public void locationTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    int status = 200;
+    List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+        "news:comp.lang.java", "urn:isbn:096139210x",
+        "http://java.sun.com/j2se/1.3/",
+        "docs/guide/collections/designfaq.html#28",
+        "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+    URI test_uri = null;
+    for (String uri_string : uri_expected) {
+      try {
+        test_uri = new URI(uri_string);
+      } catch (URISyntaxException ex) {
+        result.message.append("Unexpected exception thrown:")
+            .append(ex.getMessage());
+        result.pass = false;
+      }
+      Response resp = Response.status(status).location(test_uri).build();
+
+      HashMap<String, String> expected_map = new HashMap<String, String>();
+      expected_map.put("Location", uri_string);
+      result.append(verifyStatus(resp, status));
+      result.append(verifyHeaders(resp, expected_map));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: contentLocationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:144;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.status(status).contentLocation(URI).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void contentLocationTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    int status = 200;
+    List<String> uri_expected = Arrays.asList("mailto:java-net@java.sun.com",
+        "news:comp.lang.java", "urn:isbn:096139210x",
+        "http://java.sun.com/j2se/1.3/",
+        "docs/guide/collections/designfaq.html#28",
+        "../../../demo/jfc/SwingSet2/src/SwingSet2.java", "file:///~/calendar");
+
+    URI test_uri = null;
+    for (String uri_string : uri_expected) {
+      try {
+        test_uri = new URI(uri_string);
+      } catch (URISyntaxException ex) {
+        result.message.append("Unexpected exception thrown:")
+            .append(ex.getMessage());
+        result.pass = false;
+      }
+      Response resp = Response.status(status).contentLocation(test_uri).build();
+
+      HashMap<String, String> expected_map = new HashMap<String, String>();
+      expected_map.put("Content-Location", uri_string);
+      result.append(verifyStatus(resp, 200));
+      result.append(verifyHeaders(resp, expected_map));
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: cacheControlTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:142;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.cacheControl(String).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void cacheControlTest() throws Fault {
+    VerificationResult result;
+    int status = 200;
+    boolean nostore = true;
+
+    CacheControl ccl4 = new CacheControl();
+    ccl4.setNoStore(nostore);
+
+    List<String> ccl = Arrays.asList("no-store", "no-transform");
+
+    Response resp = Response.status(status).cacheControl(ccl4).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyCacheControl(resp, ccl));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: cookieTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:145;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.cookie(NewCookie).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void cookieTest() throws Fault {
+    VerificationResult result;
+    int status = 200;
+
+    String name = "name_1";
+    String value = "value_1";
+    // int maxage = jakarta.ws.rs.core.NewCookie.DEFAULT_MAX_AGE;
+
+    Cookie ck1 = new Cookie(name, value);
+    NewCookie nck1 = new NewCookie(ck1);
+
+    name = "name_2";
+    value = "value_2";
+    String path = "/acme";
+    String domain = "";
+
+    Cookie ck2 = new Cookie(name, value, path, domain);
+    NewCookie nck2 = new NewCookie(ck2);
+
+    name = "name_3";
+    value = "value_3";
+    path = "";
+    domain = "y.x.foo.com";
+
+    Cookie ck3 = new Cookie(name, value, path, domain);
+    NewCookie nck3 = new NewCookie(ck3);
+
+    List<String> cookies = Arrays.asList(nck1.toString().toLowerCase(),
+        nck2.toString().toLowerCase(), nck3.toString().toLowerCase());
+
+    Response resp = Response.status(status).cookie(nck1, nck2, nck3).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyCookies(resp, cookies));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: lastModifiedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:151;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.lastModified(Date).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void lastModifiedTest() throws Fault {
+    VerificationResult result;
+    int status = 200;
+    long dt = 123456789;
+    Date date = new Date(dt);
+    HashMap<String, String> expected_map = new HashMap<String, String>();
+    expected_map.put("Last-Modified", "123456789");
+
+    Response resp = Response.status(status).lastModified(date).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyHeaders(resp, expected_map));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: headerTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:148;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.header(String, Object).build() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void headerTest() throws Fault {
+    VerificationResult result;
+    int status = 200;
+    List<String> type = Arrays.asList("text/plain", "text/html");
+    List<String> encoding = Arrays.asList("gzip", "compress");
+
+    String name = "name_1";
+    String value = "value_1";
+    Cookie ck1 = new Cookie(name, value);
+    NewCookie nck1 = new NewCookie(ck1);
+
+    List<String> cookies = Arrays.asList(nck1.toString().toLowerCase());
+
+    Response resp = Response.status(status)
+        .header(HttpHeaders.CONTENT_ENCODING, encoding.get(0))
+        .header(HttpHeaders.CONTENT_ENCODING, encoding.get(1))
+        .header("Content-Language", "en-US").header("Content-Language", "en-GB")
+        .header("Content-Language", "zh-CN")
+        .header("Cache-Control", "no-transform")
+        .header("Set-Cookie", "name_1=value_1;version=1")
+        .header(HttpHeaders.CONTENT_TYPE, type.get(0))
+        .header(HttpHeaders.CONTENT_TYPE, type.get(1)).build();
+    result = verifyStatus(resp, status);
+    result.append(verifyEncoding(resp, encoding));
+    result.append(verifyLanguage(resp, getLangList()));
+    result.append(verifyContentType(resp, type));
+    result.append(verifyCookies(resp, cookies));
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: cloneTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:139; JAXRS:JAVADOC:141; JAXRS:JAVADOC:143;
+   * JAXRS:JAVADOC:123; JAXRS:JAVADOC:124; JAXRS:JAVADOC:125;
+   * 
+   * @test_Strategy: Create an instance of Response using
+   * Response.ResponseBuilder.clone() verify that correct status code is
+   * returned
+   */
+  @Test
+  public void cloneTest() throws Fault {
+    VerificationResult result;
+    int status = 200;
+    List<String> type = Arrays.asList("text/plain", "text/html");
+    List<String> encoding = Arrays.asList("gzip");
+    List<String> lang = getLangList();
+
+    String name = "name_1";
+    String value = "value_1";
+    Cookie ck1 = new Cookie(name, value);
+    NewCookie nck1 = new NewCookie(ck1);
+
+    List<String> cookies = Arrays.asList(nck1.toString().toLowerCase());
+
+    Response.ResponseBuilder respb1 = Response.status(status)
+        .header("Content-type", "text/plain")
+        .header("Content-type", "text/html").header("Content-Language", "en-US")
+        .header("Content-Language", "en-GB").header("Content-Language", "zh-CN")
+        .header("Cache-Control", "no-transform")
+        .header("Set-Cookie", "name_1=value_1;version=1")
+        .header(HttpHeaders.CONTENT_ENCODING, "gzip");
+    Response.ResponseBuilder respb2;
+    respb2 = respb1.clone();
+
+    Response resp2 = respb2.build();
+    result = verifyStatus(resp2, status);
+    result.append(verifyEncoding(resp2, encoding));
+    result.append(verifyLanguage(resp2, lang));
+    result.append(verifyContentType(resp2, type));
+    result.append(verifyCookies(resp2, cookies));
+
+    String content = "TestOnly";
+    Response resp1 = respb1.entity(content).cookie((NewCookie[]) null).build();
+    result.append(verifyContent(resp1, content));
+    result.append(verifyStatus(resp1, status));
+    result.append(verifyEncoding(resp1, encoding));
+    result.append(verifyLanguage(resp1, lang));
+    result.append(verifyContentType(resp1, type));
+
+    MultivaluedMap<java.lang.String, java.lang.Object> mvp = resp1
+        .getMetadata();
+    if (mvp.containsKey("Set-Cookie")) {
+      result.pass = false;
+      result.message.append("Response contains unexpected Set-Cookie: ")
+          .append(mvp.getFirst("Set-Cookie").toString()).append(newline);
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:161;
+   * 
+   * @test_Strategy: Call Response.Status.fromStatusCode(int) verify that
+   * correct Response.Status is returned
+   */
+  @Test
+  public void statusTest5() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response.Status tmp = null;
+
+    for (int i = 0; i < status_codes.length; i++) {
+      tmp = Response.Status.fromStatusCode(status_codes[i]);
+
+      if (tmp != resp_status[i]) {
+        result.pass = false;
+        result.message.append("fromStatusCode[").append(status_codes[i])
+            .append("] failed with ").append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: getFamilyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:162;
+   * 
+   * @test_Strategy: Call Response.Status.getFamily() verify that correct
+   * Response.Status.Family is returned
+   */
+  @Test
+  public void getFamilyTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response.Status.Family tmp = null;
+
+    assertTrue(status_family.length == Response.Status.values().length,
+        "Response.Status.values() are unexpected");
+
+    for (int i = 0; i < status_family.length; i++) {
+      tmp = resp_status[i].getFamily();
+
+      if (tmp != status_family[i]) {
+        result.pass = false;
+        result.message.append("getFamily failed with ").append(resp_status[i])
+            .append(" ").append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusTest7
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:163;
+   * 
+   * @test_Strategy: Call Response.Status.getStatusCode() verify that correct
+   * status code is returned
+   */
+  @Test
+  public void statusTest7() throws Fault {
+    VerificationResult result = new VerificationResult();
+    int tmp = 0;
+
+    for (int i = 0; i < status_codes.length; i++) {
+      tmp = resp_status[i].getStatusCode();
+
+      if (tmp != status_codes[i]) {
+        result.pass = false;
+        result.message.append("getStatusCode() failed with ")
+            .append(resp_status[i]).append(newline);
+        result.message.append("expecting ").append(status_codes[i])
+            .append(", got ").append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: toStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:164;
+   * 
+   * @test_Strategy: Call Response.Status.toString() verify that correct reason
+   * phase is returned
+   */
+  @Test
+  public void toStringTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    String tmp = null;
+
+    for (int i = 0; i < resp_status.length; i++) {
+      tmp = resp_status[i].toString();
+
+      if (!tmp.equals(status[i])) {
+        result.pass = false;
+        result.message.append("Status.toString() failed with ")
+            .append(resp_status[i]).append(newline);
+        result.message.append("expecting ").append(status[i]).append(", got ")
+            .append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: getReasonPhraseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:301; JAXRS:JAVADOC:166;
+   * 
+   * @test_Strategy: Call Response.Status.getReasonPhrase() verify that correct
+   * reason phase is returned
+   */
+  @Test
+  public void getReasonPhraseTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    String tmp = null;
+
+    assertTrue(status.length == Response.Status.values().length,
+        "Response.Status.values() are unexpected");
+
+    for (int i = 0; i < resp_status.length; i++) {
+      tmp = resp_status[i].getReasonPhrase();
+
+      if (!tmp.equals(status[i])) {
+        result.pass = false;
+        result.message.append("Status.toString() failed with ")
+            .append(resp_status[i]).append(newline);
+        result.message.append("expecting ").append(status[i]).append(", got ")
+            .append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusValueOfTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:165; JAXRS:JAVADOC:166;
+   * 
+   * @test_Strategy: Call Response.Status.valueOf(String) verify that correct
+   * Status is returned
+   */
+  @Test
+  public void statusValueOfTest() throws Fault {
+    VerificationResult result = new VerificationResult();
+    Response.Status tmp = null;
+    for (int i = 0; i < resp_status.length; i++) {
+      try {
+        tmp = Response.Status.valueOf(
+            status[i].replace(" ", "_").replace("-", "_").toUpperCase());
+      } catch (Exception ex) {
+        result.message.append("Exception thrown with status name ")
+            .append(status[i]).append(newline);
+        result.message.append(ex.getMessage());
+        result.pass = false;
+      }
+      if (!tmp.equals(resp_status[i])) {
+        result.pass = false;
+        result.message.append("Status.toString() failed with ")
+            .append(resp_status[i]).append(newline);
+        result.message.append("expecting ").append(resp_status[i])
+            .append(", got ").append(tmp).append(newline);
+      }
+    }
+    logMsg(result);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: statusFamilyValueOfTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:167; JAXRS:JAVADOC:168;
+   * 
+   * @test_Strategy: Call Response.Status.Family.valueOf() verify that correct
+   * Family is returned
+   */
+  @Test
+  public void statusFamilyValueOfTest() throws Fault {
+    Response.Status.Family[] families = Response.Status.Family.values();
+    assertTrue(families.length == status_family_list.length,
+        "Response.Status.Family.values() are unexpected");
+    Arrays.sort(status_family_list);
+    for (int i = 0; i != families.length; i++) {
+      int match = Arrays.binarySearch(status_family_list,
+          Response.Status.Family.valueOf(families[i].name()));
+      assertTrue(match != -1, "Unknown Response Status Family"+ families[i]);
+    }
+  }
+
+  /*
+   * @testName: statusFamilyValuesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:168;
+   * 
+   * @test_Strategy: Call Response.Status.Family.values() verify that correct
+   * Family is returned
+   */
+  @Test
+  public void statusFamilyValuesTest() throws Fault {
+    Response.Status.Family[] families = Response.Status.Family.values();
+    assertTrue(families.length == status_family_list.length,
+        "Response.Status.Family.values() are unexpected");
+    Arrays.sort(status_family_list);
+    for (int i = 0; i != families.length; i++) {
+      int match = Arrays.binarySearch(status_family_list, families[i]);
+      assertTrue(match != -1, "Unknown Resposne Status Family"+ families[i]);
+    }
+  }
+
+  /*
+   * @testName: acceptedNoArgTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:836;
+   * 
+   * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status.
+   */
+  @Test
+  public void acceptedNoArgTest() throws Fault {
+    VerificationResult result;
+    Response response = null;
+    response = Response.accepted().build();
+    result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: acceptedStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:837;
+   * 
+   * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status that
+   * contains a representation. It is the callers responsibility to wrap the
+   * actual entity with GenericEntity if preservation of its generic type is
+   * required.
+   */
+  @Test
+  public void acceptedStringTest() throws Fault {
+    VerificationResult result;
+    String entity = "ENtiTy";
+    Response response = null;
+    response = Response.accepted(entity).build();
+    result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+    result.append(verifyContent(response, entity));
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: acceptedGenericEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:837;
+   * 
+   * @test_Strategy: Create a new ResponseBuilder with an ACCEPTED status that
+   * contains a representation. It is the callers responsibility to wrap the
+   * actual entity with GenericEntity if preservation of its generic type is
+   * required.
+   */
+  @Test
+  public void acceptedGenericEntityTest() throws Fault {
+    VerificationResult result;
+    String entity = "ENtiTy";
+    GenericEntity<String> generic = new GenericEntity<String>(entity,
+        String.class);
+    Response response = Response.accepted(generic).build();
+    result = verifyStatus(response, Status.ACCEPTED.getStatusCode());
+    result.append(verifyContent(response, entity));
+    logMsg(result.message);
+    assertResultTrue(result);
+  }
+
+  /*
+   * @testName: bufferEntityIgnoreNoBackingStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:838;
+   * 
+   * @test_Strategy: In case the response entity instance is not backed by an
+   * unconsumed input stream an invocation of bufferEntity method is ignored and
+   * the method returns false.
+   */
+  @Test
+  public void bufferEntityIgnoreNoBackingStreamTest() throws Fault {
+    Response response = Response.ok().build();
+    boolean result = response.bufferEntity();
+    assertTrue(!result, "#bufferEntity() did not ignore no backing stream");
+    logMsg("#bufferEntity did ignore no backing stream as expected");
+  }
+
+  /*
+   * @testName: bufferEntityThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:838;
+   * 
+   * @test_Strategy: throws IllegalStateException - in case the response has
+   * been #close() closed.
+   */
+  @Test
+  public void bufferEntityThrowsIllegalStateExceptionTest() throws Fault {
+    Response response = Response.ok().build();
+    response.close();
+    try {
+      response.bufferEntity();
+      fault("buffer entity did not throw IllegalStateException when closed");
+    } catch (IllegalStateException e) {
+      logMsg("#bufferEntity throws IllegalStateException as expected");
+    }
+  }
+
+  /*
+   * @testName: getAllowedMethodsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:843;
+   * 
+   * @test_Strategy: Get the allowed HTTP methods from the Allow HTTP header.
+   */
+  @Test
+  public void getAllowedMethodsTest() throws Fault {
+    Response response = Response.ok()
+        .header(HttpHeaders.ALLOW, Request.POST.name())
+        .header(HttpHeaders.ALLOW, Request.TRACE.name()).build();
+    Set<String> set = response.getAllowedMethods();
+    String methods = JaxrsUtil.iterableToString(";", set);
+    assertContainsIgnoreCase(methods, Request.POST.name(), Request.POST.name(),
+        "method has not been found");
+    assertContainsIgnoreCase(methods, Request.TRACE.name(),
+        Request.TRACE.name(), "method has not been found");
+    assertTrue(
+        methods.length() < Request.TRACE.name().length()
+            + Request.POST.name().length() + 3,
+        "Request contains some additional methods then expected"+ methods);
+    logMsg("#getAllowedMethods returned expected methods", methods);
+  }
+
+  /*
+   * @testName: getCookiesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:844;
+   * 
+   * @test_Strategy: Get any new cookies set on the response message.
+   */
+  @Test
+  public void getCookiesTest() throws Fault {
+    NewCookie cookie1 = new NewCookie("c1", "v1");
+    NewCookie cookie2 = new NewCookie("c2", "v2");
+    List<String> cookies = Arrays.asList(cookie1.toString().toLowerCase(),
+        cookie2.toString().toLowerCase());
+    Response response = Response.ok().cookie(cookie1).cookie(cookie2).build();
+    // verifyCookies style test
+    VerificationResult result = verifyCookies(response, cookies);
+    logMsg(result);
+    assertResultTrue(result);
+    // getCookies test
+    Map<String, NewCookie> map = response.getCookies();
+    for (Entry<String, NewCookie> entry : map.entrySet())
+      if (entry.getKey().equals("c1"))
+        assertTrue(entry.getValue().equals(cookie1), cookie1.toString()+
+            "not match"+ entry.getValue());
+      else if (entry.getKey().equals("c2"))
+        assertTrue(entry.getValue().equals(cookie2), cookie2.toString()+
+            "not match"+ entry.getValue());
+      else
+        assertTrue(false, "Got unknown cookie"+ entry.getKey());
+
+    logMsg("#getCookies returned expected cookies");
+  }
+
+  /*
+   * @testName: getCookiesIsImmutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:844;
+   * 
+   * @test_Strategy: returns a read-only map of cookie name (String) to Cookie.
+   */
+  @Test
+  public void getCookiesIsImmutableTest() throws Fault {
+    NewCookie cookie1 = new NewCookie("c1", "v1");
+    NewCookie cookie2 = new NewCookie("c2", "v2");
+    Response response = Response.ok().cookie(cookie1).build();
+    // getCookies test
+    Map<String, NewCookie> map;
+    try {
+      map = response.getCookies();
+      map.put("c2", cookie2);
+    } catch (Exception e) {
+      // can throw an exception or nothing or return a copy map
+    }
+    map = response.getCookies();
+    assertTrue(!map.containsKey("c2"), "getCookies is not read-only returned"+
+        map.get("c2"));
+    logMsg("#getCookies is read-only as expected");
+  }
+
+  /*
+   * @testName: getDateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:845;
+   * 
+   * @test_Strategy: Get message date.
+   */
+  @Test
+  public void getDateTest() throws Fault {
+    Date date = Calendar.getInstance().getTime();
+    Response response = Response.ok().header("Date", date).build();
+
+    Date responseDate = response.getDate();
+    assertTrue(date.equals(responseDate), "Original date"+ date+
+        "and response#getDate()"+ responseDate+ "differs");
+    logMsg("#getDate matches the Date HTTP header");
+  }
+
+  /*
+   * @testName: getDateNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:845;
+   * 
+   * @test_Strategy: Get null if not present.
+   */
+  @Test
+  public void getDateNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    Date responseDate = response.getDate();
+    assertTrue(responseDate == null, "response#getDate() should be null, was"+
+        responseDate);
+    logMsg("#getDate is null as expected");
+  }
+
+  /*
+   * @testName: getEntityThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:123;
+   * 
+   * @test_Strategy: if the entity was previously fully consumed as an
+   * InputStream input stream, or if the response has been #close() closed.
+   */
+  @Test
+  public void getEntityThrowsIllegalStateExceptionTest() throws Fault {
+    Response response = Response.ok("entity").build();
+    response.close();
+    try {
+      response.getEntity();
+      fault("No exception has been thrown");
+    } catch (IllegalStateException e) {
+      logMsg("#getEntity throws IllegalStateException as expected", e);
+    }
+  }
+
+  /*
+   * @testName: getEntityTagTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:847;
+   * 
+   * @test_Strategy: Get the entity tag.
+   */
+  @Test
+  public void getEntityTagTest() throws Fault {
+    EntityTag tag = new EntityTag("getEntityTag");
+    Response response = Response.notModified(tag).build();
+    EntityTag responseTag = response.getEntityTag();
+    assertTrue(tag.equals(responseTag), "response#getEntityTag()"+ responseTag+
+        "is unequal to expected EntityTag"+ tag);
+    logMsg("#getEntityTag is", responseTag, "as expected");
+  }
+
+  /*
+   * @testName: getEntityTagNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:847;
+   * 
+   * @test_Strategy: Get null if not present.
+   */
+  @Test
+  public void getEntityTagNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    EntityTag responseTag = response.getEntityTag();
+    assertTrue(responseTag == null,
+        "response#getEntityTag() should be null, was"+ responseTag);
+    logMsg("#getEntityTag() is null as expected");
+  }
+
+  /*
+   * @testName: getHeadersTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:848;
+   * 
+   * @test_Strategy: Get view of the response headers and their object values.
+   */
+  @Test
+  public void getHeadersTest() throws Fault {
+    CacheControl ccl = new CacheControl();
+    NewCookie cookie = new NewCookie("cookie", "eikooc");
+    String encoding = "gzip";
+    Date date = Calendar.getInstance().getTime();
+
+    Response response = Response.ok().cacheControl(ccl).cookie(cookie)
+        .encoding(encoding).expires(date).language(Locale.CANADA_FRENCH)
+        .build();
+    logMsg("Found following objects:");
+    logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+
+    MultivaluedMap<String, Object> headers = response.getHeaders();
+    String header = null;
+
+    header = headers.getFirst(HttpHeaders.CACHE_CONTROL).toString();
+    assertContainsIgnoreCase(header, "no-transform",
+        "Cache-Control:no-transform has not been found");
+
+    header = headers.getFirst(HttpHeaders.SET_COOKIE).toString();
+    assertContainsIgnoreCase(header, "cookie=eikooc",
+        "Set-Cookie:cookie=eikooc has not been found");
+
+    header = headers.getFirst(HttpHeaders.CONTENT_ENCODING).toString();
+    assertContainsIgnoreCase(header, "gzip",
+        "Content-Encoding:gzip has not been found");
+
+    header = headers.getFirst(HttpHeaders.EXPIRES).toString();
+    assertNotNull(header, "Expires has not been found");
+
+    header = headers.getFirst(HttpHeaders.CONTENT_LANGUAGE).toString();
+    assertContainsIgnoreCase(langToString(header),
+        langToString(Locale.CANADA_FRENCH), "Content-Language:",
+        langToString(Locale.CANADA_FRENCH), "has not been found");
+
+    Object noHeader = headers.getFirst("unknown");
+    assertNull(noHeader, "Unknown header has been found", header);
+  }
+
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:848;
+   * 
+   * @test_Strategy: Get view of the response headers and their object values.
+   * Changes in the underlying header data are reflected in this view.
+   */
+  @Test
+  public void getHeadersIsMutableTest() throws Fault {
+    String header = "header";
+    Response response = Response.ok().build();
+    MultivaluedMap<String, Object> headers = response.getHeaders();
+    Object value = headers.getFirst(header);
+    assertNull(value, "Unexpected header", header, ":", value);
+    headers.add(header, header);
+    headers = response.getHeaders();
+    value = headers.getFirst(header);
+    assertContainsIgnoreCase(value, header, "Unexpected header value", header,
+        ":", value);
+    logMsg("getHeaders is mutable");
+  }
+
+  /*
+   * @testName: getHeaderStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:849;
+   * 
+   * @test_Strategy: Get a message header as a single string value.
+   */
+  @Test
+  public void getHeaderStringTest() throws Fault {
+    CacheControl ccl = new CacheControl();
+    ccl.setNoStore(true);
+    NewCookie cookie = new NewCookie("cookie", "eikooc");
+    String encoding = "gzip";
+    Date date = Calendar.getInstance().getTime();
+
+    Response response = Response.ok().cacheControl(ccl).cookie(cookie)
+        .encoding(encoding).expires(date).language(Locale.CANADA_FRENCH)
+        .build();
+    logMsg("Found following objects:");
+    logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+    assertContainsIgnoreCase(
+        response.getHeaderString(HttpHeaders.CACHE_CONTROL), "no-store",
+        "Cache-Control:no-store has not been found");
+    assertContainsIgnoreCase(
+        response.getHeaderString(HttpHeaders.CACHE_CONTROL), "no-transform",
+        "Cache-Control:no-transform has not been found");
+    assertContainsIgnoreCase(response.getHeaderString(HttpHeaders.SET_COOKIE),
+        "cookie=eikooc", "Set-Cookie:cookie=eikooc has not been found");
+    assertContainsIgnoreCase(
+        response.getHeaderString(HttpHeaders.CONTENT_ENCODING), "gzip",
+        "Content-Encoding:gzip has not been found");
+    assertNotNull(response.getHeaderString(HttpHeaders.EXPIRES),
+        "Expires has not been found");
+    assertContainsIgnoreCase(
+        langToString(response.getHeaderString("Content-Language")),
+        langToString(Locale.CANADA_FRENCH), "Content-Language:",
+        langToString(Locale.CANADA_FRENCH), "has not been found");
+    assertNull(response.getHeaderString("unknown"),
+        "Unknown header has been found", response.getHeaderString("unknown"));
+  }
+
+  /*
+   * @testName: getHeaderStringUsingHeaderDelegateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:849;
+   * 
+   * @test_Strategy: Get a message header as a single string value. Each single
+   * header value is converted to String using a RuntimeDelegate.HeaderDelegate
+   * or using its toString
+   */
+  @Test
+  public void getHeaderStringUsingHeaderDelegateTest() throws Fault {
+    StringBean bean = new StringBean("s3");
+    RuntimeDelegate original = RuntimeDelegate.getInstance();
+    RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+    try {
+      Response response = Response.ok().header(bean.get(), bean).build();
+      String header = response.getHeaderString(bean.get());
+      assertContainsIgnoreCase(header, bean.get(), "Header", bean.get(),
+          "has unexpected value", header);
+      logMsg("HeaderDelegate is used for header", bean.get());
+    } finally {
+      RuntimeDelegate.setInstance(original);
+      StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+    }
+  }
+
+  /*
+   * @testName: getHeaderStringUsingToStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:849;
+   * 
+   * @test_Strategy: Get a message header as a single string value. Each single
+   * header value is converted to String using a RuntimeDelegate.HeaderDelegate
+   * or using its toString
+   */
+  @Test
+  public void getHeaderStringUsingToStringTest() throws Fault {
+    StringBuilder builder = new StringBuilder("s1");
+    StringBuffer buffer = new StringBuffer("s2");
+    Response response = Response.ok().header(builder.toString(), builder)
+        .header(buffer.toString(), buffer).build();
+    String header = response.getHeaderString(builder.toString());
+    assertContainsIgnoreCase(header, builder.toString(), "Header", builder,
+        "has unexpected value", header);
+
+    header = response.getHeaderString(buffer.toString());
+    assertContainsIgnoreCase(header, buffer.toString(), "Header", builder,
+        "has unexpected value", header);
+
+    logMsg("toString method is used as expected");
+  }
+
+  /*
+   * @testName: getLanguageTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:850;
+   * 
+   * @test_Strategy: Get the language of the message entity.
+   */
+  @Test
+  public void getLanguageTest() throws Fault {
+    Response response = Response.ok().language(Locale.CANADA_FRENCH).build();
+    Locale locale = response.getLanguage();
+    assertTrue(Locale.CANADA_FRENCH.equals(locale), "Locale"+
+        Locale.CANADA_FRENCH+ "does NOT match response#getLocale()"+ locale);
+    logMsg("#getLocale matches the Content-Language HTTP header");
+  }
+
+  /*
+   * @testName: getLanguageNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:850;
+   * 
+   * @test_Strategy: Get null if not present.
+   */
+  @Test
+  public void getLanguageNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    Locale locale = response.getLanguage();
+    assertTrue(locale == null, "response#getLanguage() should be null, was"+
+        locale);
+    logMsg("#getLanguage() is null as expected");
+  }
+
+  /*
+   * @testName: getLastModifiedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:851;
+   * 
+   * @test_Strategy: Get the last modified date.
+   */
+  @Test
+  public void getLastModifiedTest() throws Fault {
+    Date date = Calendar.getInstance().getTime();
+    Response response = Response.ok().lastModified(date).build();
+    Date responseDate = response.getLastModified();
+    assertTrue(date.equals(responseDate), "Last Modified date"+ date+
+        "does NOT match response#getLastModified()"+ responseDate);
+    logMsg("#getLastModified matches the Last-Modified HTTP header");
+  }
+
+  /*
+   * @testName: getLastModifiedNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:851;
+   * 
+   * @test_Strategy: Get null if not present.
+   */
+  @Test
+  public void getLastModifiedNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    Date responseDate = response.getLastModified();
+    assertTrue(responseDate == null,
+        "response#getLastModified() should be null, was"+ responseDate);
+    logMsg("#getLastModified() is null as expected");
+  }
+
+  /*
+   * @testName: getLengthTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:852;
+   * 
+   * @test_Strategy: Get Content-Length value.
+   */
+  @Test
+  public void getLengthTest() throws Fault {
+    Response response = Response.ok("1234567890")
+        .header(HttpHeaders.CONTENT_LENGTH, "10").build();
+    int len = response.getLength();
+    assertTrue(len > 9, "Expected Content-Length > 9"+
+        "does NOT match response#getLength()"+ len);
+    logMsg("#getLength matches expected Content-Length", len);
+  }
+
+  /*
+   * @testName: getLengthNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:852;
+   * 
+   * @test_Strategy: In other cases returns -1.
+   */
+  @Test
+  public void getLengthNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    int len = response.getLength();
+    assertTrue(len == -1, "Expected Content-Length = -1"+
+        "does NOT match response#getLength()"+ len);
+    logMsg("#getLength matches expected Content-Length", len);
+  }
+
+  /*
+   * @testName: getLinkTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:853;
+   * 
+   * @test_Strategy: Get the link for the relation.
+   */
+  @Test
+  public void getLinkTest() throws Fault {
+    Link link = createLink("path", "getLinkTest");
+    Response response = Response.ok().links(link).build();
+    Link responseLink = response.getLink("getLinkTest");
+    assertTrue(link.equals(responseLink),
+        "#getLink() returned unexpected Link"+ responseLink);
+    logMsg("#getLink matches expected Link");
+  }
+
+  /*
+   * @testName: getLinkNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:853;
+   * 
+   * @test_Strategy: returns null if not present.
+   */
+  @Test
+  public void getLinkNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    Link responseLink = response.getLink("getLinkTest");
+    assertTrue(responseLink == null, "#getLink() returned unexpected Link"+
+        responseLink);
+    logMsg("#getLink return null as expected");
+  }
+
+  /*
+   * @testName: getLinkBuilderForTheRelationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:854;
+   * 
+   * @test_Strategy: Convenience method that returns a Link.Builder for the
+   * relation.
+   */
+  @Test
+  public void getLinkBuilderForTheRelationTest() throws Fault {
+    String rel = "anyrelation";
+    Response response = Response.ok().link("http://abc.com/b/", rel).build();
+    Link builderLink = response.getLinkBuilder("anyrelation").build();
+    response = Response.ok().links(builderLink).build();
+    Link responseLink = response.getLink("anyrelation");
+    assertNotNull(responseLink, "#getLinkBuilder('relation') returned null");
+    logMsg("#getLinkBuilder creates correct Link for given relation");
+  }
+
+  /*
+   * @testName: getLinkBuilderForTheNotPresentRelationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:854;
+   * 
+   * @test_Strategy: returns null if not present.
+   */
+  @Test
+  public void getLinkBuilderForTheNotPresentRelationTest() throws Fault {
+    Response response = Response.ok().build();
+    Builder builder = response.getLinkBuilder("anyrelation");
+    assertTrue(builder == null,
+        "#getLinkBuilder('relation') returned unexpected builder"+ builder);
+    logMsg("#getLinkBuilder returned null as expected");
+  }
+
+  /*
+   * @testName: getLinksTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:855;
+   * 
+   * @test_Strategy: Get the links attached to the message as header.
+   */
+  @Test
+  public void getLinksTest() throws Fault {
+    Link link1 = createLink("path1", "rel1");
+    Link link2 = createLink("path2", "rel2");
+    Response response = Response.ok().links(link1, link2).build();
+    Set<Link> responseLinks = response.getLinks();
+    assertEqualsInt(responseLinks.size(), 2,
+        "#getLinks() returned set of unexpected size", responseLinks.size());
+    assertTrue(responseLinks.contains(link1), "#getLinks does not contain"+
+        link1);
+    assertTrue(responseLinks.contains(link2), "#getLinks does not contain"+
+        link2);
+    logMsg("#getLinks contains expected links");
+  }
+
+  /*
+   * @testName: getLinksIsNotNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:855;
+   * 
+   * @test_Strategy: Does not return null.
+   */
+  @Test
+  public void getLinksIsNotNullTest() throws Fault {
+    Response response = Response.ok().build();
+    Set<Link> responseLinks = response.getLinks();
+    assertTrue(responseLinks != null, "#getLinks() returned null!");
+    assertTrue(responseLinks.size() == 0,
+        "#getLinks() returned non-empty map!");
+    logMsg("#getLinks contains no links as expected");
+  }
+
+  /*
+   * @testName: getLocationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:856;
+   * 
+   * @test_Strategy: Get the location.
+   */
+  @Test
+  public void getLocationTest() throws Fault {
+    URI location = createUri("path");
+    Response response = Response.ok().location(location).build();
+    URI responseLocation = response.getLocation();
+    assertTrue(responseLocation.equals(location), "#getLocation()"+
+        responseLocation+ "differs from expected"+ location);
+    logMsg("#getLocation contains expected location");
+  }
+
+  /*
+   * @testName: getLocationNotPresentTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:856;
+   * 
+   * @test_Strategy: Get null when no present.
+   */
+  @Test
+  public void getLocationNotPresentTest() throws Fault {
+    Response response = Response.ok().build();
+    URI responseLocation = response.getLocation();
+    assertTrue(responseLocation == null, "#getLocation()"+ responseLocation+
+        "should be null");
+    logMsg("#getLocation returns null as expected");
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:857;
+   * 
+   * @test_Strategy: Get the media type of the message entity.
+   */
+  @Test
+  public void getMediaTypeTest() throws Fault {
+    Response response = Response.ok().type(MediaType.APPLICATION_ATOM_XML)
+        .build();
+    MediaType responseMedia = response.getMediaType();
+    assertTrue(MediaType.APPLICATION_ATOM_XML_TYPE.equals(responseMedia),
+        "#getMediaType()"+ responseMedia+ "differs from expected"+
+        MediaType.APPLICATION_ATOM_XML);
+    logMsg("#getMediaType returned expected MediaType");
+  }
+
+  /*
+   * @testName: getMediaTypeNoMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:857;
+   * 
+   * @test_Strategy: null if there is no response entity.
+   */
+  @Test
+  public void getMediaTypeNoMediaTypeTest() throws Fault {
+    Response response = Response.ok().build();
+    MediaType responseMedia = response.getMediaType();
+    assertTrue(responseMedia == null, "#getMediaType()"+ responseMedia+
+        "should be null");
+    logMsg("#getMediaType returned null as expected");
+  }
+
+  /*
+   * @testName: getStatusInfoTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:858;
+   * 
+   * @test_Strategy: Get the complete status information associated with the
+   * response.
+   */
+  @Test
+  public void getStatusInfoTest() throws Fault {
+    for (Status status : Status.values()) {
+      Response response = Response.status(status).build();
+      StatusType info = response.getStatusInfo();
+      assertTrue(info.getStatusCode() == status.getStatusCode(),
+          "#getStatusInfo returned unexpected value"+ info);
+    }
+    logMsg("#getStatusInfo returned expected StatusTypes");
+  }
+
+  /*
+   * @testName: getStringHeadersUsingToStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:859;
+   * 
+   * @test_Strategy: Get view of the response headers and their string values.
+   * Each single header value is converted to String using a
+   * RuntimeDelegate.HeaderDelegate or using its toString
+   */
+  @Test
+  public void getStringHeadersUsingToStringTest() throws Fault {
+    RuntimeDelegate original = RuntimeDelegate.getInstance();
+    RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+    try {
+      StringBuilder builder = new StringBuilder("s1");
+      StringBuffer buffer = new StringBuffer("s2");
+      StringBean bean = new StringBean("s3");
+      Response response = Response.ok().header(builder.toString(), builder)
+          .header(buffer.toString(), buffer).header(bean.get(), bean).build();
+      MultivaluedMap<String, String> headers = response.getStringHeaders();
+      String header = headers.getFirst(builder.toString());
+      assertContainsIgnoreCase(header, builder.toString(), "Header", builder,
+          "has unexpected value", header);
+
+      header = headers.getFirst(buffer.toString());
+      assertContainsIgnoreCase(header, buffer.toString(), "Header", builder,
+          "has unexpected value", header);
+
+      logMsg("#getStringHeaders contains expected values",
+          JaxrsUtil.iterableToString(",", headers.entrySet()));
+    } finally {
+      RuntimeDelegate.setInstance(original);
+      StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+    }
+  }
+
+  /*
+   * @testName: getStringHeadersUsingHeaderDelegateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:859;
+   * 
+   * @test_Strategy: Get view of the response headers and their string values.
+   * Each single header value is converted to String using a
+   * RuntimeDelegate.HeaderDelegate or using its toString
+   */
+  @Test
+  public void getStringHeadersUsingHeaderDelegateTest() throws Fault {
+    RuntimeDelegate original = RuntimeDelegate.getInstance();
+    RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+    try {
+      StringBuilder builder = new StringBuilder("s1");
+      StringBuffer buffer = new StringBuffer("s2");
+      StringBean bean = new StringBean("s3");
+      Response response = Response.ok().header(builder.toString(), builder)
+          .header(buffer.toString(), buffer).header(bean.get(), bean).build();
+      MultivaluedMap<String, String> headers = response.getStringHeaders();
+      String header = headers.getFirst(bean.get());
+      assertContainsIgnoreCase(bean.get(), header, "Header", bean.get(),
+          "has unexpected value", header);
+
+      logMsg("#getStringHeaders contains expected values",
+          JaxrsUtil.iterableToString(",", headers.entrySet()));
+    } finally {
+      RuntimeDelegate.setInstance(original);
+      StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+    }
+  }
+
+  /*
+   * @testName: hasEntityWhenEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:860;
+   * 
+   * @test_Strategy: Check if there is an entity available in the response.
+   */
+  @Test
+  public void hasEntityWhenEntityTest() throws Fault {
+    Response response = Response.ok("entity").build();
+    assertTrue(response.hasEntity(), "#hasEntity did not found the entity");
+    logMsg("#hasEntity found the entity as expected");
+  }
+
+  /*
+   * @testName: hasEntityWhenNoEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:860;
+   * 
+   * @test_Strategy: Check if there is an entity available in the response.
+   */
+  @Test
+  public void hasEntityWhenNoEntityTest() throws Fault {
+    Response response = Response.ok().build();
+    assertTrue(!response.hasEntity(), "#hasEntity did found the entity");
+    logMsg("#hasEntity has not found any entity as expected");
+  }
+
+  /*
+   * @testName: hasEntityThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:860;
+   * 
+   * @test_Strategy: throws java.lang.IllegalStateException - in case the
+   * response has been closed.
+   */
+  @Test
+  public void hasEntityThrowsIllegalStateExceptionTest() throws Fault {
+    Response response = Response.ok().build();
+    response.close();
+    try {
+      response.hasEntity();
+      fault("No exception has been thrown");
+    } catch (IllegalStateException e) {
+      logMsg("IllegalStateException has been thrown as expected");
+    }
+
+  }
+
+  /*
+   * @testName: hasLinkWhenLinkTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:862;
+   * 
+   * @test_Strategy: Check if link for relation exists.
+   */
+  @Test
+  public void hasLinkWhenLinkTest() throws Fault {
+    Link link = createLink("path", "rel");
+    Response response = Response.ok().links(link).build();
+    assertTrue(response.hasLink("rel"), "#hasLink did not found a Link");
+    logMsg("#hasEntity found the Link as expected");
+  }
+
+  /*
+   * @testName: hasLinkWhenNoLinkTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:862;
+   * 
+   * @test_Strategy: Check if link for relation exists.
+   */
+  @Test
+  public void hasLinkWhenNoLinkTest() throws Fault {
+    Response response = Response.ok().build();
+    assertTrue(!response.hasLink("rel"), "#has Link did found some Link");
+    logMsg("#hasLink has not found any Link as expected");
+  }
+
+  // /////////////////////////////////////////////////////////////////////////
+
+  protected VerificationResult verifyContent(Response response,
+      String content) {
+    VerificationResult result = new VerificationResult();
+    if ((content == null) || (content == "")) {
+      if (!(response.getEntity() == null)
+          || (response.getEntity().equals(""))) {
+        result.pass = false;
+        result.message.append(indent)
+            .append("Entity verification failed: expecting no content, got ")
+            .append(response.getEntity()).append(newline);
+      }
+    } else if (!content.equals(response.getEntity())) {
+      result.pass = false;
+      result.message.append(indent)
+          .append("Entity verification failed: expecting ").append(content)
+          .append(", got ").append(response.getEntity()).append(newline);
+    } else {
+      result.message.append(indent)
+          .append("Correct content found in Response: ")
+          .append(response.getEntity()).append(newline);
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyStatus(Response response, int status) {
+    VerificationResult result = new VerificationResult();
+    if (response.getStatus() != status) {
+      result.pass = false;
+      result.message.append(indent)
+          .append("Status code verification failed: expecting ").append(status)
+          .append(", got ").append(response.getStatus()).append(newline);
+    } else {
+      result.message.append(indent).append("Correct status found in Response: ")
+          .append(status).append(newline);
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyHeaders(Response response,
+      HashMap<String, String> expected) {
+    MultivaluedMap<java.lang.String, java.lang.Object> headers = response
+        .getMetadata();
+    VerificationResult result = new VerificationResult();
+    result.message.append("========== Verifying a Response with Map: ")
+        .append(newline);
+    for (String key_actual : headers.keySet()) {
+      result.message.append(indent).append("Response contains key: ")
+          .append(key_actual).append(newline);
+    }
+    result.message.append(indent)
+        .append("Verifying the following keys in Response:").append(newline);
+    String actual;
+
+    for (Entry<String, String> entry : expected.entrySet()) {
+      String key = entry.getKey();
+      String value = entry.getValue();
+
+      if (!headers.containsKey(key)) {
+        result.pass = false;
+        result.message.append(indent).append(indent).append("Key: ").append(key)
+            .append(" is not found in Response;").append(newline);
+      } else if (key.equalsIgnoreCase("last-modified")) {
+        result.message.append(indent).append(indent)
+            .append("Key Last-Modified is found in response").append(newline);
+      } else {
+        actual = headers.getFirst(key).toString().toLowerCase();
+
+        if (actual.startsWith("\"") && actual.endsWith("\""))
+          actual = actual.substring(1, actual.length() - 1);
+
+        if (!actual.equalsIgnoreCase(value)) {
+          result.pass = false;
+          result.message.append(indent).append(indent);
+          result.message.append("Key: ").append(key);
+          result.message.append(" found in Response, but with different value;")
+              .append(newline);
+          result.message.append(indent).append(indent).append("Expecting ")
+              .append(value).append("; got ").append(headers.getFirst(key))
+              .append(newline);
+        }
+        result.message.append(indent).append(indent).append("Processed key ")
+            .append(key).append(" with expected value ").append(value)
+            .append(newline);
+      }
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyEncoding(Response response,
+      List<String> encoding) {
+    VerificationResult result = new VerificationResult();
+    List<Object> enc = response.getHeaders().get(HttpHeaders.CONTENT_ENCODING);
+    if (enc == null) {
+      result.pass = false;
+      result.message.append(HttpHeaders.CONTENT_ENCODING)
+          .append(" headers is null").append(newline);
+      result.message.append("Headers :").append(response.getHeaders())
+          .append(newline);
+    } else
+      for (Object e : enc)
+        if (!encoding.contains(e.toString().toLowerCase())) {
+          result.pass = false;
+          result.message.append(indent).append(indent).append("Encoding ")
+              .append(e).append(" was not found in headers")
+              .append(response.getHeaders()).append(newline);
+        } else
+          result.message.append(indent).append("Encoding ").append(e)
+              .append(" was found").append(newline);
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyLanguage(Response response,
+      List<String> languages) {
+    VerificationResult result = new VerificationResult();
+    List<Object> responseLangs = response.getHeaders()
+        .get(HttpHeaders.CONTENT_LANGUAGE); // one only
+    if (responseLangs == null) {
+      result.pass = false;
+      result.message.append(HttpHeaders.CONTENT_LANGUAGE)
+          .append(" headers is null").append(newline);
+      result.message.append("Headers :").append(response.getHeaders())
+          .append(newline);
+    } else {
+      String lang = langToString(JaxrsUtil.iterableToString(" ", languages))
+          .toLowerCase();
+      for (Object responseLang : responseLangs)
+        if (!lang.contains(langToString(responseLang).toLowerCase())) {
+          result.pass = false;
+          result.message.append(indent).append(indent)
+              .append("language test failed: ").append(responseLang)
+              .append(" is not expected in Response")
+              .append(response.getHeaders()).append(newline);
+          for (String tt : languages) {
+            result.message.append(indent).append(indent)
+                .append("Expecting Content-Language ").append(tt)
+                .append(newline);
+          }
+        } else
+          result.message.append(indent).append("Content Language ").append(lang)
+              .append(" was found").append(newline);
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyContentType(Response response,
+      List<String> type) {
+    VerificationResult result = new VerificationResult();
+    List<Object> enc = response.getHeaders().get(HttpHeaders.CONTENT_TYPE);
+    if (enc == null) {
+      result.pass = false;
+      result.message.append(HttpHeaders.CONTENT_TYPE).append(" headers is null")
+          .append(newline);
+      result.message.append("Headers :").append(response.getHeaders())
+          .append(newline);
+    } else
+      for (Object e : enc)
+        if (!type.contains(e.toString().toLowerCase())) {
+          result.pass = false;
+          result.message.append(indent).append(indent).append("Content-Type ")
+              .append(e).append(" was not found in headers")
+              .append(response.getHeaders()).append(newline);
+        } else
+          result.message.append(indent).append("Content Type ").append(e)
+              .append(" was found").append(newline);
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyVary(Response response, List<String> var) {
+    VerificationResult result = new VerificationResult();
+    if (var != null)
+      for (Entry<String, List<Object>> entry : response.getMetadata()
+          .entrySet())
+        if (entry.getKey().equalsIgnoreCase("Vary"))
+          for (String value : var) {
+            String actual = entry.getValue().toString().toLowerCase();
+            if (actual.indexOf(value.toLowerCase()) < 0) {
+              result.pass = false;
+              result.message.append(indent).append(indent)
+                  .append("Expected header ").append(value)
+                  .append(" not set in Vary.").append(newline);
+            } else {
+              result.message.append(indent).append(indent)
+                  .append("Found expected header ").append(value).append(".")
+                  .append(newline);
+            }
+          }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyCacheControl(Response response,
+      List<String> ccl) {
+    VerificationResult result = new VerificationResult();
+    if (ccl != null) {
+      for (String tt : ccl)
+        result.message.append("Expecting Cache-Control ").append(tt)
+            .append(newline);
+      for (Entry<String, List<Object>> entry : response.getMetadata()
+          .entrySet())
+        if (entry.getKey().equalsIgnoreCase("Cache-Control"))
+          for (Object all_ccl : entry.getValue())
+            for (String cc : ccl)
+              if (!(all_ccl.toString().toLowerCase()
+                  .indexOf(cc.toLowerCase()) > -1)) {
+                result.pass = false;
+                result.message.append(indent).append(indent)
+                    .append("Cache-Control test failed: ").append(cc)
+                    .append(" is not found in Response.").append(newline);
+              }
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+  protected VerificationResult verifyCookies(Response response,
+      List<String> cookies) {
+    VerificationResult result = new VerificationResult();
+    if (cookies != null) {
+      for (String tt : cookies)
+        result.message.append(indent).append(indent)
+            .append("Expecting Set-Cookie").append(tt).append(newline);
+      for (Entry<String, List<Object>> entry : response.getMetadata()
+          .entrySet()) {
+        if (entry.getKey().equalsIgnoreCase("Set-Cookie"))
+          for (Object nck_actual : entry.getValue()) {
+            result.message.append(indent).append(indent).append("Processing ")
+                .append(nck_actual.toString()).append(newline);
+            if (!cookies.contains(
+                nck_actual.toString().toLowerCase().replace(" ", ""))) {
+              result.pass = false;
+              result.message.append(indent).append(indent)
+                  .append("Set-Cookie test failed: ").append(nck_actual)
+                  .append(" is not expected in Response.").append(newline);
+            } else {
+              result.message.append(indent).append(indent)
+                  .append("Expected Set-Cookie: ").append(nck_actual)
+                  .append(" is found in Response.").append(newline);
+            }
+          }
+      }
+    }
+    result.message.append(newline);
+    return result;
+  }
+
+   protected static void assertResultTrue(VerificationResult result)   {
+    assertTrue(result.pass, "At least one assertion failed");
+  }
+
+  protected static List<String> getLangList() {
+    return Arrays.asList("en-US", "en-GB", "zh-CN");
+  }
+
+  protected static List<Variant> getVariantList(List<String> encoding,
+      MediaType... mt) {
+    return Variant.VariantListBuilder.newInstance().mediaTypes(mt)
+        .languages(new Locale("en", "US"), new Locale("en", "GB"),
+            new Locale("zh", "CN"))
+        .encodings(encoding.toArray(new String[0])).add().build();
+  }
+
+  protected static String langToString(Object object) {
+    Locale locale = null;
+    if (object instanceof List)
+      object = ((List<?>) object).iterator().next();
+    if (object instanceof Locale)
+      locale = (Locale) object;
+    String value = locale == null ? object.toString() : locale.toString();
+    return value.replace("_", "-");
+  }
+
+  protected static Link createLink(String path, String rel) throws Fault {
+    return Link.fromUri(createUri(path)).rel(rel).build();
+  }
+
+  protected static URI createUri(String path) throws Fault {
+    URI uri;
+    try {
+      uri = new URI("http://localhost.tck:888/url404/" + path);
+    } catch (URISyntaxException e) {
+      throw new Fault(e);
+    }
+    return uri;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java
new file mode 100644
index 0000000..c2fb11a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/responseclient/VerificationResult.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.responseclient;
+
+/**
+ * Verification holder structure
+ */
+public class VerificationResult {
+  public boolean pass;
+
+  public StringBuilder message;
+
+  public VerificationResult() {
+    pass = true;
+    message = new StringBuilder();
+  }
+
+  public VerificationResult(VerificationResult result) {
+    this.pass = result.pass;
+    this.message = new StringBuilder().append(message);
+  }
+
+  public VerificationResult append(VerificationResult result) {
+    this.pass &= result.pass;
+    this.message.append(result.message).append("\n");
+    return this;
+  }
+
+  @Override
+  public String toString() {
+    return message.toString();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..32e02c0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/JAXRSClientIT.java
@@ -0,0 +1,3338 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.uribuilder;
+
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.UriBuilderException;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = 1814450070599603168L;
+
+  private static final String LOCALHOST = "http://localhost:8080";
+
+  private static final String EXPECTED_PATH = "path-rootless/test2/x%25yz//path-absolute/test1/fred@example.com/x%25yz";
+
+  private static final String ENCODED_EXPECTED_PATH = "path-rootless%2Ftest2/x%25yz/%2Fpath-absolute%2F%2525test1/fred@example.com/x%25yz";
+
+  StringBuilder sb;
+
+  boolean pass = true;
+
+  URI uri;
+
+  public JAXRSClientIT() {
+    setContextRoot("/jaxrs_rs.core_uribuilder_web");
+    pass = true;
+    sb = new StringBuilder();
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /*
+   * @testName: buildTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+   * 
+   * @test_Strategy: Create an Uri instance using
+   * UriBuilder.fromPath(String).build(String)
+   */
+  @Test
+  public void buildTest1() throws Fault {
+    String value = "test1#test2";
+    String expected_value = "test1%23test2";
+
+    try {
+      uri = UriBuilder.fromPath("{arg1}").build(value);
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:177;
+   * 
+   * @test_Strategy: Create an Uri instance using
+   * UriBuilder.fromPath(String).build(null); Verify that
+   * IllegalArgumentException is thrown.
+   */
+  @Test
+  public void buildTest2() throws Fault {
+    String value = null;
+
+    try {
+      UriBuilder.fromPath("{arg1}").build(value);
+      pass = false;
+      sb.append("Expected IllegalArgumentException not thrown" + newline);
+
+    } catch (IllegalArgumentException ilex) {
+      sb.append("Expected IllegalArgumentException thrown");
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fragmentTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:189; JAXRS:JAVADOC:190;
+   * 
+   * @test_Strategy: Create an Uri instance using
+   * UriBuilder.fromPath(String).fragment(String).build()
+   */
+  @Test
+  public void fragmentTest1() throws Fault {
+    String expected_value = "test#xyz";
+
+    try {
+      uri = UriBuilder.fromPath("test").fragment("xyz").build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromMapTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:185;
+   * 
+   * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+   * Verify % is encoded; and all parameter are replaced by values supplied in
+   * Map.
+   */
+  @Test
+  public void buildFromMapTest1() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/%25test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+
+    try {
+      uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+          .buildFromMap(maps);
+      gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromMapTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:185;
+   * 
+   * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+   * Verify % is encoded; and all parameter are replaced by values supplied in
+   * Map.
+   */
+  @Test
+  public void buildFromMapTest2() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/%25test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+          .buildFromMap(maps);
+      gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+
+  /*
+   * @testName: buildFromMapTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:185;
+   * 
+   * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+   * Verify IllegalArgumentException is thrown when one parameter value is null.
+   */
+  @Test
+  public void buildFromMapTest3() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", null);
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}").buildFromMap(maps);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ex) {
+      TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+    }
+  }
+
+  /*
+   * @testName: buildFromMapTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:185;
+   * 
+   * @test_Strategy: Create an URI instance using UriBuilder.buildFromMap(Map);
+   * Verify IllegalArgumentException is thrown when one parameter value is null.
+   */
+  @Test
+  public void buildFromMapTest4() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      UriBuilder.fromPath("").path("{w}/{v}/{x}/{y}/{z}/{x}")
+          .buildFromMap(maps);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ex) {
+      TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+    }
+  }
+
+  /*
+   * @testName: buildFromMapTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:185;
+   * 
+   * @test_Strategy: Create multiple URI instances from the same UriBuilder
+   * instance using the UriBuilder.buildFromMap(Map); Verify that the builder is
+   * not affected.
+   */
+  @Test
+  public void buildFromMapTest5() throws Fault {
+    UriBuilder ub;
+
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/%25test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+
+    Map<String, String> maps1 = new HashMap<String, String>();
+    maps1.put("x", "x%20yz");
+    maps1.put("y", "/path-absolute/test1");
+    maps1.put("z", "fred@example.com");
+    maps1.put("w", "path-rootless/test2");
+
+    Map<String, String> maps2 = new HashMap<String, String>();
+    maps2.put("x", "x%yz");
+    maps2.put("y", "/path-absolute/%25test1");
+    maps2.put("z", "fred@example.com");
+    maps2.put("w", "path-rootless/test2");
+    maps2.put("v", "xyz");
+
+    String expected_path_1 = "path-rootless%2Ftest2/x%2520yz/%2Fpath-absolute%2Ftest1/fred@example.com/x%2520yz";
+
+    try {
+      ub = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+
+      uri = ub.buildFromMap(maps);
+      gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+
+      uri = ub.buildFromMap(maps1);
+      gotExpectedPass(uri.getRawPath(), expected_path_1);
+
+      uri = ub.buildFromMap(maps2);
+      gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    } catch (Throwable ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromEncodedMapTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:182;
+   * 
+   * @test_Strategy: Create an URI instance using
+   * UriBuilder.buildFromEncodedMap(Map); Verify % is encoded when needed; and
+   * all parameter are replaced by values supplied in Map.
+   */
+  @Test
+  public void buildFromEncodedMapTest1() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%20yz");
+    maps.put("y", "/path-absolute/%test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+
+    String expected_path = "path-rootless/test2/x%20yz//path-absolute/%25test1/fred@example.com/x%20yz";
+
+    try {
+      uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncodedMap(maps);
+      gotExpectedPass(uri.getRawPath(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromEncodedMapTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:182;
+   * 
+   * @test_Strategy: Create an URI instance using
+   * UriBuilder.buildFromEncodedMap(Map); Verify % is encoded; and all parameter
+   * are replaced by values supplied in Map.
+   */
+  @Test
+  public void buildFromEncodedMapTest2() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      uri = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncodedMap(maps);
+      gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromEncodedMapTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:183;
+   * 
+   * @test_Strategy: Create an URI instance using
+   * UriBuilder.buildFromEncodedMap(Map); Verify IllegalArgumentException is
+   * thrown when one parameter value is null.
+   */
+  @Test
+  public void buildFromEncodedMapTest3() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", null);
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncodedMap(maps);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ex) {
+      TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+    }
+  }
+
+  /*
+   * @testName: buildFromEncodedMapTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:183;
+   * 
+   * @test_Strategy: Create an URI instance using
+   * UriBuilder.buildFromEncodedMap(Map); Verify IllegalArgumentException is
+   * thrown when one parameter value is null.
+   */
+  @Test
+  public void buildFromEncodedMapTest4() throws Fault {
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+    maps.put("u", "extra");
+
+    try {
+      UriBuilder.fromPath("").path("{w}/{v}/{x}/{y}/{z}/{x}")
+          .buildFromEncodedMap(maps);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ex) {
+      TestUtil.logTrace("Test passed: expected TestUtil.logTrace( thrown");
+    }
+  }
+
+  /*
+   * @testName: buildFromEncodedMapTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:182;
+   * 
+   * @test_Strategy: Create multiple URI instances from the same UriBuilder
+   * instance using the UriBuilder.buildFromEncodedMap(Map); Verify that the
+   * builder is not affected.
+   */
+  @Test
+  public void buildFromEncodedMapTest5() throws Fault {
+    UriBuilder ub;
+
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+
+    Map<String, String> maps1 = new HashMap<String, String>();
+    maps1.put("x", "x%20yz");
+    maps1.put("y", "/path-absolute/test1");
+    maps1.put("z", "fred@example.com");
+    maps1.put("w", "path-rootless/test2");
+
+    Map<String, String> maps2 = new HashMap<String, String>();
+    maps2.put("x", "x%yz");
+    maps2.put("y", "/path-absolute/test1");
+    maps2.put("z", "fred@example.com");
+    maps2.put("w", "path-rootless/test2");
+    maps2.put("v", "xyz");
+
+    String expected_path_1 = "path-rootless/test2/x%20yz//path-absolute/test1/fred@example.com/x%20yz";
+
+    try {
+      ub = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+
+      uri = ub.buildFromEncodedMap(maps);
+      gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+
+      uri = ub.buildFromEncodedMap(maps1);
+      gotExpectedPass(uri.getRawPath(), expected_path_1);
+
+      uri = ub.buildFromEncodedMap(maps2);
+      gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+    } catch (Throwable ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage() + newline);
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fromPathTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String)
+   */
+  @Test
+  public void fromPathTest1() throws Fault {
+    String[] paths = { "/", "", "/path-absolute/test1", "fred@example.com",
+        "path-rootless/test2" };
+
+    int j = 0;
+    while (j < paths.length) {
+      try {
+        uri = UriBuilder.fromPath(paths[j]).build();
+        gotExpectedPass(uri.getPath(), paths[j]);
+      } catch (Exception ex) {
+        pass = false;
+        sb.append("Unexpected exception thrown: " + ex.getMessage());
+      }
+      j++;
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fromPathTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:191;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(null) Verify that IllegalArgumentException is thrown.
+   */
+  @Test
+  public void fromPathTest2() throws Fault {
+    String path = null;
+
+    try {
+      UriBuilder.fromPath(path);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ilex) {
+    }
+  }
+
+  /*
+   * @testName: fromResourceTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:192;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromResource(null) Verify that IllegalArgumentException is
+   * thrown.
+   */
+  @Test
+  public void fromResourceTest1() throws Fault {
+    Class<?> res = null;
+
+    try {
+      UriBuilder.fromResource(res);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ilex) {
+    }
+  }
+
+  /*
+   * @testName: fromResourceTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:192;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromResource(Class) Verify that Uri can be built from it with
+   * correct path.
+   */
+  @Test
+  public void fromResourceTest2() throws Fault {
+    Class<?> res = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String expected_path = "/TestPath";
+
+    try {
+      uri = UriBuilder.fromResource(res).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fromUriTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:194;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri((URI)null) Verify that IllegalArgumentException is
+   * thrown.
+   */
+  @Test
+  public void fromUriTest1() throws Fault {
+    try {
+      UriBuilder.fromUri(uri);
+
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ilex) {
+    }
+  }
+
+  /*
+   * @testName: fromUriTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:196;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri((String)null) Verify that IllegalArgumentException is
+   * thrown.
+   */
+  @Test
+  public void fromUriTest2() throws Fault {
+    String uri = null;
+
+    try {
+      UriBuilder.fromUri(uri);
+      throw new Fault(
+          "Test Failed: expected IllegalArgumentException not thrown");
+    } catch (IllegalArgumentException ilex) {
+    }
+  }
+
+  /*
+   * @testName: fromUriTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:196;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri(String)
+   */
+  @Test
+  public void fromUriTest3() throws Fault {
+    String[] uris = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+        "mailto:java-net@java.sun.com", "news:comp.lang.java",
+        "urn:isbn:096139210x", "http://www.ietf.org/rfc/rfc2396.txt",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+        "telnet://192.0.2.16:80/",
+        "foo://example.com:8042/over/there?name=ferret#nose" };
+
+    int j = 0;
+    while (j < 9) {
+      try {
+        uri = UriBuilder.fromUri(uris[j]).build();
+        gotExpectedPass(uri.toString().trim(), uris[j]);
+      } catch (Exception ex) {
+        pass = false;
+        sb.append("Unexpected exception thrown: " + ex.getMessage());
+      }
+      j++;
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fromUriTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:194;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using UriBuilder.fromUri(URI)
+   */
+  @Test
+  public void fromUriTest4() throws Fault {
+    String[] uris = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+        "mailto:java-net@java.sun.com", "news:comp.lang.java",
+        "urn:isbn:096139210x", "http://www.ietf.org/rfc/rfc2396.txt",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+        "telnet://192.0.2.16:80/",
+        "foo://example.com:8042/over/there?name=ferret#nose" };
+
+    int j = 0;
+    while (j < 9) {
+      try {
+        uri = UriBuilder.fromUri(new URI(uris[j])).build();
+        gotExpectedPass(uri.toString().trim(), uris[j]);
+      } catch (Exception ex) {
+        pass = false;
+        sb.append("Unexpected exception thrown: " + ex.getMessage());
+      }
+      j++;
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:202;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path("/TestPath"), Verify that "/TestPath" is
+   * appended as specified
+   */
+  @Test
+  public void pathTest() throws Fault {
+    String path = "test1#test2";
+    String path1 = "/TestPath";
+    String expected_path = "test1%23test2/TestPath";
+
+    try {
+      URI uri = UriBuilder.fromPath(path).path(path1).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest0
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:202;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path("TestPath"), Verify that "TestPath" is
+   * appended as specified
+   */
+  @Test
+  public void pathTest0() throws Fault {
+    String path = "test1#test2";
+    String path1 = "TestPath";
+    String expected_path = "test1%23test2/TestPath";
+
+    try {
+      URI uri = UriBuilder.fromPath(path).path(path1).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:202;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(String null), Verify that
+   * IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest1() throws Fault {
+    String path = "test1#test2";
+    String path1 = null;
+
+    try {
+      UriBuilder.fromPath(path).path(path1);
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:204;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(Class TestPath), TestPath is annonated
+   * with @Path, Verify that TestPath is appended as specified
+   */
+  @Test
+  public void pathTest2() throws Fault {
+    String path = "test1#test2";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String expected_path = "test1%23test2/TestPath";
+
+    try {
+      uri = UriBuilder.fromPath(path).path(path1).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:204;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(Class null), Verify that
+   * IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest3() throws Fault {
+    String path = "test1#test2";
+    Class<?> path1 = null;
+
+    try {
+      UriBuilder.fromPath(path).path(path1);
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:204;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(Class TestPathBad), TestPathBad is not
+   * annonated with @Path, Verify that IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest4() throws Fault {
+    String path = "test1#test2";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPathBad.class;
+
+    try {
+      UriBuilder.fromPath(path).path(path1);
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:206;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Class TestPath, String "headSub"),
+   * Verify that "/sub" is appended as specified
+   */
+  @Test
+  public void pathTest5() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String md = "headSub";
+    String expected_path = "/TestPath/sub";
+
+    try {
+      uri = UriBuilder.fromPath(path).path(path1, md).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest6
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:206;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Class TestPath, String "getPlain"),
+   * Verify that IllegalArgumentException is thrown since Method getPlain is not
+   * annonated with @Path
+   */
+  @Test
+  public void pathTest6() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String md = "getPlain";
+
+    try {
+      UriBuilder.fromPath(path).path(path1, md).build();
+      throw new Fault(
+          "Test failed, expected IllegalArgumentException not thrown."
+              + newline);
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest7
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:206;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Class TestPath, null), Verify that
+   * IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest7() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String md = null;
+
+    try {
+      UriBuilder.fromPath(path).path(path1, md).build();
+      throw new Fault(
+          "Test failed, expected IllegalArgumentException not thrown."
+              + newline);
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest8
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:206;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Class null, "headSub"), Verify that
+   * IllegalArgumentException is thrown since Method getPlan is not annonated
+   * with @Path
+   */
+  @Test
+  public void pathTest8() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = null;
+    String md = "headSub";
+
+    try {
+      UriBuilder.fromPath(path).path(path1, md).build();
+      throw new Fault(
+          "Test failed, expected IllegalArgumentException not thrown."
+              + newline);
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest9
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:206;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(TestPath,"test1"), Verify that
+   * IllegalArgumentException is thrown, since there are two methods annotated
+   * with @Path in TestPath
+   */
+  @Test
+  public void pathTest9() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String md = "test1";
+
+    try {
+      UriBuilder.fromPath(path).path(path1, md).build();
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest10
+   *
+   * @assertion_ids: JAXRS:JAVADOC:208;
+   *
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Method headSub), Verify that "/sub"
+   * is appended as specified
+   */
+  @Test
+  public void pathTest10() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String expected_path = "/TestPath/sub";
+
+    try {
+      Method md = path1.getMethod("headSub", new Class[] {});
+      URI uri = UriBuilder.fromPath(path).path(md).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest11
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:208;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").path(Method headSub), Verify that "/sub1"
+   * is appended as specified
+   */
+  @Test
+  public void pathTest11() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+    String expected_path = "/TestPath/sub1";
+
+    try {
+      Method md = path1.getMethod("test1", new Class[] {});
+      URI uri = UriBuilder.fromPath(path).path(md).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: pathTest12
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:208;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(Method getPlain), Verify that
+   * IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest12() throws Fault {
+    String path = "/TestPath";
+    Class<?> path1 = jakarta.ws.rs.tck.api.rs.core.uribuilder.TestPath.class;
+
+    try {
+      Method md = path1.getMethod("getPlain", new Class[] {});
+      UriBuilder.fromPath(path).path(md).build();
+
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    } catch (NoSuchMethodException ex) {
+      throw new Fault(
+          "Test Failed.  Unexpected exception thrown: " + ex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: pathTest13
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:208;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String).path(Method null), Verify that
+   * IllegalArgumentException is thrown
+   */
+  @Test
+  public void pathTest13() throws Fault {
+    String path = "test1#test2";
+    java.lang.reflect.Method path1 = null;
+
+    try {
+      UriBuilder.fromPath(path).path(path1);
+      throw new Fault(
+          "Test Failed.  Expected IllegalArgumentException not thrown.");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace(
+          "Expected IllegalArgumentException thrown: " + ilex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: replacePathTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:218;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").replacePath(String newPath), Verify that
+   * path is updated as specified
+   */
+  @Test
+  public void replacePathTest1() throws Fault {
+    String path = "/TestPath";
+    String new_path = "/TestPathAgain";
+
+    try {
+      URI uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+      gotExpectedPass(uri.toString(), new_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replacePathTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:218;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath1/TestPath2").replacePath(String null),
+   * Verify that all existing path cleared as specified
+   */
+  @Test
+  public void replacePathTest2() throws Fault {
+    String path = "/TestPath1/TestPath2";
+    String new_path = null;
+
+    try {
+      URI uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+      boolean conditionTrue = uri.toString() == null
+          || uri.toString().trim().compareTo("") == 0;
+      gotExpectedPass(!conditionTrue, uri.toString(), new_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replacePathTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:218;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("TestPath").replacePath(String newPath), Verify that
+   * all existing path cleared as specified
+   */
+  @Test
+  public void replacePathTest3() throws Fault {
+    String path = "TestPath";
+    String new_path = null;
+
+    try {
+      uri = UriBuilder.fromPath(path).replacePath(new_path).build();
+      boolean conditionTrue = uri.toString() == null
+          || uri.toString().trim().compareTo("") == 0;
+      gotExpectedPass(!conditionTrue, uri.toString(), new_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: portTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:210;
+   * 
+   * @test_Strategy: Call UriBuilder.port(int), Veify that port number updated
+   * accordingly.
+   */
+  @Test
+  public void portTest1() throws Fault {
+    String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+    String uri_string_expected = "foo://example.com:2008/over/there?name=ferret#nose";
+    int port = 2008;
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).port(port).build();
+      gotExpectedPass(uri.toString().trim(), uri_string_expected);
+    } catch (Exception ex) {
+      throw new Fault("Test Failed: unexpected Exception thrown", ex);
+    }
+  }
+
+  /*
+   * @testName: portTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:210;
+   * 
+   * @test_Strategy: Call UriBuilder.port(int) with an invalid port number;
+   * Verify that IllegalArgumentException is thrown.
+   */
+  @Test
+  public void portTest2() throws Fault {
+    String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+    int port = -10;
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).port(port).build();
+      throw new Fault(
+          "Test failed, expected IllegalArgumentException not thrown."
+              + "Got uri=" + uri.toString() + " instead.");
+    } catch (IllegalArgumentException ex) {
+      TestUtil
+          .logTrace("Test Passed: expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: hostTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:198;
+   * 
+   * @test_Strategy: Call UriBuilder.host(String), verify that hostame updated
+   * accordingly
+   */
+  @Test
+  public void hostTest1() throws Fault {
+    String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+    String uri_string_1 = "foo://java.net:8042/over/there?name=ferret#nose";
+    String host = "java.net";
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).host(host).build();
+      gotExpectedPass(uri.toString().trim(), uri_string_1);
+    } catch (Exception ex) {
+      throw new Fault("Test Failed: unexpected Exception thrown", ex);
+    }
+  }
+
+  /*
+   * @testName: hostTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:198;
+   * 
+   * @test_Strategy: Call UriBuilder.host(hostname) with incorrect hstname,
+   * verify that IllegalArgumentException is thrown.
+   */
+  @Test
+  public void hostTest2() throws Fault {
+    String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+    String host = "";
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).host(host).build();
+      throw new Fault(
+          "Test failed, expected IllegalArgumentException not thrown."
+              + "Got uri=" + uri.toString() + " instead.");
+    } catch (IllegalArgumentException ex) {
+      TestUtil
+          .logTrace("Test Passed: expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: schemeTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:196; JAXRS:JAVADOC:223;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri(String)
+   */
+  @Test
+  public void schemeTest1() throws Fault {
+    String uri_string = "foo://example.com:8042/over/there?name=ferret#nose";
+    String uri_string_1 = "http://example.com:8042/over/there?name=ferret#nose";
+    String scheme = "http";
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).scheme(scheme).build();
+      gotExpectedPass(uri.toString().trim(), uri_string_1);
+    } catch (Exception ex) {
+      throw new Fault("Test Failed: unexpected Exception thrown", ex);
+    }
+  }
+
+  /*
+   * @testName: schemeTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:223;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri(null); Verify that scheme is cleared.
+   */
+  @Test
+  public void schemeTest2() throws Fault {
+    String uri_string = "http://example.com:8042/over/there?name=ferret#nose";
+    String scheme = null;
+
+    try {
+      uri = UriBuilder.fromUri(uri_string).scheme(scheme).build();
+      assertTrue(uri.getRawSchemeSpecificPart() == null,
+          "scheme not cleared as expected, got"+ uri.getSchemeSpecificPart());
+    } catch (Throwable ex) {
+      TestUtil.logTrace(
+          "Unexpected Exception thrown. Test Failed." + ex.getMessage());
+    }
+  }
+
+  /*
+   * @testName: schemeSpecificPartTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:225;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri(String); Call method schemeSpecificPart(String) Verify
+   * the method works.
+   */
+  @Test
+  public void schemeSpecificPartTest() throws Fault {
+    String uri_1 = "http://example.com:8042/uber/here?name=ferret#nose";
+    String uri_2 = "//example1.com:8041/over/there?name=monkey";
+    String uri_3 = "http://example1.com:8041/over/there?name=monkey#nose";
+
+    try {
+      uri = UriBuilder.fromUri(uri_1).schemeSpecificPart(uri_2).build();
+      gotExpectedPass(uri.toString().trim(), uri_3);
+    } catch (Exception ex) {
+      throw new Fault("Test Failed: unexpected Exception thrown", ex);
+    }
+  }
+
+  /*
+   * @testName: schemeSpecificPartTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:225;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromUri(String); Call method schemeSpecificPart(null) Verify
+   * that IllegalArgumentException is thrown.
+   */
+  @Test
+  public void schemeSpecificPartTest1() throws Fault {
+    String uri_1 = "http://example.com:8042/uber/here?name=ferret#nose";
+    String uri_2 = null;
+
+    try {
+      UriBuilder.fromUri(uri_1).schemeSpecificPart(uri_2).build();
+      sb.append(
+          "Test Failed: expected IllegalArgumentException Exception not thrown.");
+      pass = false;
+    } catch (IllegalArgumentException ex) {
+      sb.append("Expected IllegalArgumentException thrown. Test PASSED.");
+    } catch (Exception ex) {
+      sb.append("Test Failed: wrong Exception thrown" + ex.getMessage());
+      pass = false;
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: templateTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:189; JAXRS:JAVADOC:190;
+   * 
+   * @test_Strategy: Create an Uri instance using
+   * UriBuilder.fromPath(String).fragment(String).build(String)
+   */
+  @Test
+  public void templateTest1() throws Fault {
+    String expected_value = "test#xyz";
+
+    try {
+      uri = UriBuilder.fromPath("{arg1}").fragment("{arg2}").build("test",
+          "xyz");
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: templateTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:190;
+   * 
+   * @test_Strategy: Create an Uri instance using
+   * UriBuilder.fromPath(String).build(String)
+   */
+  @Test
+  public void templateTest2() throws Fault {
+    String expected_value = "test1/test2/test1";
+
+    try {
+      uri = UriBuilder.fromPath("{arg1}/{arg2}/{arg1}").build("test1", "test2",
+          "test3");
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: uriTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:176; JAXRS:JAVADOC:194; JAXRS:JAVADOC:229;
+   * 
+   * @test_Strategy: Create a set of UriBuilder instances with diffeent schemes;
+   * using UriBuilder instances using UriBuilder.fromUri(URI) Call uri(URI)
+   * method on all instances; verify it works correctly on all of the instances.
+   */
+  @Test
+  public void uriTest() throws Fault {
+    String[] uris_orig = getOrigUris();
+    URI uris_replace[] = getReplacementUris();
+    String[] uris_expect = getExpectedUris();
+
+    int j = 0;
+    int i = 0;
+    int k = 0;
+    while (j < 17) {
+      try {
+        sb.append("Replace uri with ").append(uris_replace[j]).append(newline);
+        uri = UriBuilder.fromUri(new URI(uris_orig[j])).uri(uris_replace[j])
+            .build();
+        if (gotExpectedPass(uri.toString().trim(), uris_expect[j]) != 0)
+          i++;
+        else
+          k++;
+      } catch (Exception ex) {
+        pass = false;
+        sb.append("Unexpected exception thrown: ").append(ex.getMessage())
+            .append(newline);
+        sb.append("Test failed with exception for expected uri: ")
+            .append(uris_expect[j]).append(newline);
+      }
+      j++;
+    }
+
+    assertTrue(pass, k+ "assertion passed."+ newline+ i+ "assertion(s) failed:"+
+        sb.toString()+ newline);
+    logMsg(sb);
+  }
+
+  /*
+   * @testName: uriTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:229;
+   * 
+   * @test_Strategy: Calling UriBuilder.uri(URI null) verify the
+   * IllegalStateException thrown..
+   */
+  @Test
+  public void uriTest1() throws Fault {
+    try {
+      UriBuilder.fromPath("/").uri(uri);
+      throw new Fault("Expected IllegalArgumentException not thrown" + newline);
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: fromEncodedTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:179;
+   * 
+   * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+   * Object.toString() is encoded.
+   */
+  @Test
+  public void fromEncodedTest1() throws Fault {
+    String expected_value_1 = "http://localhost:8080/a/%25/=/%25G0/%25/=";
+    String expected_value_2 = "http://localhost:8080/xy/%20/%25/xy";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncoded("a", "%25", "=", "%G0", "%", "23");
+      gotExpectedPass(uri.toString(), expected_value_1);
+
+      uri = UriBuilder.fromPath(LOCALHOST).path("/{x}/{y}/{z}/{x}")
+          .buildFromEncoded("xy", " ", "%");
+      gotExpectedPass(uri.toString(), expected_value_2);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: fromEncodedTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:180;
+   * 
+   * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+   * IllegalArgumentException is thrown when one template is missing its value
+   */
+  @Test
+  public void fromEncodedTest2() throws Fault {
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncoded("a", "%25", "=", "%G0");
+      throw new Fault("Expected IllegalArgumentException Not thrown. uri ="
+          + uri.toString());
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: fromEncodedTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:180;
+   * 
+   * @test_Strategy: Calling UriBuilder.buildFromEncoded(Object...). verify
+   * IllegalArgumentException is thrown when one value is null.
+   */
+  @Test
+  public void fromEncodedTest3() throws Fault {
+    try {
+      UriBuilder.fromPath(LOCALHOST).path("/{v}/{w}/{x}/{y}/{z}/{x}")
+          .buildFromEncoded("a", "%25", null, "%G0");
+      throw new Fault("Expected IllegalArgumentException Not thrown");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: queryParamTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:212;
+   * 
+   * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+   * value). verify IllegalArgumentException is thrown when name is null.
+   */
+  @Test
+  public void queryParamTest1() throws Fault {
+    String name = null;
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", "y");
+      throw new Fault("Expected IllegalArgumentException Not thrown");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: queryParamTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:212;
+   * 
+   * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+   * value). verify IllegalArgumentException is thrown when values is null.
+   */
+  @Test
+  public void queryParamTest2() throws Fault {
+    String name = "name";
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).queryParam(name, (Object) null);
+      throw new Fault("Expected IllegalArgumentException Not thrown");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: queryParamTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:212;
+   * 
+   * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+   * value). verify IllegalArgumentException is thrown when one of values is
+   * null.
+   */
+  @Test
+  public void queryParamTest3() throws Fault {
+    String name = "name";
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", null);
+      throw new Fault("Expected IllegalArgumentException Not thrown");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: queryParamTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:212;
+   * 
+   * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+   * value). verify that when two values are supplied, both are present in final
+   * URI.
+   */
+  @Test
+  public void queryParamTest4() throws Fault {
+    String name = "name";
+    String expected_value = "http://localhost:8080?name=x&name=y";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", "y").build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: queryParamTest5
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:212;
+   * 
+   * @test_Strategy: Calling UriBuilder.queryParam(String name, Object...
+   * value). verify that values are encoded properly in final URI.
+   */
+  @Test
+  public void queryParamTest5() throws Fault {
+    String name = "name";
+    String actual = null;
+    String expected_value = "http://localhost:8080?name=x%3D&name=y?&name=x+y&name=%26";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&").build();
+      actual = uri.toString().replace("%3F", "?").replace("%3f", "?");
+      gotExpectedPass(actual, expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceQueryTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:219;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQuery(String name). verify that
+   * query is replaced properly in final URI.
+   */
+  @Test
+  public void replaceQueryTest1() throws Fault {
+    String name = "name";
+    String expected_value = "http://localhost:8080?name1=xyz";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&").replaceQuery("name1=xyz")
+          .build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceQueryTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:219;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQuery(String null). verify that
+   * query is cleared properly in final URI.
+   */
+  @Test
+  public void replaceQueryTest2() throws Fault {
+    String name = "name";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&").replaceQuery(null).build();
+      gotExpectedPass(uri.toString(), LOCALHOST);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceQueryTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:219;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQuery(String query). verify that
+   * query is replaced properly in final URI.
+   */
+  @Test
+  public void replaceQueryTest3() throws Fault {
+    String name = "name";
+    String expected_value = "http://localhost:8080?name1=x&name2=%20&name3=x+y&name4=23&name5=x%20y";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&")
+          .replaceQuery("name1=x&name2=%20&name3=x+y&name4=23&name5=x y")
+          .build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * testName: replaceQueryTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:219;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQuery(String query). verify that
+   * IllegalArgumentException is thrown when query cannot be parsed.
+   */
+  @Test
+  public void replaceQueryTest4() throws Fault {
+    String value = "http://localhost:8080?name1=x&name2=%20&name3=x+y&name4=x%20y";
+
+    try {
+      uri = UriBuilder.fromPath(value)
+          .replaceQuery("name$*()^@!+-]}[{|<>,./:;'#1==x?&name2=%20y").build();
+      pass = false;
+      sb.append("Expected IllegalArgumentException not thrown");
+      sb.append("uri=" + uri.getQuery());
+    } catch (IllegalArgumentException ex) {
+      sb.append("Expected IllegalArgumentException thrown");
+    } catch (Exception ex1) {
+      pass = false;
+      sb.append("Wrong type Exception thrown" + ex1.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceQueryParamTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:221;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQueryParam(String null, Object...
+   * value). verify IllegalArgumentException is thrown
+   */
+  @Test
+  public void replaceQueryParamTest1() throws Fault {
+    String name = null;
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).queryParam(name, "x", null);
+      throw new Fault("Expected IllegalArgumentException Not thrown");
+    } catch (IllegalArgumentException ilex) {
+      TestUtil.logTrace("Expected IllegalArgumentException thrown");
+    }
+  }
+
+  /*
+   * @testName: replaceQueryParamTest2
+   *
+   * @assertion_ids: JAXRS:JAVADOC:221;
+   *
+   * @test_Strategy: Calling UriBuilder.replaceQueryParam(String name, Object...
+   * value). verify all query params are cleared when values is null.
+   */
+  @Test
+  public void replaceQueryParamTest2() throws Fault {
+    String name = "name";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&")
+          .replaceQueryParam(name, (Object[]) null).build();
+      gotExpectedPass(uri.toString(), LOCALHOST);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceQueryParamTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:221;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceQueryParam(String name, Object...
+   * value). verify that query parameter is updated accordingly
+   */
+  @Test
+  public void replaceQueryParamTest3() throws Fault {
+    String name = "name";
+    String expected_value = "http://localhost:8080?name=x&name=y&name=y+x&name=x%25y&name=%20";
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .queryParam(name, "x=", "y?", "x y", "&")
+          .replaceQueryParam(name, "x", "y", "y x", "x%y", "%20").build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: segmentTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:227;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify
+   * IllegalArgumentException if any element of paths is null
+   */
+  @Test
+  public void segmentTest1() throws Fault {
+    String path = null;
+
+    try {
+      UriBuilder.fromPath("/").segment(path).build();
+      throw new Fault(
+          "TestFailed: expected IllegalArgumentException not thrown.");
+
+    } catch (IllegalArgumentException ex) {
+      TestUtil
+          .logTrace("Test Passed: Expected IllegalArgumentException thrown.");
+    }
+  }
+
+  /*
+   * @testName: segmentTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:227;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify "/" is
+   * added when needed and characters are encoded as needed.
+   */
+  @Test
+  public void segmentTest2() throws Fault {
+    String path1 = "";
+    String[] path2 = { "a1", "/", "3b " };
+    String expected_path = "a1/%2F/3b%20";
+
+    try {
+      uri = UriBuilder.fromPath(path1).segment(path2).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: segmentTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:227;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath("/TestPath").segment(String[] paths), Verify that a
+   * single value is only a single URI path segment. and characters are encoded
+   * as needed.
+   */
+  @Test
+  public void segmentTest3() throws Fault {
+    String path1 = "ab";
+    String[] path2 = { "a1", "x/y", "3b " };
+    String expected_path = "ab/a1/x%2Fy/3b%20";
+
+    try {
+      uri = UriBuilder.fromPath(path1).segment(path2).build();
+      gotExpectedPass(uri.toString(), expected_path);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: uriBuilderExceptionTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:232;
+   * 
+   * @test_Strategy: Create an UriBuilderException instance using
+   * UriBuilderException(). Verify that empty message is associated with the
+   * exception.
+   */
+  @Test
+  public void uriBuilderExceptionTest1() throws Fault {
+    try {
+      throw new UriBuilderException();
+    } catch (UriBuilderException ube) {
+      if (ube.getMessage() == "" || ube.getMessage() == null) {
+        TestUtil.logTrace(
+            "Test Passed with empty message: " + ube.getMessage() + ".");
+      } else {
+        throw new Fault("Test Failed.  Expecting empty message," + " Got "
+            + ube.getMessage());
+      }
+    }
+  }
+
+  /*
+   * @testName: uriBuilderExceptionTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:233;
+   * 
+   * @test_Strategy: Create an UriBuilderException instance using
+   * UriBuilderException(String msg). Verify that message msg is associated with
+   * the exception.
+   */
+  @Test
+  public void uriBuilderExceptionTest2() throws Fault {
+    String msg = "JAX-RS Test Message: xyz";
+
+    try {
+      throw new UriBuilderException(msg);
+    } catch (UriBuilderException ube) {
+      if (msg.equals(ube.getMessage())) {
+        TestUtil.logTrace(
+            "Test Passed with correct message: " + ube.getMessage() + ".");
+      } else {
+        throw new Fault("Test Failed.  Expecting message," + msg + ", got "
+            + ube.getMessage() + ".");
+      }
+    }
+  }
+
+  /*
+   * @testName: uriBuilderExceptionTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:234;
+   * 
+   * @test_Strategy: Create an UriBuilderException instance using
+   * UriBuilderException(String msg, throwable ex). Verify that message msg is
+   * associated with the exception.
+   */
+  @Test
+  public void uriBuilderExceptionTest3() throws Fault {
+    String msg = "JAX-RS Test Message: xyz";
+    String msg1 = "JAX-RS Test Message Again: xyz";
+
+    try {
+      throw new UriBuilderException(msg, new Exception(msg1));
+    } catch (UriBuilderException ube) {
+      if (ube.getMessage().contains(msg)) {
+        TestUtil.logTrace(
+            "Test Passed with correct message: " + ube.getMessage() + ".");
+      } else {
+        throw new Fault("Test Failed.  Expecting message," + msg + ", got "
+            + ube.getMessage() + ".");
+      }
+    }
+  }
+
+  /*
+   * @testName: uriBuilderExceptionTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:235;
+   * 
+   * @test_Strategy: Create an UriBuilderException instance using
+   * UriBuilderException(String msg, throwable ex). Verify that message msg is
+   * associated with the exception.
+   */
+  @Test
+  public void uriBuilderExceptionTest4() throws Fault {
+    String msg = "JAX-RS Test Message Again: xyz";
+
+    try {
+      throw new UriBuilderException(new Exception(msg));
+    } catch (UriBuilderException ube) {
+      if (ube.getMessage().contains(msg)) {
+        TestUtil.logTrace(
+            "Test Passed with correct message: " + ube.getMessage() + ".");
+      } else {
+        throw new Fault("Test Failed.  Expecting message," + msg + ", got "
+            + ube.getMessage() + ".");
+      }
+    }
+  }
+
+  /*
+   * @testName: cloneTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:188;
+   * 
+   * @test_Strategy: Create an UriBuilder instance using
+   * UriBuilder.fromPath(String); Create another UriBuilder instance using
+   * UriBuilder.clone(); Verify that both are created correctly.
+   */
+  @Test
+  public void cloneTest1() throws Fault {
+    UriBuilder ub, ub1;
+    URI uri1;
+    String path1 = "test";
+    String frag = "xyz";
+    String expected_path_1 = "test#xyz";
+
+    Map<String, String> maps = new HashMap<String, String>();
+    maps.put("x", "x%yz");
+    maps.put("y", "/path-absolute/%25test1");
+    maps.put("z", "fred@example.com");
+    maps.put("w", "path-rootless/test2");
+
+    String expected_path_2 = "test/" + ENCODED_EXPECTED_PATH + "#xyz";
+
+    try {
+      ub = UriBuilder.fromPath(path1).fragment(frag);
+      ub1 = ub.clone();
+      uri = ub.build();
+      gotExpectedPass(uri.toString(), expected_path_1);
+
+      uri1 = ub1.path("{w}/{x}/{y}/{z}/{x}").buildFromMap(maps);
+      gotExpectedPass(uri1.toString(), expected_path_2);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: matrixParamTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:200;
+   * 
+   * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+   * value). verify IllegalArgumentException is thrown when name is null.
+   */
+  @Test
+  public void matrixParamTest1() throws Fault {
+    String name = null;
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x", "y");
+      sb.append("Expected IllegalArgumentException Not thrown");
+      pass = false;
+    } catch (IllegalArgumentException ilex) {
+      sb.append("Expected IllegalArgumentException thrown");
+    } catch (Throwable th) {
+      pass = false;
+      sb.append("Incorrect Exception thrown: " + th.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: matrixParamTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:200;
+   * 
+   * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+   * value). verify IllegalArgumentException is thrown when values is null.
+   */
+  @Test
+  public void matrixParamTest2() throws Fault {
+    String name = "name";
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).matrixParam(name, (Object) null);
+      sb.append("Expected IllegalArgumentException Not thrown");
+      pass = false;
+    } catch (IllegalArgumentException ilex) {
+      sb.append("Expected IllegalArgumentException thrown");
+    } catch (Throwable th) {
+      pass = false;
+      sb.append("Incorrect Exception thrown: " + th.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: matrixParamTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:200;
+   * 
+   * @test_Strategy: Calling UriBuilder.matrixParam(String name, Object...
+   * value). verify that when two values are supplied, both are present in final
+   * URI.
+   */
+  @Test
+  public void matrixParamTest3() throws Fault {
+    String name = "name";
+    String expected_value = "http://localhost:8080;name=x;name=y";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x", "y").build();
+      gotExpectedPass(uri.toString(), expected_value);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixParamTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:216;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+   * Object... value). verify IllegalArgumentException when name is null.
+   */
+  @Test
+  public void replaceMatrixParamTest1() throws Fault {
+    String name = "name";
+
+    try {
+      UriBuilder.fromPath(LOCALHOST).matrixParam(name, "x=", "y?", "x y", "&")
+          .replaceMatrixParam(null, "x", "y").build();
+      pass = false;
+      sb.append("Expected exception not thrown.");
+    } catch (IllegalArgumentException ex) {
+      sb.append("Expected exception thrown.");
+    } catch (Throwable th) {
+      pass = false;
+      sb.append("Wrong type of  Exception thrown" + th.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixParamTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:216;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+   * Object... value). verify all values are cleared when value is null.
+   */
+  @Test
+  public void replaceMatrixParamTest2() throws Fault {
+    String name = "name";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .matrixParam(name, "x=", "y?", "x y", "&").replaceMatrixParam(name)
+          .build();
+      gotExpectedPass(uri.toString(), LOCALHOST);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixParamTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:216;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+   * Object... value). verify that matrix parameter is updated accordingly
+   */
+  @Test
+  public void replaceMatrixParamTest3() throws Fault {
+    String name = "name";
+    String expected = "http://localhost:8080;name=x;name=y;name=y%20x;name=x%25y;name=%20";
+
+    try {
+      uri = UriBuilder
+          .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+          .replaceMatrixParam(name, "x", "y", "y x", "x%y", "%20").build();
+      gotExpectedPass(uri.toString(), expected);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixParamTest4
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:216;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrixParam(String name,
+   * Object... value). verify that matrix parameter is updated accordingly
+   */
+  @Test
+  public void replaceMatrixParamTest4() throws Fault {
+    String name = "name1";
+    String expected = "http://localhost:8080;name=x=;name=y%3F;name=x%20y;name=&;name1=x;name1=y;name1=y%20x;name1=x%25y;name1=%20";
+
+    try {
+      uri = UriBuilder
+          .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+          .replaceMatrixParam(name, "x", "y", "y x", "x%y", "%20").build();
+      gotExpectedPass(uri.toString(), expected);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:214;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify all
+   * values are cleared when value is null.
+   */
+  @Test
+  public void replaceMatrixTest1() throws Fault {
+    String name = "name";
+    String expected1 = "http://localhost:8080;";
+
+    try {
+      uri = UriBuilder.fromPath(LOCALHOST)
+          .matrixParam(name, "x=", "y?", "x y", "&").replaceMatrix(null)
+          .build();
+      String sUri = uri.toString();
+      boolean condition = sUri.compareToIgnoreCase(LOCALHOST) == 0
+          || sUri.compareToIgnoreCase(expected1) == 0;
+      gotExpectedPass(!condition, sUri, LOCALHOST);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:214;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify that
+   * Matrix parameter is updated accordingly
+   */
+  @Test
+  public void replaceMatrixTest2() throws Fault {
+    String expected = "http://localhost:8080;name=x;name=y;name=y%20x;name=x%25y;name=%20";
+    String value = "name=x;name=y;name=y x;name=x%y;name= ";
+
+    try {
+      uri = UriBuilder
+          .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+          .replaceMatrix(value).build();
+      gotExpectedPass(uri.toString(), expected);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: replaceMatrixTest3
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:214;
+   * 
+   * @test_Strategy: Calling UriBuilder.replaceMatrix(String value). verify that
+   * matrix parameter is updated accordingly
+   */
+  @Test
+  public void replaceMatrixTest3() throws Fault {
+    String expected = "http://localhost:8080;name1=x;name1=y;name1=y%20x;name1=x%25y;name1=%20";
+    String value = "name1=x;name1=y;name1=y x;name1=x%y;name1= ";
+
+    try {
+      uri = UriBuilder
+          .fromPath("http://localhost:8080;name=x=;name=y?;name=x y;name=&")
+          .replaceMatrix(value).build();
+      gotExpectedPass(uri.toString(), expected);
+    } catch (Exception ex) {
+      pass = false;
+      sb.append("Unexpected Exception thrown" + ex.getMessage());
+    }
+
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: userInfoTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:231;
+   * 
+   * @test_Strategy: call UriBuilder.userInfo in different states of UriBuilder
+   * Check the userInfo on built java.net.URI
+   */
+  @Test
+  public void userInfoTest() throws Fault {
+    String unexpected = "Unexpected user info:";
+    String userInfo = "foo:foo";
+
+    uri = UriBuilder.fromUri(LOCALHOST).build();
+    assertTrue(uri.getUserInfo() == null, unexpected+ uri.getUserInfo());
+
+    uri = UriBuilder.fromUri(LOCALHOST).userInfo(userInfo).build();
+    assertTrue(uri.getRawUserInfo().equals(userInfo), unexpected+
+        uri.getRawUserInfo());
+    System.out.println(uri.getRawUserInfo());
+
+    uri = UriBuilder.fromUri("http://foo2:foo2@localhost:8080")
+        .userInfo(userInfo).build();
+    System.out.println(uri.getRawUserInfo());
+    assertTrue(userInfo.equals(uri.getRawUserInfo()), unexpected+
+        uri.getRawUserInfo());
+
+    uri = UriBuilder.fromPath("").scheme("http").userInfo(userInfo)
+        .host("localhost").port(8080).build();
+    assertTrue(uri.getRawUserInfo().equals(userInfo), unexpected+
+        uri.getRawUserInfo());
+  }
+
+  /*
+   * @testName: buildObjectsBooleanEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:886;
+   * 
+   * @test_Strategy: Build a URI, using the supplied values in order to replace
+   * any URI template parameters. Values are converted to String using their
+   * toString() method and are then encoded to match the rules of the URI
+   * component to which they pertain. The slash ('/') characters in parameter
+   * values will be encoded if the template is placed in the URI path component.
+   */
+  @Test
+  public void buildObjectsBooleanEncodedTest() throws Fault {
+    Object s[] = { "path-rootless/test2", new StringBuilder("x%yz"),
+        "/path-absolute/%25test1", "fred@example.com" };
+    uri = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}")
+        .build(new Object[] { s[0], s[1], s[2], s[3], s[1] }, true);
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildObjectsBooleanNotEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:886;
+   * 
+   * @test_Strategy: Build a URI, using the supplied values in order to replace
+   * any URI template parameters. Values are converted to String using their
+   * toString() method and are then encoded to match the rules of the URI
+   * component to which they pertain.
+   */
+  @Test
+  public void buildObjectsBooleanNotEncodedTest() throws Fault {
+    Object s[] = { new StringBuffer("path-rootless/test2"), "x%yz",
+        "/path-absolute", "test1", "fred@example.com" };
+    uri = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{z}/{w}")
+        .build(new Object[] { s[0], s[1], s[2], s[3], s[4], s[1] }, false);
+    gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildObjectsBooleanThrowsIAEWhenNoValueSuppliedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:887;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if there are any URI
+   * template parameters without a supplied value
+   */
+  @Test
+  public void buildObjectsBooleanThrowsIAEWhenNoValueSuppliedTest()
+      throws Fault {
+    try {
+      uri = UriBuilder.fromPath("").path("{v}/{w}")
+          .build(new Object[] { "first" }, false);
+      fault("IllegalArgumentException has not been thrown, uri:", uri);
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: buildObjectsBooleanThrowsIAEWhenValueIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:887;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if a value is null.
+   */
+  @Test
+  public void buildObjectsBooleanThrowsIAEWhenValueIsNullTest() throws Fault {
+    try {
+      uri = UriBuilder.fromPath("").path("{v}/{w}")
+          .build(new Object[] { "first", null }, false);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: buildFromMapWithBooleanSlashEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:889;
+   * 
+   * @test_Strategy: Build a URI. Any URI template parameters will be replaced
+   * by the value in the supplied map. Values are converted to String using
+   * their toString() method and are then encoded to match the rules of the URI
+   * component to which they pertain. All '%' characters in the stringified
+   * values will be encoded. The state of the builder is unaffected; this method
+   * may be called multiple times on the same builder instance. The slash ('/')
+   * characters in parameter values will be encoded if the template is placed in
+   * the URI path component.
+   */
+  @Test
+  public void buildFromMapWithBooleanSlashEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/%25test1"));
+    map.put("z", new Object() {
+      public String toString() {
+        return "fred@example.com";
+      }
+    });
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    builder.buildFromMap(map, false); // can be called multiple times
+    uri = builder.buildFromMap(map, true);
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromMapWithBooleanSlashNotEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:889;
+   * 
+   * @test_Strategy: Build a URI. Any URI template parameters will be replaced
+   * by the value in the supplied map. Values are converted to String using
+   * their toString() method and are then encoded to match the rules of the URI
+   * component to which they pertain. All '%' characters in the stringified
+   * values will be encoded. The state of the builder is unaffected; this method
+   * may be called multiple times on the same builder instance.
+   */
+  @Test
+  public void buildFromMapWithBooleanSlashNotEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/test1"));
+    map.put("z", new Object() {
+      public String toString() {
+        return "fred@example.com";
+      }
+    });
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    uri = builder.buildFromMap(map, false);
+    gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: buildFromMapWithBooleanThrowsIAEWhenNoSuppliedValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:890;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if there are any URI
+   * template parameters without a supplied value
+   */
+  @Test
+  public void buildFromMapWithBooleanThrowsIAEWhenNoSuppliedValueTest()
+      throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/test1"));
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    try {
+      uri = builder.buildFromMap(map, false);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: buildFromMapWithBooleanThrowsIAEWhenNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:890;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if a template
+   * parameter value is null.
+   */
+  @Test
+  public void buildFromMapWithBooleanThrowsIAEWhenNullValueTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/test1"));
+    map.put("z", null);
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    try {
+      uri = builder.buildFromMap(map, false);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: fromLinkTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:892;
+   * 
+   * @test_Strategy: Create a new instance initialized from a Link.
+   */
+  @Test
+  public void fromLinkTest() throws Fault {
+    URI uri = UriBuilder.fromUri(LOCALHOST).build();
+    Link link = Link.fromUri(uri).build();
+    URI uri2 = UriBuilder.fromLink(link).build();
+    assertTrue(uri.equals(uri2), "URI"+ uri+ "and"+ uri2+ "are not equal");
+    logMsg("URI fromLink is equal to the expected URI");
+  }
+
+  /*
+   * @testName: fromLinkThrowsIllegalArgumentExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:892;
+   * 
+   * @test_Strategy: throws IllegalArgumentException - if link is {@code null}
+   */
+  @Test
+  public void fromLinkThrowsIllegalArgumentExceptionTest() throws Fault {
+    try {
+      UriBuilder.fromLink((Link) null);
+      throw new Fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: fromMethodTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:894;
+   * 
+   * @test_Strategy: Create a new instance representing a relative URI
+   * initialized from a Path-annotated method. This method can only be used in
+   * cases where there is a single method with the specified name that is
+   * annotated with Path.
+   */
+  @Test
+  public void fromMethodTest() throws Fault {
+    URI uri = UriBuilder.fromMethod(TestPath.class, "headSub").build();
+    assertTrue(uri.toASCIIString().equals("/sub"),
+        "There is no /sub in the URI");
+    logMsg("URI fromMethod is equal to the expected URI", uri);
+  }
+
+  /*
+   * @testName: fromMethodThrowsIllegalArgumentExceptionWhenMorePathsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:894;
+   * 
+   * @test_Strategy: Throws: IllegalArgumentException - if resource or method is
+   * null, or there is more than or less than one variant of the method
+   * annotated with Path.
+   */
+  @Test
+  public void fromMethodThrowsIllegalArgumentExceptionWhenMorePathsTest()
+      throws Fault {
+    try {
+      UriBuilder.fromMethod(TestPath.class, "test1");
+      throw new Fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been sucessfully thrown", e);
+    }
+  }
+
+  /*
+   * @testName: fromMethodThrowsIllegalArgumentExceptionWhenNoPathTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:894;
+   * 
+   * @test_Strategy: Throws: IllegalArgumentException - if resource or method is
+   * null, or there is more than or less than one variant of the method
+   * annotated with Path.
+   */
+  @Test
+  public void fromMethodThrowsIllegalArgumentExceptionWhenNoPathTest()
+      throws Fault {
+    try {
+      UriBuilder.fromMethod(TestPath.class, "getPlain");
+      throw new Fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been sucessfully thrown", e);
+    }
+  }
+
+  /*
+   * @testName: toTemplateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:896;
+   * 
+   * @test_Strategy: Get the URI template string represented by this URI
+   * builder.
+   */
+  @Test
+  public void toTemplateTest() throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template);
+    assertEquals(template, builder.toTemplate(), "Given template", template,
+        "differs from obtain", builder.toTemplate());
+    logMsg("Got expected template", template);
+  }
+
+  /*
+   * @testName: uriStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:897;
+   * 
+   * @test_Strategy: Parses the string and copies the parsed components of the
+   * supplied URI to the UriBuilder replacing any existing values for those
+   * components.
+   */
+  @Test
+  public void uriStringTest() throws Fault {
+    String origUris[] = getOrigUris();
+    URI[] replaceUris = getReplacementUris();
+    String[] expectUris = getExpectedUris();
+
+    int cnt = 0;
+    int failed = 0;
+    int passed = 0;
+    while (cnt < 17) {
+      try {
+        sb.append("Replace uri ").append(origUris[cnt]).append(" with ")
+            .append(replaceUris[cnt].toASCIIString()).append(newline);
+        uri = UriBuilder.fromUri(new URI(origUris[cnt]))
+            .uri(replaceUris[cnt].toASCIIString()).build();
+        if (gotExpectedPass(uri.toString().trim(), expectUris[cnt]) != 0)
+          failed++;
+        else
+          passed++;
+      } catch (Exception ex) {
+        pass = false;
+        sb.append("Unexpected exception thrown: ").append(ex.getMessage())
+            .append(newline);
+        sb.append("Test failed with exception for expected uri: ")
+            .append(expectUris[cnt]).append(newline);
+        failed++;
+      }
+      cnt++;
+    }
+
+    assertTrue(pass, passed+ "assertion passed."+ newline+ failed+
+        "assertion(s) failed:"+ sb.toString()+ newline);
+  }
+
+  /*
+   * @testName: uriStringThrowsIAEWhenNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:896;
+   * 
+   * @test_Strategy: throws IllegalArgumentException - if URI template or is
+   * {@code null}.
+   */
+  @Test
+  public void uriStringThrowsIAEWhenNullTest() throws Fault {
+    try {
+      UriBuilder.fromMethod(TestPath.class, "headSub").uri((String) null);
+      throw new Fault("No Exception has been thrown for #uri(null)");
+    } catch (IllegalArgumentException e) {
+      logMsg(
+          "#IllegalArgumentException has been thrown as expected for #uri(null)");
+    }
+  }
+
+  /*
+   * @testName: uriStringThrowsIAEWhenNoUriTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:896;
+   * 
+   * @test_Strategy: throws IllegalArgumentException - if {@code uriTemplate} is
+   * not a valid URI template
+   */
+  @Test
+  public void uriStringThrowsIAEWhenNoUriTest() throws Fault {
+    String sUri = "://";
+    try {
+      uri = UriBuilder.fromUri(new URI("news//:comp.lang.java")).uri(sUri)
+          .build();
+      fault("No Exception has been thrown for #uri(noURI)", uri);
+    } catch (IllegalArgumentException e) {
+      logMsg(
+          "#IllegalArgumentException has been thrown as expected for #uri(noURI)");
+    } catch (URISyntaxException e) {
+      throw new Fault(e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:957;
+   * 
+   * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+   * instance using a supplied value
+   */
+  @Test
+  public void resolveTemplateStringObjectTest() throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template)
+        .resolveTemplate("v", new StringBuilder("aaa"));
+    String resolvedTemplate = template.replace("{v}", "aaa");
+    String builderTemplate = builder.toTemplate();
+    assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+        "was not resolved correctly, remains", builderTemplate);
+    logMsg("Got expected template", template);
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectThrowsIAEOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:957;
+   * 
+   * @test_Strategy: if the resolved template name or value is null.
+   */
+  @Test
+  public void resolveTemplateStringObjectThrowsIAEOnNullNameTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template);
+    try {
+      builder.resolveTemplate(null, "aaa");
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectThrowsIAEOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:957;
+   * 
+   * @test_Strategy: if the resolved template name or value is null.
+   */
+  @Test
+  public void resolveTemplateStringObjectThrowsIAEOnNullValueTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template);
+    try {
+      builder.resolveTemplate("v", null);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectBooleanSlashEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:959;
+   * 
+   * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+   * instance using a supplied value. The slash ('/') characters in template
+   * values will be encoded.
+   */
+  @Test
+  public void resolveTemplateStringObjectBooleanSlashEncodedTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template)
+        .resolveTemplate("v", new StringBuilder("a/a/a"), true);
+    String resolvedTemplate = template.replace("{v}", "a%2Fa%2Fa");
+    String builderTemplate = builder.toTemplate().replace("%2f", "%2F");
+    assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+        "was not resolved correctly, remains", builderTemplate);
+    logMsg("Got expected template", template);
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectBooleanSlashNotEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:959;
+   * 
+   * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+   * instance using a supplied value.
+   */
+  @Test
+  public void resolveTemplateStringObjectBooleanSlashNotEncodedTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template)
+        .resolveTemplate("v", new StringBuilder("a/a/a"), false);
+    String resolvedTemplate = template.replace("{v}", "a/a/a");
+    String builderTemplate = builder.toTemplate();
+    assertEquals(resolvedTemplate, builderTemplate, "Given template", template,
+        "was not resolved correctly, remains", builderTemplate);
+    logMsg("Got expected template", template);
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectBooleanThrowsIAEOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:959;
+   * 
+   * @test_Strategy: if the resolved template name or value is null.
+   */
+  @Test
+  public void resolveTemplateStringObjectBooleanThrowsIAEOnNullNameTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template);
+    try {
+      builder.resolveTemplate(null, "aaa", false);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateStringObjectBooleanThrowsIAEOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:959;
+   * 
+   * @test_Strategy: if the resolved template name or value is null.
+   */
+  @Test
+  public void resolveTemplateStringObjectBooleanThrowsIAEOnNullValueTest()
+      throws Fault {
+    String template = "{v}/{w}/{x}/{y}/{w}";
+    UriBuilder builder = UriBuilder.fromPath("").path(template);
+    try {
+      builder.resolveTemplate("v", null, false);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateFromEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:961;
+   * 
+   * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+   * instance using a supplied encoded value.
+   */
+  @Test
+  public void resolveTemplateFromEncodedTest() throws Fault {
+    Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%25yz"),
+        "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    builder = builder.resolveTemplateFromEncoded("v", s[0]);
+    builder = builder.resolveTemplateFromEncoded("w", s[1]);
+    builder = builder.resolveTemplateFromEncoded("x", s[2]);
+    builder = builder.resolveTemplateFromEncoded("y", s[3]);
+    uri = builder.build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplateFromEncodedPercentEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:961;
+   * 
+   * @test_Strategy: Resolve a URI template with a given name in this UriBuilder
+   * instance using a supplied encoded value. All % characters in the
+   * stringified values that are not followed by two hexadecimal numbers will be
+   * encoded.
+   */
+  @Test
+  public void resolveTemplateFromEncodedPercentEncodedTest() throws Fault {
+    Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%yz"),
+        "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    builder = builder.resolveTemplateFromEncoded("v", s[0]);
+    builder = builder.resolveTemplateFromEncoded("w", s[1]);
+    builder = builder.resolveTemplateFromEncoded("x", s[2]);
+    builder = builder.resolveTemplateFromEncoded("y", s[3]);
+    uri = builder.build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplateFromEncodedThrowsNullOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:961;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if the resolved
+   * template name or encoded value is null.
+   */
+  @Test
+  public void resolveTemplateFromEncodedThrowsNullOnNullNameTest()
+      throws Fault {
+    Object s[] = { "path-rootless%2Ftest2", new StringBuilder("x%25yz"),
+        "%2Fpath-absolute%2F%2525test1", "fred@example.com" };
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    try {
+      builder.resolveTemplateFromEncoded(null, s[0]);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplateFromEncodedThrowsNullOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:961;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if the resolved
+   * template name or encoded value is null.
+   */
+  @Test
+  public void resolveTemplateFromEncodedThrowsNullOnNullValueTest()
+      throws Fault {
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    try {
+      builder.resolveTemplateFromEncoded("v", (Object) null);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:963;
+   * 
+   * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+   * instance using supplied name-value pairs.
+   */
+  @Test
+  public void resolveTemplatesMapTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/%25test1"));
+    map.put("z", new Object() {
+      public String toString() {
+        return "fred@example.com";
+      }
+    });
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    uri = builder.resolveTemplates(map).build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplatesMapThrowsIAEOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:963;
+   * 
+   * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesMapThrowsIAEOnNullNameTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("a", new StringBuilder("x%yz"));
+    map.put(null, "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+    try {
+      builder.resolveTemplates(map);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesMapThrowsIAEOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:963;
+   * 
+   * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesMapThrowsIAEOnNullValueTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("a", null);
+    map.put("b", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+    try {
+      builder.resolveTemplates(map);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesMapBooleanSlashEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:965;
+   * 
+   * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+   * instance using supplied name-value pairs.
+   */
+  @Test
+  public void resolveTemplatesMapBooleanSlashEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/%25test1"));
+    map.put("z", new Object() {
+      public String toString() {
+        return "fred@example.com";
+      }
+    });
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    uri = builder.resolveTemplates(map, true).build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplatesMapBooleanSlashNotEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:965;
+   * 
+   * @test_Strategy: Resolve one or more URI templates in this UriBuilder
+   * instance using supplied name-value pairs.
+   */
+  @Test
+  public void resolveTemplatesMapBooleanSlashNotEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("x", new StringBuilder("x%yz"));
+    map.put("y", new StringBuffer("/path-absolute/test1"));
+    map.put("z", new Object() {
+      public String toString() {
+        return "fred@example.com";
+      }
+    });
+    map.put("w", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{w}/{x}/{y}/{z}/{x}");
+    uri = builder.resolveTemplates(map, false).build();
+    gotExpectedPass(uri.getRawPath(), EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:966;
+   * 
+   * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesMapBooleanThrowsIAEOnNullNameTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("a", new StringBuilder("x%yz"));
+    map.put(null, "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+    try {
+      builder.resolveTemplates(map, true);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:966;
+   * 
+   * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesMapBooleanThrowsIAEOnNullValueTest()
+      throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("a", null);
+    map.put("b", "path-rootless/test2");
+    UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+    try {
+      builder.resolveTemplates(map, false);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesMapBooleanThrowsIAEOnNullMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:966;
+   * 
+   * @test_Strategy:java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesMapBooleanThrowsIAEOnNullMapTest() throws Fault {
+    UriBuilder builder = UriBuilder.fromPath("").path("{a}/{b}");
+    try {
+      builder.resolveTemplates((Map<String, Object>) null, false);
+      fault("IllegalArgumentException has not been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException has been thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesFromEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:967;
+   * 
+   * @test_Strategy: Resolve one or more URI templates in this instance using
+   * supplied name-value pairs.
+   */
+  @Test
+  public void resolveTemplatesFromEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("v", new StringBuilder("path-rootless%2Ftest2"));
+    map.put("w", new StringBuilder("x%25yz"));
+    map.put("x", new Object() {
+      public String toString() {
+        return "%2Fpath-absolute%2F%2525test1";
+      }
+    });
+    map.put("y", "fred@example.com");
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    builder = builder.resolveTemplatesFromEncoded(map);
+    uri = builder.build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplatesFromEncodedPercentEncodedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:967;
+   * 
+   * @test_Strategy: Resolve one or more URI templates in this instance using
+   * supplied name-value pairs. All % characters in the stringified values that
+   * are not followed by two hexadecimal numbers will be encoded.
+   */
+  @Test
+  public void resolveTemplatesFromEncodedPercentEncodedTest() throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("v", new StringBuilder("path-rootless%2Ftest2"));
+    map.put("w", new StringBuilder("x%yz"));
+    map.put("x", new Object() {
+      public String toString() {
+        return "%2Fpath-absolute%2F%2525test1";
+      }
+    });
+    map.put("y", "fred@example.com");
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    builder = builder.resolveTemplatesFromEncoded(map);
+    uri = builder.build();
+    gotExpectedPass(uri.getRawPath(), ENCODED_EXPECTED_PATH);
+    assertPassAndLog();
+  }
+
+  /*
+   * @testName: resolveTemplatesFromEncodedThrowsNullOnNullNameTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:967;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesFromEncodedThrowsNullOnNullNameTest()
+      throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put(null, "aa");
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    try {
+      builder.resolveTemplatesFromEncoded(map);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesFromEncodedThrowsNullOnNullValueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:967;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesFromEncodedThrowsNullOnNullValueTest()
+      throws Fault {
+    Map<String, Object> map = new HashMap<String, Object>();
+    map.put("v", null);
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    try {
+      builder.resolveTemplatesFromEncoded(map);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException thrown as expected", e);
+    }
+  }
+
+  /*
+   * @testName: resolveTemplatesFromEncodedThrowsNullOnNullMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:967;
+   * 
+   * @test_Strategy: java.lang.IllegalArgumentException - if the name-value map
+   * or any of the names or values in the map is null.
+   */
+  @Test
+  public void resolveTemplatesFromEncodedThrowsNullOnNullMapTest()
+      throws Fault {
+    UriBuilder builder = UriBuilder.fromPath("").path("{v}/{w}/{x}/{y}/{w}");
+    try {
+      builder.resolveTemplatesFromEncoded((Map<String, Object>) null);
+      fault("No exception has been thrown");
+    } catch (IllegalArgumentException e) {
+      logMsg("IllegalArgumentException thrown as expected", e);
+    }
+  }
+
+
+  // ////////////////////////////////////////////////////////////////////////
+  /**
+   * This is the pattern used in all over the tests. Add to stringBuilder what's
+   * expected, what's got and set pass value.
+   * 
+   * @param got
+   * @param expected
+   * @return got.compareToIgnoreCase(expected)
+   */
+  private int gotExpectedPass(String got, String expected) {
+    got = got.replace("%2f", "%2F");
+    int compare = got.compareToIgnoreCase(expected);
+    gotExpectedPass(compare != 0, got, expected);
+    return compare;
+  }
+
+  private boolean gotExpectedPass(boolean conditionFalse, String got,
+      String expected) {
+    if (conditionFalse) {
+      pass = false;
+      sb.append("Incorrect URI returned: ").append(got);
+      sb.append(", expecting ").append(expected);
+    } else
+      sb.append("Got expected return: ").append(expected);
+    sb.append(newline);
+    return conditionFalse;
+
+  }
+
+  private void assertPassAndLog() throws Fault {
+    assertTrue(pass, "At least one assertion failed:"+ sb.toString());    
+    TestUtil.logTrace(sb.toString());
+  }
+
+  private static String[] getOrigUris() {
+    String[] uris_orig = { "ftp://ftp.is.co.za/rfc/rfc1808.txt",
+        "ftp://ftp.is.co.za/rfc/rfc1808.txt", "mailto:java-net@java.sun.com",
+        "mailto:java-net@java.sun.com", "news:comp.lang.java",
+        "news:comp.lang.java", "urn:isbn:096139210x",
+        "http://www.ietf.org/rfc/rfc2396.txt",
+        "http://www.ietf.org/rfc/rfc2396.txt",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+        "tel:+1-816-555-1212", "telnet://192.0.2.16:80/",
+        "telnet://192.0.2.16:80/",
+        "foo://example.com:8042/over/there?name=ferret#nose",
+        "foo://example.com:8042/over/there?name=ferret#nose" };
+    return uris_orig;
+  }
+
+  private static URI[] getReplacementUris() throws Fault {
+    URI uris_replace[] = { null, null, null, null, null, null, null, null, null,
+        null, null, null, null, null, null, null, null };
+
+    try {
+      uris_replace[0] = new URI("http", "//ftp.is.co.za/rfc/rfc1808.txt", null);
+      uris_replace[1] = new URI(null, "ftp.is.co.za", "/test/rfc1808.txt", null,
+          null);
+      uris_replace[2] = new URI("mailto", "java-net@java.sun.com", null);
+      uris_replace[3] = new URI(null, "testuser@sun.com", null);
+      uris_replace[4] = new URI("http", "//comp.lang.java", null);
+      uris_replace[5] = new URI(null, "news.lang.java", null);
+      uris_replace[6] = new URI("urn:isbn:096139210x");
+      uris_replace[7] = new URI(null, "//www.ietf.org/rfc/rfc2396.txt", null);
+      uris_replace[8] = new URI(null, "www.ietf.org", "/rfc/rfc2396.txt", null,
+          null);
+      uris_replace[9] = new URI("ldap", "//[2001:db8::7]/c=GB?objectClass?one",
+          null);
+      uris_replace[10] = new URI(null, "//[2001:db8::7]/c=GB?objectClass?one",
+          null);
+      uris_replace[11] = new URI("tel", "+1-816-555-1212", null);
+      uris_replace[12] = new URI(null, "+1-866-555-1212", null);
+      uris_replace[13] = new URI("telnet", "//192.0.2.16:80/", null);
+      uris_replace[14] = new URI(null, "//192.0.2.16:81/", null);
+      uris_replace[15] = new URI("http",
+          "//example.com:8042/over/there?name=ferret", null);
+      uris_replace[16] = new URI(null,
+          "//example.com:8042/over/there?name=ferret", "mouth");
+    } catch (Exception ex) {
+      throw new Fault(
+          "========== Exception thrown constructing replacing URIs: "
+              + ex.getMessage() + newline);
+    }
+    return uris_replace;
+  }
+
+  private static String[] getExpectedUris() {
+    String[] uris_expect = { "http://ftp.is.co.za/rfc/rfc1808.txt",
+        "ftp://ftp.is.co.za/test/rfc1808.txt", "mailto:java-net@java.sun.com",
+        "mailto:testuser@sun.com", "http://comp.lang.java",
+        "news:news.lang.java", "urn:isbn:096139210x",
+        "http://www.ietf.org/rfc/rfc2396.txt",
+        "http://www.ietf.org/rfc/rfc2396.txt",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one",
+        "ldap://[2001:db8::7]/c=GB?objectClass?one", "tel:+1-816-555-1212",
+        "tel:+1-866-555-1212", "telnet://192.0.2.16:80/",
+        "telnet://192.0.2.16:81/",
+        "http://example.com:8042/over/there?name=ferret#nose",
+        "foo://example.com:8042/over/there?name=ferret#mouth" };
+    return uris_expect;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java
new file mode 100644
index 0000000..fbfbca0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPath.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.uribuilder;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.Response;
+
+@Path(value = "/TestPath")
+public class TestPath {
+
+  @GET
+  public Response getPlain() {
+    return Response.ok().build();
+  }
+
+  @Path(value = "/sub")
+  public Response headSub() {
+    return Response.ok().build();
+  }
+
+  @Path(value = "sub1")
+  public Response test1() {
+    return Response.ok().build();
+  }
+
+  @Path(value = "/sub2")
+  public Response test1(@QueryParam("testName") String test) {
+    return Response.ok(test).build();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java
new file mode 100644
index 0000000..4f8ed3c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/uribuilder/TestPathBad.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.uribuilder;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.core.Response;
+
+public class TestPathBad {
+  @GET
+  public Response getPlain() {
+    return Response.ok().build();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java
new file mode 100644
index 0000000..a4c74d7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/AbstractMessageBodyRW.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.Path;
+
+/**
+ * This class is a superclass used in MessageBodyWriters which need to check
+ * 
+ * @Path annotation value
+ */
+public abstract class AbstractMessageBodyRW {
+
+  public static String getPathValue(Annotation[] annotations) {
+    return getSpecifiedAnnotationValue(annotations, Path.class);
+  }
+
+  @SuppressWarnings("unchecked")
+  public static <T extends Annotation> T getSpecifiedAnnotation(
+      Annotation[] annotations, Class<T> clazz) {
+    T t = null;
+    for (Annotation a : annotations)
+      if (a.annotationType() == clazz)
+        t = (T) a;
+    return t != null ? t : null;
+  }
+
+  public static <T extends Annotation> String getSpecifiedAnnotationValue(
+      Annotation[] annotations, Class<T> clazz) {
+    T t = getSpecifiedAnnotation(annotations, clazz);
+    try {
+      Method m = clazz.getMethod("value");
+      return (String) m.invoke(t);
+    } catch (Exception e) {
+      return null;
+    }
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
new file mode 100644
index 0000000..f69dd67
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/JAXRSCommonClient.java
@@ -0,0 +1,1212 @@
+ /*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common;
+
+import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Properties;
+import java.nio.charset.StandardCharsets;
+
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpState;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.validation.CheckOneOfStatusesTokenizedValidator;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.common.util.Data;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * 
+ * @author dianne jiao
+ * @author jan supol
+ */
+//public abstract class JAXRSCommonClient extends ServiceEETest {
+public abstract class JAXRSCommonClient {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * TS Webserver host property
+   */
+  protected static final String SERVLETHOSTPROP = "webServerHost";
+
+  /**
+   * TS Webserver port property
+   */
+  protected static final String SERVLETPORTPROP = "webServerPort";
+
+  /**
+   * TS home property
+   */
+  protected static final String TSHOME = "ts_home";
+
+  /**
+   * Test properties
+   */
+  protected static final Hashtable<Property, String> TEST_PROPS = new Hashtable<Property, String>();
+
+  /**
+   * StatusCode property
+   */
+  protected static final String STATUS_CODE = "STATUS_CODE";
+
+  /**
+   * Request property
+   */
+  protected static final String REQUEST = "REQUEST";
+
+  /**
+   * Request headers property
+   */
+  protected static final String REQUEST_HEADERS = "REQUEST_HEADERS";
+
+  /**
+   * Goldenfile property
+   */
+  protected static final String GOLDENFILE = "goldenfile";
+
+  /**
+   * Search string property
+   */
+  protected static final String SEARCH_STRING = "SEARCH_STRING";
+
+  /**
+   * Search string case insensitive property
+   */
+  protected String TESTDIR = null;
+
+  /**
+   * Goldenfile directory
+   */
+  protected String GOLDENFILEDIR = "/src/web";
+
+  /**
+   * Default request method
+   */
+  protected static final String GET = "GET ";
+
+  /**
+   * HTTP 1.0
+   */
+  protected static final String HTTP10 = " HTTP/1.0";
+
+  /**
+   * HTTP 1.1
+   */
+  protected static final String HTTP11 = " HTTP/1.1";
+
+  /**
+   * Forward slash
+   */
+  protected static final String SL = "/";
+
+  /**
+   * Goldenfile suffix
+   */
+  protected static final String GF_SUFFIX = ".gf";
+
+  /**
+   * JSP suffix
+   */
+  /**
+   * Current test name
+   */
+  protected String _testName = null;
+
+  /**
+   * location of _tsHome
+   */
+  protected String _tsHome = null;
+
+  /**
+   * Context root of target tests
+   */
+  public String _contextRoot = null;
+
+  /**
+   * General file/request URI for both gfiles and tests
+   */
+  protected String _generalURI = null;
+
+  /**
+   * Target webserver hostname
+   */
+  protected String _hostname = null;
+
+  /**
+   * Target webserver port
+   */
+  protected int _port = 0;
+
+  /**
+   * HttpState that may be used for multiple invocations requiring state.
+   */
+  protected HttpState _state = null;
+
+  /**
+   * Test case.
+   */
+  protected WebTestCase _testCase = null;
+
+  /**
+   * Use saved state.
+   */
+  protected boolean _useSavedState = false;
+
+  /**
+   * Save state.
+   */
+  protected boolean _saveState = false;
+
+  protected boolean _redirect = false;
+
+  public static final String newline = System.getProperty("line.separator");
+
+  public static final String servletAdaptor = System.getProperty("servlet_adaptor", "org.glassfish.jersey.servlet.ServletContainer");
+
+  public static final String indent = "    ";
+
+  /**
+   * List of possible requests
+   */
+  protected enum Request {
+    GET, PUT, POST, HEAD, OPTIONS, DELETE, TRACE
+  }
+
+  /**
+   * the list of properties to be put into a property table
+   */
+  protected enum Property {
+    APITEST, BASIC_AUTH_PASSWD, BASIC_AUTH_REALM, BASIC_AUTH_USER, //
+    CONTENT, DONOTUSEServletName, EXPECT_RESPONSE_BODY, EXPECTED_HEADERS, //
+    FOLLOW_REDIRECT, GOLDENFILE, IGNORE_BODY, IGNORE_STATUS_CODE, //
+    REASON_PHRASE, REQUEST, REQUEST_HEADERS, RESPONSE_MATCH, SAVE_STATE, //
+    SEARCH_STRING, SEARCH_STRING_IGNORE_CASE, STANDARD, STATUS_CODE, //
+    STRATEGY, TEST_NAME, UNEXPECTED_HEADERS, UNEXPECTED_RESPONSE_MATCH, //
+    UNORDERED_SEARCH_STRING, USE_SAVED_STATE;
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+  /**
+   * <code>setTestDir</code> sets the current test directory.
+   * 
+   * @param testDir
+   *          a <code>String</code> value
+   */
+  public void setTestDir(String testDir) {
+    TestUtil.logTrace("[JAXRSCommonClient] setTestDir");
+    TESTDIR = testDir;
+  }
+
+  public void setContextRoot(String root) {
+    TestUtil.logTrace("[JAXRSCommonClient] Contextroot set at " + root);
+    _contextRoot = root;
+  }
+
+  public String getContextRoot() {
+    TestUtil.logTrace("[JAXRSCommonClient]getContextRoot");
+    return _contextRoot;
+  }
+
+  /**
+   * <code>setup</code> is by the test harness to initialize the tests.
+   * 
+   * @param args
+   *          a <code>String[]</code> value
+   * @param p
+   *          a <code>Properties</code> value
+   * @exception Fault
+   *              if an error occurs
+   */
+  //public void setup(String[] args, Properties p)   {
+  public void setup()   {
+    TestUtil.logTrace("setup method JAXRSCommonClient");
+
+    String hostname = System.getProperty(SERVLETHOSTPROP);
+    String portnum = System.getProperty(SERVLETPORTPROP);
+    //String tshome = p.getProperty(TSHOME);
+
+    assertTrue(!isNullOrEmpty(hostname),
+        "[JAXRSCommonClient] 'webServerHost' was not set.");
+    _hostname = hostname.trim();
+    assertTrue(!isNullOrEmpty(portnum),
+        "[JAXRSCommonClient] 'webServerPort' was not set.");
+    _port = Integer.parseInt(portnum.trim());
+
+    //assertTrue(!isNullOrEmpty(tshome),
+    //    "[JAXRSCommonClient] 'tshome' was not set in the build.properties.");
+    //_tsHome = tshome.trim();
+
+    TestUtil.logMsg("[JAXRSCommonClient] Test setup OK");
+  }
+
+  /**
+   * <code>cleanup</code> is called by the test harness to cleanup after text
+   * execution
+   * 
+   * @exception Fault
+   *              if an error occurs
+   */
+  public void cleanup() throws Fault  {
+    TestUtil.logMsg("[JAXRSCommonClient] Test cleanup OK");
+  }
+
+  /*
+   * protected methods
+   * ========================================================================
+   */
+  /**
+   * <PRE>
+   * Invokes a test based on the properties
+   * stored in TEST_PROPS.  Once the test has completed,
+   * the properties in TEST_PROPS will be cleared.
+   * </PRE>
+   * 
+   * @throws Fault
+   *           If an error occurs during the test run
+   */
+  protected void invoke() throws Fault {
+    TestUtil.logTrace("[JAXRSCommonClient] invoke");
+    try {
+      _testCase = new WebTestCase();
+      setTestProperties(_testCase);
+      TestUtil.logTrace("[JAXRSCommonClient] EXECUTING");
+      if (_useSavedState && _state != null) {
+        _testCase.getRequest().setState(_state);
+      }
+      if (_redirect != false) {
+        TestUtil.logTrace("##########Call setFollowRedirects");
+        _testCase.getRequest().setFollowRedirects(_redirect);
+      }
+      _testCase.execute();
+      if (_saveState) {
+        _state = _testCase.getResponse().getState();
+      }
+    } catch (TestFailureException tfe) {
+      Throwable t = tfe.getRootCause();
+      if (t != null) {
+        TestUtil.logErr("Root cause of Failure: " + t.getMessage(), t);
+        if (t instanceof RuntimeException) {
+          throw (RuntimeException) t;
+        } else if (t instanceof Error) {
+          throw (Error) t;
+        } else {
+          throw new RuntimeException(t);
+        }
+      }
+      throw new Fault("[JAXRSCommonClient] " + _testName
+          + " failed!  Check output for cause of failure.", tfe);
+    } finally {
+      _useSavedState = false;
+      _saveState = false;
+      _redirect = false;
+      clearTestProperties();
+    }
+  }
+
+  /**
+   * <PRE>
+   * Sets the appropriate test properties based
+   * on the values stored in TEST_PROPS
+   * </PRE>
+   */
+  protected void setTestProperties(WebTestCase testCase) {
+    TestUtil.logTrace("[JAXRSCommonClient] setTestProperties");
+
+    setStandardProperties(TEST_PROPS.get(Property.STANDARD), testCase);
+    setApiTestProperties(TEST_PROPS.get(Property.APITEST), testCase);
+
+    if (TEST_PROPS.get(Property.STATUS_CODE) == null)
+      setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+
+    HttpRequest req = testCase.getRequest();
+
+    // Check for a request object. If doesn't exist, then
+    // check for a REQUEST property and create the request object.
+    if (req == null)
+      req = setWebTestCaseRequest(testCase, null);
+    setWebTestCaseProperties(testCase, req);
+  }
+
+  protected HttpRequest setWebTestCaseRequest(WebTestCase testCase,
+      HttpRequest req) {
+    String request = TEST_PROPS.get(Property.REQUEST);
+    boolean isRequest = false;
+    for (Request r : Request.values())
+      if (request.startsWith(r.name()))
+        isRequest = true;
+    if (request.endsWith(HTTP10) || request.endsWith(HTTP11))
+      isRequest = true;
+    if (isRequest) {
+      // user has overridden default request behavior
+      req = createHttpRequest(request, _hostname, _port);
+      testCase.setRequest(req);
+    } else {
+      req = createHttpRequest(getTSRequest(request), _hostname, _port);
+      testCase.setRequest(req);
+    }
+    return req;
+  }
+
+  protected void setWebTestCaseProperties(WebTestCase testCase,
+      HttpRequest req) {
+    Property key = null;
+    String value = null;
+    // process the remainder of the properties
+    for (Enumeration<Property> e = TEST_PROPS.keys(); e.hasMoreElements();) {
+      key = e.nextElement();
+      value = TEST_PROPS.get(key);
+      switch (key) {
+      case APITEST:
+        break;
+      case BASIC_AUTH_PASSWD:
+      case BASIC_AUTH_REALM:
+      case BASIC_AUTH_USER:
+        String user = TEST_PROPS.get(Property.BASIC_AUTH_USER);
+        String password = TEST_PROPS.get(Property.BASIC_AUTH_PASSWD);
+        String realm = TEST_PROPS.get(Property.BASIC_AUTH_REALM);
+        req.setAuthenticationCredentials(user, password,
+            HttpRequest.BASIC_AUTHENTICATION, realm);
+        break;
+      case CONTENT:
+        req.setContent(value);
+        break;
+      case DONOTUSEServletName:
+        break;
+      case EXPECT_RESPONSE_BODY:
+        // FIXME
+        // setExpectResponseBody(false);
+        break;
+      case EXPECTED_HEADERS:
+        testCase.addExpectedHeader(value);
+        break;
+      case FOLLOW_REDIRECT:
+        TestUtil.logTrace("##########Found redirect Property");
+        _redirect = true;
+        break;
+      case GOLDENFILE:
+        StringBuffer sb = new StringBuffer(50);
+        sb.append(_tsHome).append(GOLDENFILEDIR);
+        sb.append(_generalURI).append(SL);
+        sb.append(value);
+        testCase.setGoldenFilePath(sb.toString());
+        break;
+      case IGNORE_BODY:
+        // FIXME
+        // setIgnoreResponseBody(true);
+        testCase.setGoldenFilePath(null);
+        break;
+      case IGNORE_STATUS_CODE:
+        testCase.setExpectedStatusCode("-1");
+        break;
+      case REASON_PHRASE:
+        testCase.setExpectedReasonPhrase(value);
+        break;
+      case REQUEST:
+        break;
+      case REQUEST_HEADERS:
+        req.addRequestHeader(value);
+        break;
+      case RESPONSE_MATCH:
+        // setResponseMatch(TEST_PROPS.getProperty(key));
+        break;
+      case SAVE_STATE:
+        _saveState = true;
+        break;
+      case SEARCH_STRING:
+        testCase.setResponseSearchString(value);
+        break;
+      case SEARCH_STRING_IGNORE_CASE:
+        testCase.setResponseSearchStringIgnoreCase(value);
+        break;
+      case STANDARD:
+        break;
+      case STATUS_CODE:
+        if (value.contains("|"))
+          testCase.setStrategy(
+              CheckOneOfStatusesTokenizedValidator.class.getName());
+        testCase.setExpectedStatusCode(value);
+        break;
+      case STRATEGY:
+        testCase.setStrategy(value);
+        break;
+      case TEST_NAME:
+        // testName = TEST_PROPS.getProperty(key);
+        break;
+      case UNEXPECTED_HEADERS:
+        testCase.addUnexpectedHeader(value);
+        break;
+      case UNEXPECTED_RESPONSE_MATCH:
+        testCase.setUnexpectedResponseSearchString(value);
+        break;
+      case UNORDERED_SEARCH_STRING:
+        testCase.setUnorderedSearchString(value);
+        break;
+      case USE_SAVED_STATE:
+        _useSavedState = true;
+        break;
+      }
+    }
+  }
+
+  /**
+   * Create request <type> /<contextroot>/<path> HTTP/1.1. ContextRoot is
+   * defined in every client.
+   * 
+   * @param type
+   *          PUT, GET, POST, ...
+   * @param path
+   *          path defined in a servlet
+   * @return String representing HTTP request
+   */
+  protected String buildRequest(String type, String... path) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(type).append(" ").append(_contextRoot).append(SL);
+    for (String segment : path)
+      sb.append(segment);
+    sb.append(HTTP11);
+    return sb.toString();
+  }
+
+  protected String buildRequest(Request type, String... path) {
+    return buildRequest(type.name(), path);
+  }
+
+  protected String buildRequest10(Request type, String... path) {
+    return buildRequest(type, path).replace(HTTP11, HTTP10);
+  }
+
+  /**
+   * Create counterpart to @Produces
+   * 
+   * @param type
+   * @return Accept:{@code type}.{@link #toString()}
+   */
+  protected static String buildAccept(MediaType type) {
+    return buildHeaderMediaType("Accept", type);
+  }
+
+  /**
+   * Create counterpart to @Consumes
+   * 
+   * @param type
+   * @return
+   */
+  protected static String buildContentType(MediaType type) {
+    return buildHeaderMediaType("Content-Type", type);
+  }
+
+  protected static String buildHeaderMediaType(String header, MediaType type) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(header).append(":").append(type.getType()).append(SL);
+    sb.append(type.getSubtype());
+    return sb.toString();
+  }
+
+  public static String editWebXmlString(InputStream inStream) throws IOException{
+    String line;
+    String webXmlTemplate = "";
+    try (BufferedReader bufReader = new BufferedReader(new InputStreamReader(inStream, StandardCharsets.UTF_8))) {
+      while ((line = bufReader.readLine()) != null) {
+        webXmlTemplate = webXmlTemplate + line + System.lineSeparator();
+      }
+    }
+    
+    String webXml = webXmlTemplate.replaceAll("servlet_adaptor", servletAdaptor);
+    return webXml;
+  }
+
+  /**
+   * @return http response body as string
+   * @throws Fault
+   *           when an error occur
+   */
+  protected String getResponseBody() throws Fault  {
+    try {
+      jakarta.ws.rs.tck.common.webclient.http.HttpResponse response;
+      response = _testCase.getResponse();
+      boolean isNull = response.getResponseBodyAsRawStream() == null;
+      return isNull ? null : response.getResponseBodyAsString();
+    } catch (IOException e) {
+        throw new Fault(e);
+    }
+  }
+
+  /**
+   * @return http response body as string
+   * @throws Fault
+   *           when an error occur
+   */
+  protected String[] getResponseHeaders() throws Fault  {
+    Header[] headerEntities = _testCase.getResponse().getResponseHeaders();
+    String[] headers = new String[headerEntities.length];
+    for (int i = 0; i != headerEntities.length; i++)
+      headers[i] = headerEntities[i].toString();
+    return headers;
+  }
+
+  /**
+   * @param s
+   *          the header to search
+   * @throws Fault
+   *           when header not found
+   */
+  protected void assertResponseHeadersContain(String s) throws Fault  {
+    boolean found = false;
+    for (String header : getResponseHeaders())
+      if (header.contains(s)) {
+        found = true;
+        break;
+      }
+    assertTrue(found, "Response headers do not contain"+ s);
+  }
+
+  /**
+   * @param s
+   *          the entity to search
+   * @throws Fault
+   *           when entity not found
+   */
+  protected void assertResponseBodyContain(String s)  throws Fault {
+    boolean found = getResponseBody().contains(s);
+    assertTrue(found, "Response body does not contain"+ s);
+  }
+
+  /**
+   * get HttpResponse#statusCode
+   * 
+   * @return JAXRS Response.Status equivalent of HttpResponse#statusCode
+   */
+  protected Response.Status getResponseStatusCode() {
+    String status = _testCase.getResponse().getStatusCode();
+    return Response.Status.fromStatusCode(Integer.parseInt(status));
+  }
+
+  /**
+   * Set TEST_PROPS property value. If it already exists, the value is appended
+   */
+  protected void setProperty(String key, String value) {
+    Property property = Property.valueOf(key);
+    setProperty(property, value);
+  }
+
+  /*
+   * @since 2.0.1
+   */
+  protected void setProperty(Property key, String... value) {
+    setProperty(key, objectsToString("", (Object[]) value));
+  }
+
+  protected void setProperty(Property key, String value) {
+    String oldValue = TEST_PROPS.get(key);
+    if (oldValue == null) {
+      TEST_PROPS.put(key, value);
+    } else {
+      int len = value.length() + oldValue.length() + 1;
+      StringBuilder combinedValue = new StringBuilder(len);
+      combinedValue.append(oldValue).append("|").append(value);
+      TEST_PROPS.put(key, combinedValue.toString());
+    }
+  }
+
+  protected void clearProperty(Property key) {
+    TEST_PROPS.remove(key);
+  }
+
+  /**
+   * This pattern is used in all subclasses
+   */
+  //protected Status run(String[] args) {
+  //  Status s;
+  //  s = run(args, new PrintWriter(System.out), new PrintWriter(System.err));
+  //  s.exit();
+  //  return s;
+  //}
+
+  /**
+   * Asserts that a condition is true.
+   * 
+   * @param conditionTrue
+   *          tested condition
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   * @ 
+   *           when conditionTrue is not met with message provided
+   */
+  /*public static void //
+      assertFault(boolean conditionTrue, Object... message)   {
+    assertTrue(conditionTrue, message);
+  }*/
+
+  /**
+   * Asserts that a condition is true.
+   * 
+   * @param condition
+   *          tested condition
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   * @ 
+   *           when conditionTrue is not met with message provided
+   */
+  //public static void //
+  //    assertTrue(boolean condition, Object... message)   {
+  //  if (!condition)
+  //    fail(message);
+  //}
+
+  /**
+   * Asserts that a condition is false.
+   * 
+   * @param condition
+   *          tested condition
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   * @ 
+   *           when condition is not false with message provided
+   */
+  /*public static void //
+      assertFalse(boolean condition, Object... message)   {
+    assertTrue(!condition, message);
+  }*/
+
+  /**
+   * Asserts that two objects are equal. When instances of Comparable, such as
+   * String, compareTo is used.
+   * 
+   * @param first
+   *          first object
+   * @param second
+   *          second object
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   * @ 
+   *           when objects are not equal with message provided
+   */
+  @SuppressWarnings("unchecked")
+  public static <T> void //
+      assertEquals(T first, T second, Object... message)   {
+    if (first == null && second == null)
+      return;
+    assertFalse(first == null && second != null, message.toString());
+    assertFalse(first != null && second == null, message.toString());
+    if (first instanceof Comparable)
+      assertTrue(((Comparable<T>) first).compareTo(second) == 0, message.toString());
+    else
+      assertTrue(first.equals(second), message.toString());
+  }
+
+  public static <T> void //
+      assertEqualsInt(int first, int second, Object... message)   {
+    assertTrue(first == second, message.toString());
+  }
+
+  public static <T> void //
+      assertEqualsLong(long first, long second, Object... message)
+            {
+    assertTrue(first == second, message.toString());
+  }
+
+  public static <T> void //
+      assertEqualsBool(boolean first, boolean second, Object... message)
+            {
+    assertTrue(first == second, message.toString());
+  }
+
+  /**
+   * Asserts that an object is null.
+   * 
+   * @param object
+   *          Assert that object is not null
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   */
+  public static void //
+      assertNull(Object object, Object... message) {
+    assertTrue(object == null, message.toString());
+  }
+
+  /**
+   * Asserts that an object is not null.
+   * 
+   * @param object
+   *          Assert that object is not null
+   * @param message
+   *          a space separated message[i].toString() compilation for
+   *          i=<0,message.length)
+   */
+  public static void //
+      assertNotNull(Object object, Object... message) {
+    assertTrue(object != null, message.toString());
+  }
+
+  /**
+   * Throws Fault with space separated objects[1],object[2],...,object[n]
+   * message
+   * 
+   * @param objects
+   *          objects whose toString() results will be added to Fault message
+   * @throws Fault
+   *           fault with space separated objects.toString values
+   */
+  public static void fault(Object... objects) throws Fault  {
+    throw new Fault(objectsToString(objects));
+  }
+
+  /**
+   * Assert that given substring is a substring of given string
+   * 
+   * @param string
+   *          the string to search substring in
+   * @param substring
+   *          the substring to be searched in a given string
+   * @param message
+   *          space separated message values to be thrown
+   * @ 
+   *           throws
+   */
+  public static void assertContains(String string, String substring,
+      Object... message)   {
+    assertTrue(string.contains(substring), message.toString());
+  }
+
+  /**
+   * Assert that given substring is a substring of given string, case
+   * insensitive
+   * 
+   * @param string
+   *          the string to search substring in
+   * @param substring
+   *          the substring to be searched in a given string
+   * @param message
+   *          space separated message values to be thrown
+   * @ 
+   */
+  public static void assertContainsIgnoreCase(String string, String substring,
+      Object... message)   {
+    assertTrue(string.toLowerCase().contains(substring.toLowerCase()), message.toString());
+  }
+
+  /**
+   * Assert that given subtext.toString() subject is a substring of given text
+   * 
+   * @param text
+   *          the text.toString() object to search subtext.toString() in
+   * @param subtext
+   *          the subtext.toString() to be searched in a given text.toString()
+   * @param message
+   *          space separated message values to be thrown
+   * @ 
+   */
+  public static <T> void assertContains(T text, T subtext, Object... message)
+        {
+    assertContains(text.toString(), subtext.toString(), message.toString());
+  }
+
+  /**
+   * Assert that given subtext.toString() subject is a substring of given text,
+   * case insensitive
+   * 
+   * @param text
+   *          the text.toString() object to search subtext.toString() in
+   * @param subtext
+   *          the subtext.toString() to be searched in a given text.toString()
+   * @param message
+   *          space separated message values to be thrown
+   * @ 
+   */
+  public static <T> void assertContainsIgnoreCase(T text, T subtext,
+      Object... message)   {
+    assertContainsIgnoreCase(text.toString(), subtext.toString(), message.toString());
+  }
+
+  /**
+   * Searches an encapsulated exception cause in parent exception
+   */
+  protected static <T extends Throwable> T assertCause(Throwable parent,
+      Class<T> wrapped, Object... msg)   {
+    T t = hasCause(parent, wrapped);
+    assertNotNull(t, msg);
+    return t;
+  }
+
+  @SuppressWarnings("unchecked")
+  private static <T extends Throwable> T //
+      hasCause(Throwable parent, Class<? extends Throwable> cause) {
+    while (parent != null) {
+      if (cause.isInstance(parent))
+        return (T) parent;
+      parent = parent.getCause();
+    }
+    return null;
+  }
+
+  public static String getStatusCode(Response.Status status) {
+    return String.valueOf(status.getStatusCode());
+  }
+
+  public static void logMsg(Object... msg) {
+    TestUtil.logMsg(objectsToString(msg));
+  }
+
+  public static void logTrace(Object... msg) {
+    TestUtil.logTrace(objectsToString(msg));
+  }
+
+  /**
+   * Use rather this method than
+   * {@link JaxrsUtil#iterableToString(String, Iterable)} since not all wars
+   * (for servlet vehicle, api) do contain JaxrsUtil
+   * 
+   * @param objects
+   * @return objects in a single string , each object separated by " "
+   */
+  protected static String objectsToString(Object... objects) {
+    return objectsToString(" ", objects);
+  }
+
+  /**
+   * @since 2.0.1
+   */
+  protected static String objectsToString(String delimiter, Object... objects) {
+    StringBuilder sb = new StringBuilder();
+    for (Object o : objects)
+      sb.append(o).append(delimiter);
+    return sb.toString().trim();
+  }
+
+  /*
+   * private methods
+   * ========================================================================
+   */
+  private String getTSRequest(String request) {
+    TestUtil.logTrace("[JAXRSCommonClient] getTSRequest");
+    StringBuffer finReq = new StringBuffer(50);
+    finReq.append(GET).append(_contextRoot).append(SL).append(_generalURI);
+    finReq.append(SL).append(request).append(HTTP11);
+    return finReq.toString();
+  }
+
+  /**
+   * Clears the contents of TEST_PROPS
+   */
+  protected void clearTestProperties() {
+    TEST_PROPS.clear();
+  }
+
+  protected boolean isNullOrEmpty(String val) {
+    return val == null || val.trim().equals("");
+  }
+
+  private InetAddress[] _addrs = null;
+
+  protected String _servlet = null;
+
+  /**
+   * Sets the request, testname, and a search string for test passed. A search
+   * is also added for test failure. If found, the test will fail.
+   * 
+   * @param testValue
+   *          - a logical test identifier
+   * @param testCase
+   *          - the current test case
+   */
+  private void setApiTestProperties(String testValue, WebTestCase testCase) {
+    TestUtil.logTrace("[JAXRSCommonClient] setApiTestProperties");
+
+    if (testValue == null) {
+      return;
+    }
+
+    // An API test consists of a request with a request parameter of
+    // testname, a search string of Test PASSED, and a logical test name.
+
+    // set the testname
+    _testName = testValue;
+
+    // set the request
+    StringBuffer sb = new StringBuffer(50);
+    if ((_servlet != null)
+        && (TEST_PROPS.get(Property.DONOTUSEServletName) == null)) {
+      sb.append(GET).append(_contextRoot).append(SL);
+      sb.append(_servlet).append("?testname=").append(testValue);
+      sb.append(HTTP11);
+    } else {
+      sb.append(GET).append(_contextRoot).append(SL);
+      sb.append(testValue).append(HTTP10);
+    }
+    System.out.println("REQUEST LINE: " + sb.toString());
+
+    HttpRequest req = createHttpRequest(sb.toString(), _hostname, _port);
+    testCase.setRequest(req);
+
+    String value = TEST_PROPS.get(Property.SEARCH_STRING);
+    if (isNullOrEmpty(value)) {
+      testCase.setResponseSearchString(Data.PASSED);
+      testCase.setUnexpectedResponseSearchString(Data.FAILED);
+    }
+  }
+
+  protected HttpRequest createHttpRequest(String requestLine, String host,
+      int port) {
+    return new HttpRequest(requestLine, host, port);
+  }
+
+  /**
+   * Consists of a test name, a request, and a goldenfile.
+   * 
+   * @param testValue
+   *          - a logical test identifier
+   * @param testCase
+   *          - the current test case
+   */
+  private void setStandardProperties(String testValue, WebTestCase testCase) {
+    TestUtil.logTrace("[JAXRSCommonClient] setStandardProperties");
+
+    if (testValue == null) {
+      return;
+    }
+    // A standard test sets consists of a testname
+    // a request, and a goldenfile. The URI is not used
+    // in this case since the JSP's are assumed to be located
+    // at the top of the contextRoot
+    String req;
+
+    // set the testname
+    _testName = testValue;
+
+    if (_servlet != null) {
+      req = buildRequest(Request.GET, _servlet, "?testname=", testValue);
+    } else {
+      req = buildRequest10(Request.GET, testValue);
+    }
+    System.out.println("REQUEST LINE: " + req);
+    System.out.println("_hostname=" + _hostname);
+    HttpRequest httpReq = createHttpRequest(req, _hostname, _port);
+    testCase.setRequest(httpReq);
+
+    // set the goldenfile
+    StringBuffer sb = new StringBuffer(50);
+    sb.append(_tsHome).append(GOLDENFILEDIR);
+    sb.append(_generalURI).append(SL);
+    sb.append(testValue).append(GF_SUFFIX);
+    testCase.setGoldenFilePath(sb.toString());
+  }
+
+  /**
+   * Sets the name of the servlet to use when building a request for a single
+   * servlet API test.
+   * 
+   * @param servlet
+   *          - the name of the servlet
+   */
+  protected void setServletName(String servlet) {
+    TestUtil.logTrace("[JAXRSCommonClient] setServletName");
+    _servlet = servlet;
+  }
+
+  protected String getServletName() {
+    return _servlet;
+  }
+
+  protected String getLocalInterfaceInfo(boolean returnAddresses) {
+    String result = null;
+    initInetAddress();
+    if (_addrs.length != 0) {
+      StringBuffer sb = new StringBuffer(32);
+      if (!returnAddresses) {
+        // localhost might not show up if aliased
+        sb.append("localhost,");
+      } else {
+        // add 127.0.0.1
+        sb.append("127.0.0.1,");
+      }
+
+      for (int i = 0; i < _addrs.length; i++) {
+        if (returnAddresses) {
+          String ip = _addrs[i].getHostAddress();
+          if (!ip.equals("127.0.0.1")) {
+            if (ip.contains("%")) {
+              int scope_id = ip.indexOf("%");
+              ip = ip.substring(0, scope_id);
+            }
+            sb.append(ip);
+          }
+        } else {
+          String host = _addrs[i].getCanonicalHostName();
+          if (!host.equals("localhost")) {
+            sb.append(host);
+          }
+        }
+        if (i + 1 != _addrs.length) {
+          sb.append(",");
+        }
+      }
+      result = sb.toString();
+      TestUtil.logTrace("[AbstractUrlClient] Interface info: " + result);
+    }
+    return result;
+  }
+
+  private void initInetAddress() {
+    if (_addrs == null) {
+      try {
+        _addrs = InetAddress
+            .getAllByName(InetAddress.getLocalHost().getCanonicalHostName());
+      } catch (UnknownHostException uhe) {
+        TestUtil.logMsg(
+            "[AbstractUrlClient][WARNING] Unable to obtain local host information.");
+      }
+    }
+  }
+
+  protected String getAbsoluteUrl() {
+    return getAbsoluteUrl(null);
+  }
+
+  protected String getAbsoluteUrl(String method) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("http://").append(_hostname).append(":").append(_port)
+        .append(getContextRoot());
+    if (method != null)
+      sb.append("/").append(method);
+    return sb.toString();
+  }
+
+  /**
+   * This exception must be thrown to signify a
+   * test failure. Overrides 3 printStackTrace methods to preserve the original
+   * stack trace.
+   *
+   * @author Kyle Grucci
+   */
+
+  public static class Fault extends Exception {
+    private static final long serialVersionUID = -1574745208867827913L;
+
+    public Throwable t;
+
+    /**
+     * creates a Fault with a message
+     */
+    public Fault(String msg) {
+      super(msg);
+      TestUtil.logErr(msg);
+    }
+
+    /**
+     * creates a Fault with a message.
+     *
+     * @param msg
+     *          the message
+     * @param t
+     *          prints this exception's stacktrace
+     */
+    public Fault(String msg, Throwable t) {
+      super(msg);
+      this.t = t;
+      TestUtil.logErr(msg, t);
+    }
+
+    /**
+     * creates a Fault with a Throwable.
+     *
+     * @param t
+     *          the Throwable
+     */
+    public Fault(Throwable t) {
+      super(t);
+      this.t = t;
+    }
+
+    /**
+     * Prints this Throwable and its backtrace to the standard error stream.
+     *
+     */
+    public void printStackTrace() {
+      if (this.t != null) {
+        this.t.printStackTrace();
+      } else {
+        super.printStackTrace();
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print stream.
+     *
+     * @param s
+     *          <code>PrintStream</code> to use for output
+     */
+    public void printStackTrace(PrintStream s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    /**
+     * Prints this throwable and its backtrace to the specified print writer.
+     *
+     * @param s
+     *          <code>PrintWriter</code> to use for output
+     */
+    public void printStackTrace(PrintWriter s) {
+      if (this.t != null) {
+        this.t.printStackTrace(s);
+      } else {
+        super.printStackTrace(s);
+      }
+    }
+
+    @Override
+    public Throwable getCause() {
+      return t;
+    }
+
+    @Override
+    public synchronized Throwable initCause(Throwable cause) {
+      if (t != null)
+        throw new IllegalStateException("Can't overwrite cause");
+      if (!Exception.class.isInstance(cause))
+        throw new IllegalArgumentException("Cause not permitted");
+      this.t = (Exception) cause;
+      return this;
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java
new file mode 100644
index 0000000..269b5de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/Version.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common;
+
+/**
+ * There were references to the following versions of TCK:
+ * <p>
+ * 1.0 - The tests that used jakarta.ws.rs.tck.common.JAXRSCommonClient as
+ * a superclass.
+ * </p>
+ * <p>
+ * 1.1 - The tests that used jakarta.ws.rs.tck.common.JAXRSCommonClient as
+ * a superclass.
+ * </p>
+ * <p>
+ * 2.0 - The tests that used mainly
+ * jakarta.ws.rs.tck.common.client.JaxrsCommonClient, sometimes
+ * jakarta.ws.rs.tck.common.JAXRSCommonClient as a superclass.
+ * </p>
+ * <p>
+ * 2.0.1 - The code that has been created after JAXRS 2.0 TCK bundle has been
+ * built
+ * </p>
+ * <p>
+ * 2.1 - The code that has been created for JAXRS 2.1 TCK
+ * 
+ * @since 2.0.1
+ */
+public interface Version {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java
new file mode 100644
index 0000000..b6e0004
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheRequestAdapter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+
+public class ApacheRequestAdapter extends HttpRequest {
+
+  public ApacheRequestAdapter(String requestLine, String host, int port) {
+    super(requestLine, host, port);
+  }
+
+  /**
+   * <code>getRequestPath</code> returns the request path for this particular
+   * request.
+   *
+   * @return String request path
+   */
+  public String getRequestPath() {
+    return super.getRequestPath();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java
new file mode 100644
index 0000000..16eedcf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/ApacheResponseAdapter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+import java.io.IOException;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.apache.commons.httpclient.Header;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+public class ApacheResponseAdapter extends HttpResponse {
+
+  public ApacheResponseAdapter(jakarta.ws.rs.core.Response response, String host,
+      int port) {
+    super(host, port, port == 443, null, null);
+    this.response = response;
+    this.caser = TextCaser.NONE;
+  }
+
+  public ApacheResponseAdapter(jakarta.ws.rs.core.Response response, String host,
+      int port, TextCaser caser) {
+    this(response, host, port);
+    this.caser = caser;
+  }
+
+  private jakarta.ws.rs.core.Response response;
+
+  private String entity = null;
+
+  private TextCaser caser = null;
+
+  /**
+   * Returns the HTTP status code returned by the server
+   * 
+   * @return HTTP status code
+   */
+  public String getStatusCode() {
+    return Integer.toString(response.getStatus());
+  }
+
+  @Override
+  public String getResponseBodyAsString() throws IOException {
+    if (entity == null)
+      entity = response.readEntity(String.class);
+    return entity == null ? "" : caser.getCasedText(entity);
+  }
+
+  @Override
+  public String getResponseBodyAsRawString() throws IOException {
+    return getResponseBodyAsString();
+  }
+
+  @Override
+  public String getReasonPhrase() {
+    return response.toString();// getReasonPhrase();
+  }
+
+  @Override
+  public Header[] getResponseHeaders() {
+    List<Header> headers = new LinkedList<Header>();
+    MultivaluedMap<String, Object> mHeaders = response.getMetadata();
+    String[] sHeaders = JaxrsCommonClient.getMetadata(mHeaders);
+    for (String header : sHeaders) {
+      String[] split = header.split(":", 2);
+      headers.add(new Header(split[0], split[1]));
+    }
+    return headers.toArray(new Header[headers.size()]);
+  }
+
+  @Override
+  public Header getResponseHeader(String headerName) {
+    for (Header header : getResponseHeaders())
+      if (header.getName().equals(headerName))
+        return header;
+    return null;
+  }
+
+  @Override
+  public String getResponseEncoding() {
+    String encoding = null;
+    Header header = getResponseHeader("Content-Type");
+    if (header != null) {
+      String headerVal = header.getValue();
+      int idx = headerVal.indexOf(";charset=");
+      if (idx > -1) {
+        // content encoding included in response
+        encoding = headerVal.substring(idx + 9);
+      }
+    }
+    return encoding;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java
new file mode 100644
index 0000000..b16bda8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsCommonClient.java
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+import java.util.Enumeration;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+
+import jakarta.ws.rs.tck.lib.util.BASE64Encoder;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.validation.CheckOneOfStatusesTokenizedValidator;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.client.JaxrsWebTestCase.Execution;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+public class JaxrsCommonClient extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = 1L;
+
+  protected transient JaxrsWebTestCase testCase;
+
+  protected boolean isTestCaseAfterInvocation;
+
+  // list of clients to be closed automatically at cleanup
+  protected List<Client> clients = new LinkedList<Client>();
+
+  /**
+   * <PRE>
+   * Sets the appropriate test properties based
+   * on the values stored in TEST_PROPS
+   * </PRE>
+   */
+  protected void setTestProperties(JaxrsWebTestCase testCase) {
+    TestUtil.logTrace("[JAXRSCommonClient] setTestProperties");
+
+    if (TEST_PROPS.get(Property.STATUS_CODE) == null)
+      setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+    setWebTestCaseProperties(testCase);
+  }
+
+  protected void setWebTestCaseProperties(JaxrsWebTestCase testCase) {
+    Property key = null;
+    String value = null;
+    // process the remainder of the properties
+    for (Enumeration<Property> e = TEST_PROPS.keys(); e.hasMoreElements();) {
+      key = e.nextElement();
+      value = TEST_PROPS.get(key);
+      switch (key) {
+      case APITEST:
+        break;
+      case BASIC_AUTH_PASSWD:
+      case BASIC_AUTH_REALM:
+        break;
+      case BASIC_AUTH_USER:
+        String user = TEST_PROPS.get(Property.BASIC_AUTH_USER);
+        String password = TEST_PROPS.get(Property.BASIC_AUTH_PASSWD);
+        String base64 = new BASE64Encoder()
+            .encode((user + ":" + password).getBytes());
+        testCase.addHeader("Authorization", " Basic " + base64);
+        break;
+      case CONTENT:
+        // req.setContent(value);
+        testCase.setEntity(value);
+        break;
+      case DONOTUSEServletName:
+        break;
+      case EXPECT_RESPONSE_BODY:
+        // FIXME
+        // setExpectResponseBody(false);
+        break;
+      case EXPECTED_HEADERS:
+        testCase.addExpectedHeader(value);
+        break;
+      case FOLLOW_REDIRECT:
+        TestUtil.logTrace("##########Found redirect Property");
+        _redirect = true;
+        break;
+      case GOLDENFILE:
+        StringBuffer sb = new StringBuffer(50);
+        sb.append(_tsHome).append(GOLDENFILEDIR);
+        sb.append(_generalURI).append(SL);
+        sb.append(value);
+        testCase.setGoldenFilePath(sb.toString());
+        break;
+      case IGNORE_BODY:
+        // FIXME
+        // setIgnoreResponseBody(true);
+        testCase.setGoldenFilePath(null);
+        break;
+      case IGNORE_STATUS_CODE:
+        testCase.setExpectedStatusCode("-1");
+        break;
+      case REASON_PHRASE:
+        testCase.setExpectedReasonPhrase(value);
+        break;
+      case REQUEST:
+        testCase.setUrlRequest(value);
+        break;
+      case REQUEST_HEADERS:
+        String[] headers = splitByColon(value);
+        for (String header : headers) {
+          String[] split = header.split(":", 2);
+          testCase.addHeader(split[0].trim(), split[1].trim());
+        }
+        break;
+      case RESPONSE_MATCH:
+        // setResponseMatch(TEST_PROPS.getProperty(key));
+        break;
+      case SAVE_STATE:
+        _saveState = true;
+        break;
+      case SEARCH_STRING:
+        value = testCase.getTextCaser().getCasedText(value);
+        testCase.setResponseSearchString(value);
+        break;
+      case SEARCH_STRING_IGNORE_CASE:
+        testCase.setResponseSearchStringIgnoreCase(value);
+        break;
+      case STANDARD:
+        break;
+      case STATUS_CODE:
+        if (value.contains("|"))
+          testCase.setStrategy(
+              CheckOneOfStatusesTokenizedValidator.class.getName());
+        testCase.setExpectedStatusCode(value);
+        break;
+      case STRATEGY:
+        testCase.setStrategy(value);
+        break;
+      case TEST_NAME:
+        // testName = TEST_PROPS.getProperty(key);
+        break;
+      case UNEXPECTED_HEADERS:
+        testCase.addUnexpectedHeader(value);
+        break;
+      case UNEXPECTED_RESPONSE_MATCH:
+        testCase.setUnexpectedResponseSearchString(value);
+        break;
+      case UNORDERED_SEARCH_STRING:
+        value = testCase.getTextCaser().getCasedText(value);
+        testCase.setUnorderedSearchString(value);
+        break;
+      case USE_SAVED_STATE:
+        _useSavedState = true;
+        break;
+      }
+    }
+  }
+
+  /**
+   * Replaces String#split("|"), as it does not split for special character '|'
+   */
+  protected static String[] splitByColon(String value) {
+    int colonIndex = -1, lastIndex = 0;
+    LinkedList<String> list = new LinkedList<String>();
+    while ((colonIndex = value.indexOf('|', lastIndex)) != -1) {
+      list.add(value.substring(lastIndex, colonIndex));
+      lastIndex = colonIndex + 1;
+    }
+    if (lastIndex < value.length())
+      list.add(value.substring(lastIndex));
+    return list.toArray(new String[list.size()]);
+  }
+
+  /**
+   * <PRE>
+   * Invokes a test based on the properties
+   * stored in TEST_PROPS.  Once the test has completed,
+   * the properties in TEST_PROPS will be cleared.
+   * </PRE>
+   *   
+   *  @throws Fault
+   *           If an error occurs during the test run
+   */
+  protected void invoke() throws Fault {
+    TestUtil.logTrace("[JAXRSCommonClient] invoke");
+    try {
+      getTestCase().setPort(_port);
+      getTestCase().setHostname(_hostname);
+      setTestProperties(testCase);
+      TestUtil.logTrace("[JAXRSCommonClient] EXECUTING");
+      if (_useSavedState && _state != null) {
+        testCase.getRequest().setState(_state);
+      }
+      if (_redirect != false) {
+        TestUtil.logTrace("##########Call setFollowRedirects");
+        testCase.getRequest().setFollowRedirects(_redirect);
+      }
+      testCase.execute();
+      isTestCaseAfterInvocation = true;
+      if (_saveState) {
+        _state = testCase.getResponse().getState();
+      }
+    } catch (TestFailureException tfe) {
+      Throwable t = tfe.getRootCause();
+      if (t != null) {
+        TestUtil.logErr("Root cause of Failure: " + t.getMessage(), t);
+      }
+      throw new Fault("[JAXRSCommonClient] " + _testName
+          + " failed!  Check output for cause of failure.", tfe);
+    } finally {
+      _useSavedState = false;
+      _saveState = false;
+      _redirect = false;
+      clearTestProperties();
+      clients.add(testCase.client);
+    }
+  }
+
+  @Override
+  public void cleanup() throws Fault{
+    super.cleanup();
+    // The client.close has to be called on cleanup, because after invoke,
+    // some methods are called and resources might not be available then
+    // (javadoc: Close client instance and all it's associated resources).
+    // Since more invoke() invocations are possible, the clients are stored
+    // in a list to be closed on cleanup
+    for (Client c : clients)
+      c.close();
+    clients.clear();
+  }
+
+  /*public void setup(String[] args, Properties p) {
+    super.setup(args, p);
+    String property = System.getProperty("cts.tmp");
+    if (property != null)
+      System.setProperty("java.io.tmpdir", property);
+  }*/
+
+  protected JaxrsWebTestCase getTestCase() {
+    if (testCase == null || isTestCaseAfterInvocation) {
+      testCase = new JaxrsWebTestCase();
+      isTestCaseAfterInvocation = false;
+    }
+    return testCase;
+  }
+
+  @Override
+  protected String buildRequest(Request type, String... path) {
+    getTestCase().setRequestType(type.name());
+    StringBuilder sb = new StringBuilder();
+    sb.append(_contextRoot == null ? "" : _contextRoot).append(SL);
+    for (String segment : path)
+      sb.append(segment);
+    return sb.toString();
+  }
+
+  @Override
+  @Deprecated
+  protected void setProperty(String key, String value) {
+    super.setProperty(key, value);
+  }
+
+  @Override
+  @Deprecated
+  protected String buildRequest(String type, String... path) {
+    return super.buildRequest(type, path);
+  }
+
+  protected Response getResponse() {
+    return testCase.getJaxrsResponse();
+  }
+
+  @Override
+  protected String getResponseBody() {
+    return getResponseBody(String.class);
+  }
+
+  protected <T> T getResponseBody(Class<T> clazz) {
+    return getResponse().readEntity(clazz);
+  }
+
+  public List<Object> getProvidersToRegister() {
+    return getTestCase().getProvidersToRegister();
+  }
+
+  public void addProvider(Object providerToRegister) {
+    getTestCase().addProviderToRegister(providerToRegister);
+  }
+
+  @Override
+  protected String[] getResponseHeaders() throws Fault {
+    return getMetadata(getResponse().getMetadata());
+  }
+
+  /**
+   * Calls setHeader(Property.REQUEST_HEADERS, header : values);
+   * 
+   * @param header
+   *          Recommended one of HttpHeaders static values
+   * @param values
+   *          the value[1]value[2]...value[n] which are to be assigned to
+   *          {@code}header name
+   */
+  protected void addHeader(String header, String... values) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(header).append(":");
+    if (values != null)
+      for (String value : values)
+        sb.append(value);
+    setProperty(Property.REQUEST_HEADERS, sb.toString());
+  }
+
+  /**
+   * This method is typically used to transform http headers metadata into a
+   * String array. The headers are in a form of java class instance, e.g.
+   * stream(!), or String
+   * 
+   * @param metadata
+   * @return
+   */
+  public static String[] getMetadata(MultivaluedMap<String, Object> metadata) {
+    String[] headers = new String[metadata.size()];
+    int i = 0;
+    for (Entry<String, List<Object>> e : metadata.entrySet()) {
+      headers[i++] = e.getKey() + ":" + listToString(e.getValue());
+    }
+    return headers;
+  }
+
+  @Override
+  protected Status getResponseStatusCode() {
+    return Status.fromStatusCode(getResponse().getStatus());
+  }
+
+  protected void setRequestContentEntity(Object object) {
+    getTestCase().setEntity(object);
+  }
+
+  public static <T> String listToString(List<T> list) {
+    StringBuilder sb = new StringBuilder();
+    for (T s : list)
+      sb.append(s).append(" ");
+    return sb.toString().trim();
+  }
+
+  protected void printClientCall(boolean print) {
+    getTestCase().setPrintClientCall(print);
+  }
+
+  protected void setAsynchronousProcessing() {
+    getTestCase().setProcessingType(Execution.ASYNCHRONOUS);
+  }
+
+  protected void setPrintEntity(boolean printEntity) {
+    getTestCase().setPrintEntity(printEntity);
+  }
+
+  protected void bufferEntity(boolean buffer) {
+    getTestCase().bufferEntity(buffer);
+  }
+
+  protected void setTextCaser(TextCaser caser) {
+    getTestCase().setTextCaser(caser);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java
new file mode 100644
index 0000000..82cb16c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JaxrsWebTestCase.java
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.Future;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationFactory;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationStrategy;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Replaces WebTestCase to be used with JAXRS client instead of apache client
+ * 
+ * @author supol
+ */
+public class JaxrsWebTestCase extends WebTestCase {
+
+  /**
+   * The JAXRS request instance
+   */
+  protected Request request;
+
+  /**
+   * The JAXRS response instance
+   */
+  protected Response response;
+
+  /**
+   * GET, PUT, OPTIONS, ...
+   */
+  protected String requestType;
+
+  /**
+   * The URL of the Request
+   */
+  protected String urlRequest;
+
+  /**
+   * The HTTP content entity. A MessageBodyWriter<entity.getClass()> needs to be
+   * registered if not a standard entity type supported by JAXRS
+   */
+  protected Object entity;
+
+  /**
+   * port of the server
+   */
+  protected int port;
+
+  /**
+   * host name of the server
+   */
+  protected String hostname;
+
+  /**
+   * HTTP header list
+   */
+  protected Map<String, String> headerMap;
+
+  /**
+   * Apache HTTP response mock
+   */
+  protected HttpResponse _response;
+
+  /**
+   * print the response entity
+   */
+  protected boolean printEntity = true;
+
+  /**
+   * buffer the returned entity
+   */
+  protected boolean bufferEntity = false;
+
+  /**
+   * Provider logging the request and response
+   */
+  protected Object loggingFilter;
+
+  /**
+   * other providers, such as MessageBodyReader, or MessageBodyWriter
+   */
+  protected List<Object> providersToRegister;
+
+  /**
+   * Strategy to use when validating the test case against the server's
+   * response.
+   */
+  protected ValidationStrategy strategy = null;
+
+  /**
+   * Show the call client code, used to be printed when report issues
+   */
+  protected boolean printClientCall = false;
+
+  /**
+   * Upper case, lower case, or exact text matching?
+   */
+  protected TextCaser textCaser = TextCaser.NONE;
+
+  /**
+   * Type of execution
+   */
+  protected enum Execution {
+    SYNCHRONOUS, ASYNCHRONOUS
+  }
+
+  /**
+   * Runnable to run while asynchronous
+   */
+  protected Runnable asyncRunnable;
+
+  /**
+   * Execution type instance
+   */
+  protected Execution executionType = Execution.SYNCHRONOUS;
+
+  /**
+   * Client instance here not to be garbage collected before end of test.
+   */
+  protected Client client;
+
+  public JaxrsWebTestCase() {
+    strategy = ValidationFactory.getInstance(TOKENIZED_STRATEGY);
+    headerMap = new HashMap<String, String>();
+    providersToRegister = new LinkedList<Object>();
+    closeClient();
+  }
+
+  /**
+   * Sets the validation strategy for this test case instance.
+   * 
+   * @param validator
+   *          - the fully qualified class name of the response validator to use.
+   */
+  public void setStrategy(String validator) {
+    ValidationStrategy strat = ValidationFactory.getInstance(validator);
+    if (strat != null) {
+      strategy = strat;
+    } else {
+      StringBuilder sb = new StringBuilder();
+      sb.append("[WebTestCase][WARNING] An attempt was made to use a ");
+      sb.append("non-existing validator (");
+      sb.append(validator);
+      sb.append(").  Falling back to the TokenizedValidator");
+      TestUtil.logMsg(sb.toString());
+    }
+  }
+
+  // /**
+  //  * Executes the test case.
+  //  * 
+  //  * @throws TestFailureException
+  //  *           if the test fails for any reason.
+  //  * @throws IllegalStateException
+  //  *           if no request was configured or if no Validator is available at
+  //  *           runtime.
+  //  */
+  // public void execute() throws TestFailureException {
+  //   verifyValidationStrategy();
+  //   verifySettings();
+  //   try {
+  //     String url = logClientRequestAndGetUrl();
+
+  //     client = getClientWithRegisteredProviders();
+  //     WebTarget target = client.target(url.toString());
+  //     Invocation i = buildRequest(target);
+  //     response = invoke(i);
+  //     if (bufferEntity)
+  //       response.bufferEntity();
+  //   } catch (Throwable t) {
+  //     String message = t.getMessage();
+
+  //     StringBuilder sb = new StringBuilder();
+  //     sb.append("[FATAL] Unexpected failure during test execution.\n");
+  //     // print client call code to report into JIRA when needed
+  //     sb.append(printClientCall().toString());
+  //     // Inherited message
+  //     sb.append((message == null ? t.toString() : message));
+
+  //     throw new TestFailureException(sb.toString(), t);
+  //   }
+
+  //   // Validate this test case instance
+  //   if (!strategy.validate(this)) {
+  //     throw new TestFailureException("Test FAILED!");
+  //   }
+  // }
+
+  public void closeClient() {
+    if (client != null)
+      client.close();
+    client = null;
+  }
+
+  protected void verifyValidationStrategy() {
+    // If no strategy instance is available (strange, but has happened),
+    // fail.
+    try {
+      getStrategy();
+    } catch (NullPointerException e) {
+      throw new IllegalStateException("[FATAL] No Validator available.");
+    }
+  }
+
+  protected void verifySettings() throws TestFailureException {
+    if (hostname == null)
+      throw new TestFailureException("No hostname set");
+    if (port == 0)
+      throw new TestFailureException("Port not set");
+    if (requestType == null)
+      throw new TestFailureException("No request method set");
+    if (urlRequest == null)
+      throw new TestFailureException("No resource url request set");
+  }
+
+  // /**
+  //  * @return Client with all providers already registered
+  //  */
+  // protected Client getClientWithRegisteredProviders() {
+  //   Client client = ClientBuilder.newClient();
+  //   client.register(new JdkLoggingFilter(isPrintedEntity()));
+  //   for (Object o : providersToRegister)
+  //     if (o instanceof Class)
+  //       client.register((Class<?>) o); // otherwise it does not work
+  //     else
+  //       client.register(o);
+  //   return client;
+  // }
+
+  protected String logClientRequestAndGetUrl() {
+    StringBuilder url = new StringBuilder();
+    url.append("http://").append(hostname).append(":").append(port);
+    url.append(urlRequest);
+
+    StringBuilder msg = new StringBuilder();
+    msg.append("[Request] Dispatching request: '").append(requestType)
+        .append(" ").append(url).append("' to target server at '")
+        .append(hostname).append(":").append(port).append("'");
+    TestUtil.logMsg(msg.toString());
+    TestUtil.logMsg("###############################");
+
+    if (printClientCall)
+      TestUtil.logMsg(printClientCall().toString());
+
+    return url.toString();
+  }
+
+  /**
+   * Log java code executed
+   */
+  protected StringBuilder printClientCall() {
+    StringBuilder url = new StringBuilder();
+    url.append("http://").append(hostname).append(":").append(port);
+    url.append(urlRequest);
+
+    StringBuilder sb = new StringBuilder();
+    // print client call code to report into JIRA when needed
+    sb.append("Client client = ClientFactory.newClient();\n");
+    for (Object o : providersToRegister) {
+      sb.append("client.configuration().register(");
+      if (o instanceof Class)
+        sb.append(((Class<?>) o).getName()).append(".class");
+      else
+        sb.append(o.getClass().getName());
+      sb.append(");\n");
+    }
+    sb.append("WebTarget target = client.target(\"").append(url.toString())
+        .append("\");\n");
+    sb.append("Invocation.Builder builder;\n");
+    sb.append("builder = target.request(\"").append(getAcceptMediaType())
+        .append("\");\n");
+    for (Entry<String, String> entry : headerMap.entrySet()) {
+      sb.append("builder.header(\"").append(entry.getKey()).append("\",\"")
+          .append(entry.getValue()).append("\");\n");
+    }
+    sb.append("Invocation i;\n");
+    sb.append("i=builder.build(\"").append(requestType).append("\"");
+    if (entity != null)
+      sb.append(",").append("Entity.entity(").append(entity.toString())
+          .append(",").append(getContentType());
+    sb.append(");\n");
+    sb.append("i.invoke();\n");
+
+    return sb;
+  }
+
+  /**
+   * Build Invocation
+   */
+  protected Invocation buildRequest(WebTarget target) {
+    Invocation.Builder builder;
+    builder = target.request(getAcceptMediaType());
+    for (Entry<String, String> entry : headerMap.entrySet()) {
+      if (!entry.getKey().equals("Accept"))
+        builder.header(entry.getKey(), entry.getValue());
+    }
+    Invocation i;
+    if (entity != null) {
+      if (entity instanceof Entity)
+        i = builder.build(requestType, (Entity<?>) entity);
+      else
+        i = builder.build(requestType, Entity.entity(entity, getContentType()));
+      TestUtil.logMsg("[Request] Adding entity: " + entity);
+    } else
+      i = builder.build(requestType);
+    return i;
+  }
+
+  /**
+   * Invoke the invocation synchronously, or asynchronously
+   */
+  protected Response invoke(Invocation invocation) throws TestFailureException {
+    Response response = null;
+    switch (executionType) {
+    case SYNCHRONOUS:
+      response = invocation.invoke();
+      break;
+    case ASYNCHRONOUS:
+      int cnt = 0;
+      try {
+        final boolean[] buffered = { false };
+        InvocationCallback<Response> callback = new InvocationCallback<Response>() {
+          @Override
+          public void completed(Response res) {
+            try {
+              JaxrsWebTestCase.this.response = res;
+              // buffer before stream is closed
+              getResponse().getResponseBodyAsString();
+              buffered[0] = true;
+            } catch (IOException e) {
+              throw new RuntimeException(e);
+            }
+          }
+
+          @Override
+          public void failed(Throwable throwable) {
+            throw new RuntimeException(throwable);
+          }
+        };
+        Future<Response> future = invocation.submit(callback);
+        while (!buffered[0] && cnt++ < 50) {
+          Thread.sleep(100L);
+        }
+        response = future.get();
+        // response = invocation.submit().get();
+      } catch (Exception e) {
+        throw new TestFailureException(e);
+      }
+      if (cnt > 49) {
+        throw new TestFailureException(
+            "Invocation callback has not been called within 5 second");
+      }
+    }
+    return response;
+  }
+
+  /**
+   * Get media type in Request Content Type
+   */
+  protected String getAcceptMediaType() {
+    String media = headerMap.get("Accept");
+    if (media == null)
+      media = MediaType.WILDCARD;
+    return media;
+  }
+
+  /**
+   * Get media type in Request Content Type
+   */
+  protected String getContentType() {
+    String media = headerMap.get("Content-Type");
+    if (media == null)
+      media = MediaType.WILDCARD;
+    return media;
+  }
+
+  // ---------------------------------------------------------------------
+  // Apache adaptor methods
+
+  @Override
+  public HttpRequest getRequest() {
+    if (super.getRequest() == null) {
+      StringBuilder sb = new StringBuilder();
+      sb.append(requestType).append(" ").append(urlRequest).append("/");
+      sb.append(" HTTP/1.1");
+      super.setRequest(new ApacheRequestAdapter(sb.toString(), hostname, port));
+    }
+    return super.getRequest();
+  }
+
+  @Override
+  public synchronized HttpResponse getResponse() {
+    if (_response == null) {
+      _response = new ApacheResponseAdapter(response, hostname, port,
+          textCaser);
+    }
+    return _response;
+  }
+
+  // ---------------------------------------------------------------------
+  // Getters and Setters
+
+  public void setRequestType(String requestType) {
+    this.requestType = requestType;
+  }
+
+  public int getPort() {
+    return port;
+  }
+
+  public void setPort(int port) {
+    this.port = port;
+  }
+
+  public String getHostname() {
+    return hostname;
+  }
+
+  public void setHostname(String hostname) {
+    this.hostname = hostname;
+  }
+
+  public String getUrlRequest() {
+    return urlRequest;
+  }
+
+  public void setUrlRequest(String urlRequest) {
+    this.urlRequest = urlRequest;
+  }
+
+  public void addHeader(String name, String value) {
+    headerMap.put(name, value);
+  }
+
+  public Response getJaxrsResponse() {
+    return response;
+  }
+
+  public void setEntity(Object entity) {
+    this.entity = entity;
+  }
+
+  /**
+   * Returns the Request for this particular test case.
+   * 
+   * @return Request of this test case
+   */
+  public Request getJaxrsRequest() {
+    return request;
+  }
+
+  public boolean isPrintedEntity() {
+    return printEntity;
+  }
+
+  /**
+   * Set whether the entity is to be printed in trace log or not;
+   */
+  public void setPrintEntity(boolean printEntity) {
+    this.printEntity = printEntity;
+  }
+
+  public void bufferEntity(boolean bufferEntity) {
+    this.bufferEntity = bufferEntity;
+  }
+
+  public List<Object> getProvidersToRegister() {
+    return providersToRegister;
+  }
+
+  public void addProviderToRegister(Object providerToRegister) {
+    this.providersToRegister.add(providerToRegister);
+  }
+
+  public void setPrintClientCall(boolean print) {
+    printClientCall = print;
+  }
+
+  public void setProcessingType(Execution type) {
+    executionType = type;
+  }
+
+  public TextCaser getTextCaser() {
+    return textCaser;
+  }
+
+  public void setTextCaser(TextCaser textCaser) {
+    this.textCaser = textCaser;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java
new file mode 100644
index 0000000..971f9c4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/JdkLoggingFilter.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.ConsoleHandler;
+import java.util.logging.Formatter;
+import java.util.logging.LogRecord;
+import java.util.logging.Logger;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(Integer.MAX_VALUE)
+public class JdkLoggingFilter extends Formatter
+    implements ClientRequestFilter, ClientResponseFilter {
+
+  private static final Logger LOGGER = Logger
+      .getLogger(JdkLoggingFilter.class.getName());
+
+  private static final String REQUEST_PREFIX = ">> ";
+
+  private static final String RESPONSE_PREFIX = "<< ";
+
+  //
+  private final DateFormat df = new SimpleDateFormat("MM-dd-yyyy HH:mm:ss");
+
+  private final Logger logger;
+
+  private boolean printEntity = true;
+
+  /**
+   * Create a logging filter logging the request and response to a default JDK
+   * logger, named as the fully qualified class name of this class.
+   */
+  public JdkLoggingFilter(boolean printEntity) {
+    this(LOGGER, printEntity);
+  }
+
+  /**
+   * Create a logging filter with custom logger and custom settings of entity
+   * logging.
+   * 
+   * @param logger
+   *          the logger to log requests and responses.
+   * @param printEntity
+   *          if true, entity will be logged as well.
+   */
+  public JdkLoggingFilter(Logger logger, boolean printEntity) {
+    this.logger = logger;
+    this.printEntity = printEntity;
+
+    ConsoleHandler handler = new ConsoleHandler();
+    logger.setUseParentHandlers(false);
+    handler.setFormatter(this);
+
+    // Set handler only once
+    if (logger.getHandlers().length == 0)
+      logger.addHandler(handler);
+  }
+
+  @Override
+  public void filter(ClientRequestContext arg0,
+      ClientResponseContext responseContext) throws IOException {
+    printResponseLine(responseContext.getStatus());
+    printPrefixedHeaders(RESPONSE_PREFIX, responseContext.getHeaders());
+    if (printEntity && responseContext.hasEntity()) {
+      List<String> entity = replaceEntityStream(responseContext);
+      log(RESPONSE_PREFIX, entity);
+    }
+
+  }
+
+  @Override
+  public void filter(ClientRequestContext requestContext) throws IOException {
+    printRequestLine(requestContext.getMethod(), requestContext.getUri());
+    MultivaluedMap<String, Object> headers = requestContext.getHeaders();
+    StringBuilder sb = new StringBuilder().append(REQUEST_PREFIX);
+    for (String header : JaxrsCommonClient.getMetadata(headers)) {
+      if (sb.length() > REQUEST_PREFIX.length())
+        sb.append(", ");
+      sb.append(header);
+    }
+    log(sb);
+    if (printEntity && requestContext.hasEntity()) {
+      log(new StringBuilder().append(REQUEST_PREFIX)
+          .append(requestContext.getEntity().toString()));
+    }
+  }
+
+  private static List<String> replaceEntityStream(ClientResponseContext ctx)
+      throws IOException {
+    List<String> entity = null;
+    if (ctx.hasEntity()) {
+      InputStream is = ctx.getEntityStream();
+      entity = readEntityFromStream(is);
+      ByteArrayInputStream bais = new ByteArrayInputStream(
+          linesToBytes(entity));
+      ctx.setEntityStream(bais);
+    }
+    return entity;
+  }
+
+  private static byte[] linesToBytes(List<String> lines) {
+    StringBuilder sb = new StringBuilder();
+    for (Iterator<String> i = lines.iterator(); i.hasNext();) {
+      sb.append(i.next());
+      if (i.hasNext())
+        sb.append("\n");
+    }
+    return sb.toString().getBytes();
+  }
+
+  private static List<String> readEntityFromStream(InputStream is)
+      throws IOException {
+    String entity;
+    List<String> lines = new LinkedList<String>();
+    InputStreamReader isr = new InputStreamReader(is);
+    BufferedReader br = new BufferedReader(isr);
+    while ((entity = br.readLine()) != null)
+      lines.add(entity);
+    return lines;
+  }
+
+  private void log(StringBuilder b) {
+    if (logger != null)
+      logger.info(b.append("\n").toString());
+  }
+
+  private void log(String prefix, List<String> rows) {
+    if (logger != null && rows != null)
+      for (String row : rows)
+        logger.info(new StringBuilder().append(prefix).append(row).append("\n")
+            .toString());
+  }
+
+  private void printRequestLine(String method, URI uri) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(REQUEST_PREFIX).append(method).append(" ")
+        .append(uri.toASCIIString());
+    log(sb);
+  }
+
+  private void printResponseLine(int status) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(RESPONSE_PREFIX).append(status).append(" ")
+        .append(Response.Status.fromStatusCode(status).name());
+    log(sb);
+  }
+
+  private void printPrefixedHeaders(final String prefix,
+      Map<String, List<String>> headers) {
+    for (Map.Entry<String, List<String>> e : headers.entrySet()) {
+      StringBuilder sb = new StringBuilder();
+      List<String> val = e.getValue();
+      String header = e.getKey();
+
+      if (val.size() == 1) {
+        sb.append(prefix).append(header).append(": ").append(val.get(0));
+      } else {
+        StringBuilder sb2 = new StringBuilder();
+        for (String s : val) {
+          if (sb2.length() != 0)
+            sb2.append(',');
+          sb2.append(s);
+        }
+        sb.append(prefix).append(header).append(": ").append(sb2.toString());
+      }
+      if (sb.length() != 0)
+        log(sb);
+    }
+
+  }
+
+  @Override
+  public String format(LogRecord record) {
+    StringBuilder sb = new StringBuilder();
+    sb.append(df.format(new Date(record.getMillis()))).append(":  ")
+        .append("TRACE: [WIRE] - ");
+    sb.append(formatMessage(record));
+    return sb.toString();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java
new file mode 100644
index 0000000..4e454da
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/client/TextCaser.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.client;
+
+/**
+ * Standard WebTestCase can search strings in an order case sensitive, case
+ * insensitive or not in order case sensitive. When there is a need to match not
+ * in order and case insensitive, this class is used.
+ */
+public enum TextCaser {
+  UPPER, NONE, LOWER;
+
+  /**
+   * Get the text upper cased, lower cased, or unchanged, depending on current
+   * TextCaser value
+   */
+  public final String getCasedText(String text) {
+    String ret = null;
+    switch (this) {
+    case UPPER:
+      ret = text.toUpperCase();
+      break;
+    case LOWER:
+      ret = text.toLowerCase();
+      break;
+    case NONE:
+      ret = text;
+      break;
+    }
+    return ret;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java
new file mode 100644
index 0000000..4cd4db4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/SinglevaluedMap.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+ package jakarta.ws.rs.tck.common.impl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+
+public class SinglevaluedMap<K, V> implements MultivaluedMap<K, V> {
+
+  Map<K, V> map = new HashMap<K, V>();
+
+  @Override
+  public int size() {
+    return map.size();
+  }
+
+  @Override
+  public boolean isEmpty() {
+    return map.isEmpty();
+  }
+
+  @Override
+  public boolean containsKey(Object key) {
+    return map.containsKey(key);
+  }
+
+  @Override
+  public boolean containsValue(Object value) {
+    return map.containsValue(value);
+  }
+
+  @Override
+  public List<V> get(Object key) {
+    return Collections.singletonList(map.get(key));
+  }
+
+  @Override
+  public List<V> put(K key, List<V> value) {
+    V v;
+    if (value == null)
+      v = map.put(key, null);
+    else
+      v = map.put(key, value.iterator().next());
+    return Collections.singletonList(v);
+  }
+
+  @Override
+  public List<V> remove(Object key) {
+    return Collections.singletonList(map.remove(key));
+  }
+
+  @Override
+  public void putAll(Map<? extends K, ? extends List<V>> m) {
+    for (Entry<? extends K, ? extends List<V>> e : m.entrySet())
+      map.put(e.getKey(), e.getValue().iterator().next());
+  }
+
+  @Override
+  public void clear() {
+    map.clear();
+  }
+
+  @Override
+  public Set<K> keySet() {
+    return map.keySet();
+  }
+
+  @Override
+  public Collection<List<V>> values() {
+    Collection<List<V>> col = new ArrayList<List<V>>();
+    for (V v : map.values())
+      col.add(Collections.singletonList(v));
+    return col;
+  }
+
+  @Override
+  public Set<java.util.Map.Entry<K, List<V>>> entrySet() {
+    Map<K, List<V>> adapter = new HashMap<K, List<V>>();
+    for (Entry<K, V> e : map.entrySet())
+      adapter.put(e.getKey(), Collections.singletonList(e.getValue()));
+    return adapter.entrySet();
+  }
+
+  @Override
+  public void add(K key, V value) {
+    map.put(key, value);
+  }
+
+  @Override
+  public V getFirst(K key) {
+    return map.get(key);
+  }
+
+  @Override
+  public void putSingle(K key, V value) {
+    map.put(key, value);
+  }
+
+  @Override
+  public void addAll(K key, V... value) {
+    if (value != null)
+      putSingle(key, value[0]);
+  }
+
+  @Override
+  public void addAll(K arg0, List<V> arg1) {
+    if (arg1.iterator().hasNext())
+      putSingle(arg0, arg1.iterator().next());
+  }
+
+  @Override
+  public void addFirst(K arg0, V arg1) {
+    putSingle(arg0, arg1);
+  }
+
+  @Override
+  public boolean equalsIgnoreValueOrder(MultivaluedMap<K, V> arg0) {
+    for (java.util.Map.Entry<K, List<V>> set : arg0.entrySet()) {
+      if (!map.containsKey(set.getKey()))
+        return false;
+      if (!map.containsValue(set.getValue().iterator().next()))
+        return false;
+    }
+    return true;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java
new file mode 100644
index 0000000..8139699
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/impl/TRACE.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.impl;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.HttpMethod;
+
+@HttpMethod("TRACE")
+@Target(value = ElementType.METHOD)
+@Retention(value = RetentionPolicy.RUNTIME)
+public @interface TRACE {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java
new file mode 100644
index 0000000..6b6a51b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBean.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.provider;
+
+/**
+ * This is the object which standard implementation does not have a provider
+ * for, even though its some simple String holder. It can also be used as
+ * mutable string.
+ */
+public class StringBean {
+  private String header;
+
+  public String get() {
+    return header;
+  }
+
+  public void set(String header) {
+    this.header = header;
+  }
+
+  @Override
+  public String toString() {
+    return "StringBean. To get a value, use rather #get() method.";
+  }
+
+  public StringBean(String header) {
+    super();
+    this.header = header;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java
new file mode 100644
index 0000000..283770c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanHeaderDelegate.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.provider;
+
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.RuntimeDelegate.HeaderDelegate;
+
+@Provider
+public class StringBeanHeaderDelegate implements HeaderDelegate<StringBean> {
+
+  @Override
+  public StringBean fromString(String string) throws IllegalArgumentException {
+    return new StringBean(string);
+  }
+
+  @Override
+  public String toString(StringBean bean) throws IllegalArgumentException {
+    return bean.get();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java
new file mode 100644
index 0000000..309d8cb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanRuntimeDelegate.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+ package jakarta.ws.rs.tck.common.provider;
+
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.EntityPart;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.Variant.VariantListBuilder;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+import java.util.concurrent.CompletionStage;
+
+import jakarta.ws.rs.SeBootstrap;
+import jakarta.ws.rs.SeBootstrap.Instance;
+
+public class StringBeanRuntimeDelegate extends RuntimeDelegate {
+
+  public StringBeanRuntimeDelegate(RuntimeDelegate orig) {
+    super();
+    this.original = orig;
+    assertNotStringBeanRuntimeDelegate(orig);
+  }
+
+  private RuntimeDelegate original;
+
+  @Override
+  public <T> T createEndpoint(Application arg0, Class<T> arg1)
+      throws IllegalArgumentException, UnsupportedOperationException {
+    return original.createEndpoint(arg0, arg1);
+  }
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> HeaderDelegate<T> createHeaderDelegate(Class<T> arg0)
+      throws IllegalArgumentException {
+    if (arg0 == StringBean.class)
+      return (HeaderDelegate<T>) new StringBeanHeaderDelegate();
+    else
+      return original.createHeaderDelegate(arg0);
+  }
+
+  @Override
+  public ResponseBuilder createResponseBuilder() {
+    return original.createResponseBuilder();
+  }
+
+  @Override
+  public UriBuilder createUriBuilder() {
+    return original.createUriBuilder();
+  }
+
+  @Override
+  public VariantListBuilder createVariantListBuilder() {
+    return original.createVariantListBuilder();
+  }
+
+  @Override
+  public EntityPart.Builder createEntityPartBuilder(String partName) {
+    return original.createEntityPartBuilder(partName);
+  }
+
+  @Override
+  public CompletionStage<Instance> bootstrap(Application application, SeBootstrap.Configuration configuration) {
+    return original.bootstrap(application, configuration);
+  }
+
+  @Override
+  public SeBootstrap.Configuration.Builder createConfigurationBuilder() {
+    return original.createConfigurationBuilder();
+  }
+
+  public RuntimeDelegate getOriginal() {
+    return original;
+  }
+
+  public static final void assertNotStringBeanRuntimeDelegate() {
+    RuntimeDelegate delegate = RuntimeDelegate.getInstance();
+    assertNotStringBeanRuntimeDelegate(delegate);
+  }
+
+  public static final//
+  void assertNotStringBeanRuntimeDelegate(RuntimeDelegate delegate) {
+    if (delegate instanceof StringBeanRuntimeDelegate) {
+      StringBeanRuntimeDelegate sbrd = (StringBeanRuntimeDelegate) delegate;
+      if (sbrd.getOriginal() != null)
+        RuntimeDelegate.setInstance(sbrd.getOriginal());
+      throw new RuntimeException(
+          "RuntimeDelegate.getInstance() is StringBeanRuntimeDelegate");
+    }
+  }
+
+  @Override
+  public Link.Builder createLinkBuilder() {
+    return original.createLinkBuilder();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java
new file mode 100644
index 0000000..d433614
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Data.java
@@ -0,0 +1,65 @@
+/*
+*
+* The Apache Software License, Version 1.1
+*
+* Copyright (c) 2018, 2021 Oracle and/or its affiliates. All rights reserved.
+* Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
+* reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in
+*    the documentation and/or other materials provided with the
+*    distribution.
+*
+* 3. The end-user documentation included with the redistribution, if
+*    any, must include the following acknowlegement:
+*       "This product includes software developed by the
+*        Apache Software Foundation (http://www.apache.org/)."
+*    Alternately, this acknowlegement may appear in the software itself,
+*    if and wherever such third-party acknowlegements normally appear.
+*
+* 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+*    Foundation" must not be used to endorse or promote products derived
+*    from this software without prior written permission. For written
+*    permission, please contact apache@apache.org.
+*
+* 5. Products derived from this software may not be called "Apache"
+*    nor may "Apache" appear in their names without prior written
+*    permission of the Apache Group.
+*
+* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+* DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+* ====================================================================
+*
+* This software consists of voluntary contributions made by many
+* individuals on behalf of the Apache Software Foundation.  For more
+* information on the Apache Software Foundation, please see
+* <http://www.apache.org/>.
+*
+*/
+
+package jakarta.ws.rs.tck.common.util;
+
+public final class Data {
+
+  public static final String PASSED = "Test PASSED";
+
+  public static final String FAILED = "Test FAILED";
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java
new file mode 100644
index 0000000..d5df129
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/Holder.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.util;
+
+public class Holder<TYPE> {
+
+  public Holder() {
+  };
+
+  public Holder(TYPE type) {
+    set(type);
+  }
+
+  public TYPE value;
+
+  public void set(TYPE value) {
+    this.value = value;
+  }
+
+  public TYPE get() {
+    return value;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java
new file mode 100644
index 0000000..3663433
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/JaxrsUtil.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.util;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.reflect.Array;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Locale;
+import java.util.TimeZone;
+
+public abstract class JaxrsUtil {
+
+  public static final//
+  String readFromStream(InputStream stream) throws IOException {
+    InputStreamReader isr = new InputStreamReader(stream);
+    return readFromReader(isr);
+  }
+
+  public static final//
+  String readFromReader(Reader reader) throws IOException {
+    BufferedReader br = new BufferedReader(reader);
+    String entity = br.readLine();
+    br.close();
+    return entity;
+  }
+
+  public static final//
+  String readFromFile(File file) throws IOException {
+    FileReader reader = new FileReader(file);
+    return readFromReader(reader);
+  }
+
+  public static final <T> //
+  String iterableToString(String separator, Iterable<T> collection) {
+    if (collection != null)
+      return iterableToString(separator, collection.iterator());
+    return "";
+  }
+
+  public static final <T> //
+  String iterableToString(String separator, Iterator<T> iterator) {
+    StringBuilder sb = new StringBuilder();
+    while (iterator.hasNext()) {
+      T item = iterator.next();
+      if (item != null) {
+        String appendable = item.toString();
+        sb.append(appendable);
+        if (iterator.hasNext())
+          sb.append(separator);
+      }
+    }
+    return sb.toString();
+  }
+
+  public static final <T> //
+  String enumerationToString(String separator, Enumeration<T> enumeration) {
+    StringBuilder sb = new StringBuilder();
+    if (enumeration != null)
+      while (enumeration.hasMoreElements()) {
+        T item = enumeration.nextElement();
+        if (item != null) {
+          String appendable = item.toString();
+          sb.append(appendable);
+          if (enumeration.hasMoreElements())
+            sb.append(separator);
+        }
+      }
+    return sb.toString();
+  }
+
+  public static final //
+  String iterableToString(String separator, Object... collection) {
+    StringBuilder sb = new StringBuilder();
+    if (collection != null)
+      for (int i = 0; i != collection.length; i++) {
+        Object item = collection[i];
+        if (item != null) {
+          String appendable = item.toString();
+          sb.append(appendable);
+          if (i != collection.length - 1)
+            sb.append(separator);
+        }
+      }
+    return sb.toString();
+  }
+
+  public static final TimeZone findTimeZoneInDate(String date) {
+    StringBuilder sb = new StringBuilder();
+    StringBuilder dateBuilder = new StringBuilder(date.trim()).reverse();
+    int index = 0;
+    char c;
+    while ((c = dateBuilder.charAt(index++)) != ' ') {
+      sb.append(c);
+    }
+    TimeZone timezone = TimeZone.getTimeZone(sb.reverse().toString());
+    return timezone;
+  }
+
+  public static final String mapToString(java.util.Map<?, ?> map) {
+    StringBuilder sb = new StringBuilder();
+    if (map != null)
+      for (Object key : map.keySet()) {
+        sb.append("[").append(key).append(" : ");
+        Object value = map.get(key);
+        sb.append(toString(value)).append("]");
+      }
+    return sb.toString();
+  }
+
+  public static final DateFormat createDateFormat(TimeZone timezone) {
+    SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z",
+        Locale.US);
+    sdf.setTimeZone(timezone);
+    return sdf;
+  }
+
+  public static String toString(Object object) {
+    String to = null;
+    if (object == null)
+      to = "null";
+    else if (Iterable.class.isInstance(object))
+      to = iterableToString(" ", (Iterable<?>) object);
+    else if (Enumeration.class.isInstance(object))
+      to = enumerationToString(" ", (Enumeration<?>) object);
+    else if (java.util.Map.class.isInstance(object))
+      to = mapToString((java.util.Map<?, ?>) object);
+    else if (Iterator.class.isInstance(object))
+      to = iterableToString(" ", (Iterator<?>) object);
+    else if (Array.class.isInstance(object))
+      to = iterableToString(" ", (Object[]) object);
+    else if (object.getClass().isArray())
+      to = primitiveArrayToString(object);
+    else
+      to = String.valueOf(object);
+    return to;
+  }
+
+  public static String primitiveArrayToString(Object array) {
+    String to = null;
+    if (array == null)
+      to = "null";
+    else if (array.getClass().isArray()) {
+      String sarray = array.toString();
+      if (sarray.startsWith("[I"))
+        to = Arrays.toString((int[]) array);
+      else if (sarray.startsWith("[B"))
+        to = Arrays.toString((byte[]) array);
+      else if (sarray.startsWith("[J"))
+        to = Arrays.toString((long[]) array);
+      else if (sarray.startsWith("[C"))
+        to = Arrays.toString((char[]) array);
+      else if (sarray.startsWith("[S"))
+        to = Arrays.toString((short[]) array);
+      else if (sarray.startsWith("[F"))
+        to = Arrays.toString((float[]) array);
+      else if (sarray.startsWith("[D"))
+        to = Arrays.toString((double[]) array);
+      else if (sarray.startsWith("[Z"))
+        to = Arrays.toString((boolean[]) array);
+      else if (sarray.startsWith("[L"))
+        to = Arrays.toString((Object[]) array);
+    } else
+      to = String.valueOf(array);
+    return to;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java
new file mode 100644
index 0000000..c9c3479
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/util/LinkedHolder.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2017, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.util;
+
+import java.util.Iterator;
+import java.util.LinkedList;
+
+/**
+ * Hold multiple instances of TYPE in a {@link LinkedList} structure, last one
+ * accessible by {@link #get()}.
+ * 
+ * @param <TYPE>
+ */
+public class LinkedHolder<TYPE> extends Holder<TYPE> implements Iterable<TYPE> {
+
+  private LinkedList<TYPE> list = new LinkedList<TYPE>();
+
+  public LinkedHolder(TYPE type) {
+    add(type);
+  }
+
+  public LinkedHolder() {
+  }
+
+  public void add(TYPE value) {
+    list.add(value);
+    super.set(value);
+  }
+
+  /**
+   * Replace the last item in the list
+   */
+  @Override
+  public void set(TYPE value) {
+    if (list.size() != 0) {
+      list.set(list.size() - 1, value);
+      super.set(value);
+    }
+    if (value == null) {
+      super.set(null);
+    } else {
+      add(value);
+    }
+  }
+
+  public TYPE get(int index) {
+    if (index >= list.size())
+      return null;
+    return list.get(index);
+  }
+
+  public int size() {
+    return list.size();
+  }
+
+  public void clear() {
+    super.set(null);
+    list.clear();
+  }
+
+  @Override
+  public Iterator<TYPE> iterator() {
+    return list.iterator();
+  }
+
+  public LinkedList<TYPE> asList() {
+    return list;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java
new file mode 100644
index 0000000..cdd8023
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Goldenfile.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * A representation of a Goldenfile that may be used by a particular test case.
+ */
+
+public class Goldenfile {
+
+  /*
+   * Message to be returned if the goldenfile cannot be located.
+   */
+  private static final byte[] NOTFOUND = "NO GOLDENFILE FOUND".getBytes();
+
+  /*
+   * Message to be returned if the goldenfile doesn't have read permissions.
+   */
+  private static final byte[] NOPERM = "INSUFFICIENT PERMISSIONS".getBytes();
+
+  /*
+   * Goldenfile represented by this object.
+   */
+  private File _file = null;
+
+  /*
+   * Error message to return by public methods if the file is not found or the
+   * user has insufficient permissions.
+   */
+  private byte[] _errMessage = null;
+
+  /*
+   * Goldenfile length
+   */
+  private long _length = 0L;
+
+  /*
+   * Encoding
+   */
+  private String _encoding = null;
+
+  /**
+   * Creates a new GoldenFile based on the fully qualified filename provided.
+   *
+   * @param path
+   *          Fully qualified file name
+   * @param encoding
+   *          to use when reading the goldenfile
+   */
+  public Goldenfile(String path, String encoding) {
+    _file = new File(path);
+    if (!_file.exists()) {
+      TestUtil.logTrace("[GoldenFile] Goldenfile: " + path + ", not found!");
+      _errMessage = NOTFOUND;
+      _file = null;
+    } else if (!_file.canRead()) {
+      _errMessage = NOPERM;
+      _file = null;
+    } else {
+      _length = _file.length();
+      _encoding = encoding;
+    }
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns the length of the Goldenfile.
+   *
+   * @return long length
+   */
+  public long getLength() {
+    return _length;
+  }
+
+  /**
+   * Returns the byte content of the specified goldenfile using the charset
+   * encoding specified in the response from the server.
+   *
+   * @return the goldenfile as a byte array
+   * @throws IOException
+   *           if an error occurs processing the file.
+   */
+  public byte[] getGoldenFileAsBytes() throws IOException {
+    if (_file != null) {
+      return getGoldenFileAsString().getBytes();
+    } else {
+      return _errMessage;
+    }
+  }
+
+  /**
+   * Retuns a string representation of the specified goldenfile using the
+   * charset encoding specified in the response from the server.
+   *
+   * @return the goldenfile as a String.
+   * @throws IOException
+   *           if an error occurs processing the file.
+   */
+  public String getGoldenFileAsString() throws IOException {
+    String gf = null;
+    if (_file != null) {
+      TestUtil.logTrace(
+          "[Goldenfile] Loading goldenfile using " + "encoding: " + _encoding);
+      FileInputStream in = new FileInputStream(_file);
+      gf = Util.getEncodedStringFromStream(in, _encoding);
+      in.close();
+    } else {
+      gf = new String(_errMessage);
+    }
+    return gf;
+  }
+
+  /**
+   * Returns the goldenfile as an InputStream using the charset encoding
+   * specified in the response from the server.
+   *
+   * @return goldenfile as an InputStream
+   * @throws IOException
+   *           If an error occurs processing the file.
+   */
+  public InputStream getGoldenFileAsStream() throws IOException {
+    if (_file != null) {
+      return new ByteArrayInputStream(getGoldenFileAsBytes());
+    } else {
+      return new ByteArrayInputStream(_errMessage);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java
new file mode 100644
index 0000000..45b716e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestCase.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+/**
+ * This interface defines a base set of methods required used by a TS test case.
+ */
+public interface TestCase {
+
+  /**
+   * Executes the test case.
+   *
+   * @throws TestFailureException
+   *           if the test fails for any reason.
+   */
+  public void execute() throws TestFailureException;
+
+  /**
+   * Sets the name of the test case.
+   *
+   * @param name
+   *          of the test case
+   */
+  public void setName(String name);
+
+  /**
+   * Returns the name of this test case.
+   *
+   * @return test case name
+   */
+  public String getName();
+
+  /**
+   * Sets the state for this test case. This state will differ from
+   * implementation to implementation.
+   *
+   * @param state
+   *          test state
+   */
+  public void setState(Object state);
+
+  /**
+   * Returns the state of the test case. The state returned could possibly
+   * differ depending on when this method is called and when the test case has
+   * been executed.
+   */
+  public Object getState();
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java
new file mode 100644
index 0000000..c71f384
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/TestFailureException.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+/**
+ * Signifies a failure at some point during a test cycle.
+ */
+public class TestFailureException extends java.lang.Exception {
+
+  private static final long serialVersionUID = -4651996590051941456L;
+
+  /**
+   * Creates a new instance of <code>TestFailureException</code> without a
+   * detailed message.
+   */
+  public TestFailureException() {
+  }
+
+  /**
+   * Creates a new instance of <code>TestFailureException</code> containing the
+   * root cause of the test failure.
+   * 
+   * @param t
+   *          - root cause
+   */
+  public TestFailureException(Throwable t) {
+    super(t);
+  }
+
+  /**
+   * Creates a new instance of <code>TestFailureException</code> with the
+   * specified detail message.
+   * 
+   * @param msg
+   *          - the detail message.
+   */
+  public TestFailureException(String msg) {
+    super(msg);
+  }
+
+  /**
+   * Creates a new instance of <code>TestFailureException</code> with the
+   * specified detail message, and the root cause of the test failure
+   * 
+   * @param msg
+   *          - the detail message
+   * @param t
+   *          - root cause
+   */
+  public TestFailureException(String msg, Throwable t) {
+    super(msg, t);
+  }
+
+  /**
+   * Returns, if any, the root cause of this Exception.
+   * 
+   * @return the root cause of this exception, or null
+   */
+  public Throwable getRootCause() {
+    return getCause();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java
new file mode 100644
index 0000000..604e6cf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/Util.java
@@ -0,0 +1,234 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import jakarta.ws.rs.tck.lib.util.BASE64Encoder;
+
+public class Util {
+
+  /**
+   * Zeros
+   */
+  private static final String ZEROS = "00000000";
+
+  /**
+   * short pad size
+   */
+  private static final int SHORTPADSIZE = 4;
+
+  /**
+   * byte pad size
+   */
+  private static final int BYTEPADSIZE = 2;
+
+  /** Creates new Util */
+  private Util() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * BASE64 encodes the provided string.
+   * 
+   * @return BASE64 encoded string.
+   */
+  public static String getBase64EncodedString(String value) {
+    BASE64Encoder encoder = new BASE64Encoder();
+    return encoder.encode(value.getBytes());
+  }
+
+  /**
+   * Returns a charset encoded string based on the provided InputStream and
+   * charset encoding.
+   *
+   * @return encoding string
+   */
+  public static String getEncodedStringFromStream(InputStream in, String enc)
+      throws IOException {
+    BufferedReader bin = new BufferedReader(new InputStreamReader(in, enc));
+    StringBuffer sb = new StringBuffer(128);
+    for (int ch = bin.read(); ch != -1; ch = bin.read()) {
+      sb.append((char) ch);
+    }
+    return sb.toString();
+  }
+
+  /**
+   * <code>getHexValue</code> displays a formatted hex representation of the
+   * passed byte array. It also allows for only a specified offset and length of
+   * a particular array to be returned.
+   *
+   * @param bytes
+   *          <code>byte[]</code> array to process.
+   * @param pos
+   *          <code>int</code> specifies offset to begin processing.
+   * @param len
+   *          <code>int</code> specifies the number of bytes to process.
+   * @return <code>String</code> formatted hex representation of processed
+   *         array.
+   */
+  public static String getHexValue(byte[] bytes, int pos, int len) {
+    StringBuffer outBuf = new StringBuffer(bytes.length * 2);
+    int bytesPerLine = 36;
+    int cnt = 1;
+    int groups = 4;
+    int curPos = pos;
+    int linePos = 1;
+    boolean displayOffset = true;
+
+    while (len-- > 0) {
+      if (displayOffset) {
+
+        outBuf.append("\n" + paddedHexString(pos, SHORTPADSIZE, true) + ": ");
+        displayOffset = false;
+      }
+
+      outBuf.append(paddedHexString((int) bytes[pos], BYTEPADSIZE, false));
+      linePos += 2; // Byte is padded to 2 characters
+
+      if ((cnt % 4) == 0) {
+        outBuf.append(" ");
+        linePos++;
+      }
+
+      // Now display the characters that are printable
+      if ((cnt % (groups * 4)) == 0) {
+        outBuf.append(" ");
+
+        while (curPos <= pos) {
+          if (!Character.isWhitespace((char) bytes[curPos])) {
+            outBuf.append((char) bytes[curPos]);
+          } else {
+            outBuf.append(".");
+          }
+
+          curPos++;
+        }
+
+        curPos = pos + 1;
+        linePos = 1;
+        displayOffset = true;
+      }
+
+      cnt++;
+      pos++;
+    }
+
+    // pad out the line with spaces
+    while (linePos++ <= bytesPerLine) {
+      outBuf.append(" ");
+    }
+
+    outBuf.append(" ");
+    // Now display the printable characters for the trailing bytes
+    while (curPos < pos) {
+      if (!Character.isWhitespace((char) bytes[curPos])) {
+        outBuf.append((char) bytes[curPos]);
+      } else {
+        outBuf.append(".");
+      }
+
+      curPos++;
+    }
+
+    return outBuf.toString();
+  }
+
+  /*
+   * private methods
+   * ========================================================================
+   */
+
+  /**
+   * <code>paddedHexString</code> pads the passed value based on the specified
+   * wordsize and the value of the prefixFlag.
+   *
+   * @param val
+   *          an <code>int</code> value
+   * @param wordsize
+   *          an <code>int</code> value
+   * @param prefixFlag
+   *          a <code>boolean</code> value
+   * @return a <code>String</code> value
+   */
+  private static String paddedHexString(int val, int wordsize,
+      boolean prefixFlag) {
+
+    String prefix = prefixFlag ? "0x" : "";
+    String hexVal = Integer.toHexString(val);
+
+    if (hexVal.length() > wordsize)
+      hexVal = hexVal.substring(hexVal.length() - wordsize);
+
+    return (prefix + (wordsize > hexVal.length()
+        ? ZEROS.substring(0, wordsize - hexVal.length())
+        : "") + hexVal);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java
new file mode 100644
index 0000000..27c1c3a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/WebTestCase.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpState;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationFactory;
+import jakarta.ws.rs.tck.common.webclient.validation.ValidationStrategy;
+import jakarta.ws.rs.tck.common.webclient.TestFailureException;
+
+/**
+ * A TestCase implementation for HTTP-based testing. This allows the user to set
+ * criteria for test success which will be compared against the response from
+ * the server.
+ */
+public class WebTestCase implements TestCase {
+
+  /**
+   * Tokenized response validation strategy
+   */
+  public static final String TOKENIZED_STRATEGY = "jakarta.ws.rs.tck.common.webclient.validation.TokenizedValidator";
+
+  /**
+   * Whitespace response validation strategy
+   */
+  public static final String WHITESPACE_STRATEGY = "jakarta.ws.rs.tck.common.webclient.validation.WhitespaceValidator";
+
+  /**
+   * The request for this case.
+   */
+  private HttpRequest _request = null;
+
+  /**
+   * The server's response.
+   */
+  private HttpResponse _response = null;
+
+  // use HttpMethod instances to store test
+  // case headers that are expected or not
+  // expected.
+
+  /**
+   * Storage for headers that are expected in the response
+   */
+  private Map<String, Header> _expected = null;
+
+  /**
+   * Storage for headers that are not expected in the response
+   */
+  private Map<String, Header> _unexpected = null;
+
+  /**
+   * Expected response status code.
+   */
+  private String _statusCode = null;
+
+  /**
+   * Expected response reason phrase.
+   */
+  private String _reasonPhrase = null;
+
+  /**
+   * Path to goldenfile.
+   */
+  private String _goldenfilePath = null;
+
+  /**
+   * A List of strings that will be searched for in the response in the order
+   * they appear in the list.
+   */
+  private List<String> _searchStrings = null;
+
+  /**
+   * A List of case insensitive strings that will be searched for in the
+   * response in the order they appear in the list.
+   */
+  private List<String> _searchStringsNoCase = null;
+
+  /**
+   * A List of strings that will be search for in the response with no attention
+   * paid to the order they appear.
+   */
+  private List<String> _unorderedSearchStrings = null;
+
+  /**
+   * A List of strings that should not be in the server's response.
+   */
+  private List<String> _uSearchStrings = null;
+
+  /**
+   * Indicates whether a response body should be expected or not.
+   */
+  private boolean _expectResponseBody = true;
+
+  /**
+   * Strategy to use when validating the test case against the server's
+   * response.
+   */
+  private ValidationStrategy _strategy = null;
+
+  /**
+   * Logical name for test case.
+   */
+  private String _name = "Test Case";
+
+  /**
+   * Creates a new instance of WebTestCase By default, a new WebTestCase
+   * instance will use the TokenizedValidator to verify the response with the
+   * configured properties of the test case.
+   */
+  public WebTestCase() {
+    _strategy = ValidationFactory.getInstance(TOKENIZED_STRATEGY);
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+  /**
+   * Executes the test case.
+   *
+   * @throws TestFailureException
+   *           if the test fails for any reason.
+   * @throws IllegalStateException
+   *           if no request was configured or if no Validator is available at
+   *           runtime.
+   */
+  public void execute() throws TestFailureException {
+
+    // If no request was created, we can't run.
+    if (_request == null) {
+      throw new IllegalStateException("[FATAL] HttpRequest is null.");
+    }
+
+    // If no stragey instance is available (strange, but has happened),
+    // fail.
+    if (_strategy == null) {
+      throw new IllegalStateException("[FATAL] No Validator available.");
+    }
+
+    try {
+      _response = _request.execute();
+    } catch (Throwable t) {
+      String message = t.getMessage();
+      throw new TestFailureException("[FATAL] Unexpected failure during "
+          + "test execution." + (message == null ? t.toString() : message), t);
+    }
+
+    // Validate this test case instance
+    if (!_strategy.validate(this)) {
+      throw new TestFailureException("Test FAILED!");
+    }
+
+  }
+
+  /**
+   * Sets the status code to be expected in the response from the server, i.e.
+   * 500 or 404, etc.
+   *
+   * @param statusCode
+   *          the expected status code
+   */
+  public void setExpectedStatusCode(String statusCode) {
+    _statusCode = statusCode;
+  }
+
+  /**
+   * Sets the reason phrase to be expected in the response from the server.
+   *
+   * @param reasonPhrase
+   *          the expected reason-phrase
+   */
+  public void setExpectedReasonPhrase(String reasonPhrase) {
+    _reasonPhrase = reasonPhrase;
+  }
+
+  /**
+   * Adds a header that is to be expected in the response from the server.
+   *
+   * @param header
+   *          in the format of <headername>:<value> (test:foo)
+   */
+  public void addExpectedHeader(String header) {
+    if (_expected == null) {
+      _expected = new HashMap<String, Header>();
+    }
+    addHeader(_expected, header);
+  }
+
+  /**
+   * Sets the path to the goldenfile the test case should use.
+   *
+   * @param gfPath
+   *          a fully qualified path including filename.
+   */
+  public void setGoldenFilePath(String gfPath) {
+    _goldenfilePath = gfPath;
+  }
+
+  /**
+   * Sets the request that should be dispatched by this test case.
+   *
+   * @param request
+   *          the HTTP request used for this test case
+   */
+  public void setRequest(HttpRequest request) {
+    _request = request;
+  }
+
+  /**
+   * Adds a header that is should not be in the server's response.
+   *
+   * @param header
+   *          in the format of <headername>:<value> (test:foo)
+   */
+  public void addUnexpectedHeader(String header) {
+    if (_unexpected == null) {
+      _unexpected = new HashMap<String, Header>();
+    }
+    addHeader(_unexpected, header);
+  }
+
+  /**
+   * Enables/Disables an assertion that a response body is present.
+   *
+   * @param value
+   *          a value of true will enable the assertion.
+   */
+  public void setAssertNoResponseBody(boolean value) {
+  }
+
+  /**
+   * Sets a string that will be scanned for and expected in the response body
+   * from the server.
+   *
+   * If multiple search strings are required, one can either call this method
+   * for each string, or pass in one string with pipe <code>|<code> delimiting
+   * the individual search strings within the large string.
+   *
+   * @param searchString
+   *          a string expected in the server's response body
+   */
+  public void setResponseSearchString(String searchString) {
+    if (_searchStrings == null) {
+      _searchStrings = new ArrayList<String>();
+    }
+    addSearchStrings(_searchStrings, searchString);
+  }
+
+  /**
+   * Sets a string that will be scanned for and expected in the response body
+   * from the server.
+   *
+   * If multiple search strings are required, one can either call this method
+   * for each string, or pass in one string with pipe <code>|<code> delimiting
+   * the individual search strings within the large string.
+   *
+   * @param searchString
+   *          a case insensitive string expected in the server's response body
+   */
+  public void setResponseSearchStringIgnoreCase(String searchString) {
+    if (_searchStringsNoCase == null) {
+      _searchStringsNoCase = new ArrayList<String>();
+    }
+    addSearchStrings(_searchStringsNoCase, searchString);
+  }
+
+  /**
+   * Sets a string that will be scanned for and should not be present in the
+   * response body from the server.
+   *
+   * If multiple search strings are required, one can either call this method
+   * for each string, or pass in one string with pipe <code>|<code> delimiting
+   * the individual search strings within the large string.
+   *
+   * @param searchString
+   *          a string that is not expected in the server's response body
+   */
+  public void setUnexpectedResponseSearchString(String searchString) {
+    if (_uSearchStrings == null) {
+      _uSearchStrings = new ArrayList<String>();
+    }
+    addSearchStrings(_uSearchStrings, searchString);
+  }
+
+  /**
+   * Sets a string or series of strings that will be searched for in the
+   * response. If multiple search strings are required, one can either call this
+   * method for each string, or pass in one string with pipe <code>|<code>
+   * delimiting the individual search strings within the large string.
+   *
+   * @param searchString
+   *          a string that is not expected in the server's response body
+   */
+  public void setUnorderedSearchString(String searchString) {
+    if (_unorderedSearchStrings == null) {
+      _unorderedSearchStrings = new ArrayList<String>();
+    }
+    addSearchStrings(_unorderedSearchStrings, searchString);
+  }
+
+  /**
+   * Returns the list of search strings.
+   * 
+   * @return the list of search strings.
+   */
+  public List<String> getUnorderedSearchStrings() {
+    return _unorderedSearchStrings;
+  }
+
+  /**
+   * Returns the response for this particular test case.
+   *
+   * @return an HttpResponse object
+   */
+  public HttpResponse getResponse() {
+    return _response;
+  }
+
+  /**
+   * Returns an array of Header objects that are expected to be found in the
+   * responst.
+   *
+   * @return an array of headers
+   */
+  public Header[] getExpectedHeaders() {
+    if (_expected == null) {
+      return null;
+    }
+    return _expected.values().toArray(new Header[_expected.size()]);
+  }
+
+  /**
+   * Returns an array of Header objects that are not expected to be found in the
+   * responst.
+   *
+   * @return an array of headers
+   */
+  public Header[] getUnexpectedHeaders() {
+    if (_unexpected == null) {
+      return null;
+    }
+    return _unexpected.values().toArray(new Header[_unexpected.size()]);
+  }
+
+  /**
+   * Returns the status code expected to be found in the server's response
+   *
+   * @return status code
+   */
+  public String getStatusCode() {
+    return _statusCode;
+  }
+
+  /**
+   * Returns the reason phrase that is expected to be found in the server's
+   * response.
+   *
+   * @return reason phrase
+   */
+  public String getReasonPhrase() {
+    return _reasonPhrase;
+  }
+
+  /**
+   * Returns the configured list of strings that will be used when scanning the
+   * server's response.
+   *
+   * @return list of Strings
+   */
+  public List<String> getSearchStrings() {
+    if (_searchStrings == null) {
+      return null;
+    }
+    return _searchStrings;
+  }
+
+  /**
+   * Returns the configured list of strings that will be used when scanning the
+   * server's response.
+   *
+   * @return list of case insensitive Strings
+   */
+  public List<String> getSearchStringsNoCase() {
+    if (_searchStringsNoCase == null) {
+      return null;
+    }
+    return _searchStringsNoCase;
+  }
+
+  /**
+   * Returns the configured list of strings that will be used when scanning the
+   * server's response (these strings are not expected in the response).
+   *
+   * @return list of Strings
+   */
+  public List<String> getUnexpectedSearchStrings() {
+    if (_uSearchStrings == null) {
+      return null;
+    }
+    return _uSearchStrings;
+  }
+
+  /**
+   * Returns an indicator on whether a response body is expected or not.
+   *
+   * @return boolean value
+   */
+  public boolean getExpectResponseBody() {
+    return _expectResponseBody;
+  }
+
+  /**
+   * Returns the HttpRequest for this particular test case.
+   *
+   * @return HttpRequest of this test case
+   */
+  public HttpRequest getRequest() {
+    return _request;
+  }
+
+  /**
+   * Returns the path to the goldenfile.
+   *
+   * @return path to the goldenfile
+   */
+  public String getGoldenfilePath() {
+    return _goldenfilePath;
+  }
+
+  /**
+   * Returns the state for this particular test case.
+   *
+   * @return test state
+   */
+  public Object getState() {
+    if (_response != null) {
+      return _response.getState();
+    } else {
+      // an initial request for state
+      return _request.getState();
+    }
+  }
+
+  /**
+   * Sets the state for this test case.
+   *
+   * @param state
+   *          test state
+   */
+  public void setState(Object state) {
+    _request.setState((HttpState) state);
+  }
+
+  /**
+   * Sets a logical name for this test case.
+   *
+   * @param name
+   *          the logical name for this test
+   */
+  public void setName(String name) {
+    _name = name;
+  }
+
+  /**
+   * Returns the logical name for this test case.
+   *
+   * @return test name
+   */
+  public String getName() {
+    return _name;
+  }
+
+  /**
+   * Sets the validation strategy for this test case instance.
+   *
+   * @param validator
+   *          - the fully qualified class name of the response validator to use.
+   */
+  public void setStrategy(String validator) {
+    ValidationStrategy strat = ValidationFactory.getInstance(validator);
+    if (strat != null) {
+      _strategy = strat;
+    } else {
+      TestUtil.logMsg("[WebTestCase][WARNING] An attempt was made to use a "
+          + "non-existing validator (" + validator + ")"
+          + ".  Falling back to the TokenizedValidator");
+    }
+  }
+
+  /**
+   * Returns the class name of the response validator used.
+   *
+   * @return the fully qualified class of the validator used
+   */
+  public String getStrategy() {
+    return _strategy.getClass().getName();
+  }
+
+  /*
+   * Private Methods
+   * ===========================================================================
+   */
+
+  /**
+   * Utility method to add headers to test case holder objects.
+   *
+   * @param map
+   *          the object in which to add header to
+   * @param headerString
+   *          String representation of a header in the form of
+   *          <headername>:<value>
+   */
+  private void addHeader(Map<String, Header> map, String headerString) {
+    TestUtil.logTrace(
+        "[WebTestCase] addHeader utility method called: " + headerString);
+    StringTokenizer st = new StringTokenizer(headerString, "|");
+    while (st.hasMoreTokens()) {
+      String head = st.nextToken();
+      int colIdx = head.indexOf(':');
+      String name = head.substring(0, colIdx).trim();
+      String value = head.substring(colIdx + 1).trim();
+      TestUtil
+          .logTrace("[WebTestCase] Adding test header: " + name + ", " + value);
+      Header header = map.get(name);
+      if (header != null) {
+        map.put(name, createNewHeader(value, header));
+      } else {
+        map.put(name, new Header(name, value));
+      }
+    }
+  }
+
+  /**
+   * Creates a new header based of the provided header and value.
+   * 
+   * @param newValue
+   *          - the new value to add to an existing header
+   * @param header
+   *          - the original header
+   * @return new Header
+   */
+  private Header createNewHeader(String newValue, Header header) {
+    String oldValue = header.getValue();
+    return new Header(header.getName(), oldValue + ", " + newValue);
+  }
+
+  /**
+   * Adds a search string to the provided list
+   * 
+   * @param stringList
+   *          - list to add the string to
+   * @param s
+   *          - the search string
+   */
+  private void addSearchStrings(List<String> stringList, String s) {
+    StringTokenizer st = new StringTokenizer(s, "|");
+    while (st.hasMoreTokens()) {
+      stringList.add(st.nextToken());
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java
new file mode 100644
index 0000000..5fc2685
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ALLOWHandler.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+public class ALLOWHandler implements Handler {
+
+  private static final Handler HANDLER = new ALLOWHandler();
+
+  private static final String DELIM = "##";
+
+  private ALLOWHandler() {
+  }
+
+  public static Handler getInstance() {
+    return HANDLER;
+  }
+
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+    String ALLOWHeader = responseHeader.getValue().toLowerCase();
+    String expectedValues = configuredHeader.getValue().toLowerCase()
+        .replace(" ", "");
+
+    TestUtil.logTrace("[ALLOWHandler] ALLOW header received: " + ALLOWHeader);
+
+    StringTokenizer conf = new StringTokenizer(expectedValues, ",");
+    while (conf.hasMoreTokens()) {
+      String token = conf.nextToken();
+      String token1 = token;
+
+      if ((ALLOWHeader.indexOf(token) < 0)
+          && (ALLOWHeader.indexOf(token1) < 0)) {
+        TestUtil.logErr("[ALLOWHandler] Unable to find '" + token
+            + "' within the ALLOW header returned by the server.");
+        return false;
+      } else {
+        TestUtil.logTrace("[ALLOWHandler] Found expected value, '" + token
+            + "' in ALLOW header returned by server.");
+      }
+    }
+    return true;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java
new file mode 100644
index 0000000..3840a64
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/ContentTypeHandler.java
@@ -0,0 +1,153 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * When invoked, the content-type header
+ * will be appropriately handled.  It allows
+ * flexible checking of control values against
+ * the response which could be in the form of:
+ *    content-type; charset
+ *      -or-
+ *    conent-type
+ * </PRE>
+ */
+public class ContentTypeHandler implements Handler {
+
+  private static Handler handler = new ContentTypeHandler();
+
+  /**
+   * Creates new ContentTypeHandler
+   */
+  private ContentTypeHandler() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns an instance of this handler.
+   */
+  public static Handler getInstance() {
+    return handler;
+  }
+
+  /**
+   * Invokes handler logic.
+   * 
+   * @param configuredHeader
+   *          the user configured header
+   * @param responseHeader
+   *          the response header from the server
+   * @return True if the passed match, otherwise false
+   */
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+    boolean ret = false;
+    TestUtil.logTrace("[ContentTypeHandler] ContentTypeHandler invoked.");
+    String configVal = configuredHeader.getValue().trim();
+    String responseVal = responseHeader.getValue().trim();
+    int colIdx = configVal.indexOf(';');
+    if (colIdx < 0) {
+      // Info we're interested in : type/subtype
+
+      // check response Content-Type header to see what format
+      // it's in.
+      int rColIdx = responseVal.indexOf(';');
+      if (rColIdx < 0) {
+        // Type and subtype, i.e. type/subtype are to be compared
+        // case insensitively.
+        if (configVal.equalsIgnoreCase(responseVal)) {
+          ret = true;
+        }
+      } else {
+        if (configVal.equalsIgnoreCase(responseVal.substring(0, rColIdx))) {
+          ret = true;
+        }
+      }
+    } else {
+      // Info we're interested in : type/subtype; parameter=value
+
+      int rColIdx = responseVal.indexOf(';');
+      if (rColIdx > -1) {
+        String confTypeSubType = configVal.substring(0, colIdx).trim();
+        String responseTypeSubType = responseVal.substring(0, rColIdx).trim();
+        String confParameter = configVal.substring(colIdx + 1).trim();
+        String responseParameter = (responseVal.substring(rColIdx + 1).trim())
+            .replaceAll(" ", "");
+        // compare type/subtype in a case insensitive manner
+        if (confTypeSubType.equalsIgnoreCase(responseTypeSubType)) {
+          // next validate the parameter in a case insensitive manner
+          if (confParameter.equalsIgnoreCase(responseParameter)) {
+            ret = true;
+          }
+        }
+      }
+    }
+    return ret;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java
new file mode 100644
index 0000000..4ef41af
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/DefaultHandler.java
@@ -0,0 +1,145 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HeaderElement;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * The default handler will handle any
+ * header that doesn't have a configured handler.
+ * </PRE>
+ */
+public class DefaultHandler implements Handler {
+
+  private static Handler handler = new DefaultHandler();
+
+  /**
+   * Creates new DefaultHandler
+   */
+  private DefaultHandler() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns an instance of this handler.
+   */
+  public static Handler getInstance() {
+    return handler;
+  }
+
+  /**
+   * Invokes handler logic.
+   * 
+   * @param configuredHeader
+   *          the user configured header
+   * @param responseHeader
+   *          the response header from the server
+   * @return True if the passed match, otherwise false
+   */
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+    TestUtil.logTrace("[DefaulHandler] DefaultHandler invoked.");
+
+    return areHeadersEqual(configuredHeader, responseHeader);
+  }
+
+  /**
+   * Utility method to determine equality of two Header objects
+   * 
+   * @param h1
+   *          first header
+   * @param h2
+   *          second header
+   * @return true if the headers are equal, otherwise false
+   */
+  protected boolean areHeadersEqual(Header h1, Header h2) {
+
+    HeaderElement[] h1Values = h1.getElements();
+    HeaderElement[] h2Values = h2.getElements();
+
+    if (h1Values.length == h2Values.length) {
+      for (HeaderElement h1Value : h1Values) {
+        String h1Val = h1Value.getName();
+        boolean found = false;
+        for (HeaderElement h2Value : h2Values) {
+          if (h1Val.equals(h2Value.getName())) {
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          return false;
+        }
+      }
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java
new file mode 100644
index 0000000..3801d33
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/Handler.java
@@ -0,0 +1,84 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+/**
+ * Handler interface.
+ */
+public interface Handler {
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Invokes handler logic.
+   * 
+   * @param configuredHeader
+   *          the user configured header
+   * @param responseHeader
+   *          the response header from the server
+   * @return True if the passed match, otherwise false
+   */
+  public boolean invoke(Header configuredHeader, Header responseHeader);
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java
new file mode 100644
index 0000000..6d90810
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/HandlerFactory.java
@@ -0,0 +1,126 @@
+/* ====================================================================
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+/**
+ * <PRE>
+ * The HandlerManager is responsible for returning the appropriate handler
+ * instance based on the provided value.
+ */
+public class HandlerFactory {
+
+  /**
+   * Content-Type handler name.
+   */
+  private static final String CONTENT_TYPE = "content-type";
+
+  /**
+   * Location handler name.
+   */
+  private static final String LOCATION = "location";
+
+  /**
+   * Set-Cookie handler name.
+   */
+  private static final String SET_COOKIE = "set-cookie";
+
+  /**
+   * ALLOW handler name.
+   */
+  private static final String ALLOW = "allow";
+
+  /**
+   * www-authenticate handler name.
+   */
+  private static final String WWW_AUTH = "www-authenticate";
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Constructs a new HandlerManager instance
+   */
+  private HandlerFactory() {
+  }
+
+  /**
+   * Returns the appropriate handler instance based on provided discriminate (a
+   * header name).
+   *
+   * @param handlerName
+   *          handler instance to obtain.
+   */
+  public static Handler getHandler(String handlerName) {
+    if (CONTENT_TYPE.equals(handlerName.toLowerCase())) {
+      return ContentTypeHandler.getInstance();
+    } else if (LOCATION.equals(handlerName.toLowerCase())) {
+      return LocationHandler.getInstance();
+    } else if (SET_COOKIE.equals(handlerName.toLowerCase())) {
+      return SetCookieHandler.getInstance();
+    } else if (WWW_AUTH.equals(handlerName.toLowerCase())) {
+      return WWWAuthenticateHandler.getInstance();
+    } else if (ALLOW.equals(handlerName.toLowerCase())) {
+      return ALLOWHandler.getInstance();
+    } else {
+      return DefaultHandler.getInstance();
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java
new file mode 100644
index 0000000..835bb73
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/LocationHandler.java
@@ -0,0 +1,162 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * Will handle headers for the following
+ * cases:
+ *   - Server is on port 80 and port value isn't
+ *     propagated back to client (assumed)
+ *   - Port value is in response
+ * </PRE>
+ */
+public class LocationHandler implements Handler {
+
+  private static Handler handler = new LocationHandler();
+
+  /**
+   * Creates new ContentTypeHandler
+   */
+  private LocationHandler() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns an instance of this handler.
+   */
+  public static Handler getInstance() {
+    return handler;
+  }
+
+  /**
+   * Invokes handler logic.
+   * 
+   * @param configuredHeader
+   *          the user configured header
+   * @param responseHeader
+   *          the response header from the server
+   * @return True if the passed match, otherwise false
+   */
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+    boolean pass = true;
+
+    try {
+      TestUtil.logTrace("[LocationHandler] LocationHandler invoked.");
+
+      URL configURL = new URL(configuredHeader.getValue());
+      URL responseURL = new URL(responseHeader.getValue());
+
+      if (!(configURL.getProtocol().equals(responseURL.getProtocol()))) {
+        pass = false;
+        TestUtil.logErr("[LocationHandler] Mismatch between protocols:");
+        TestUtil.logErr(
+            "[LocationHandler] Configured value: " + configURL.getProtocol());
+        TestUtil.logErr(
+            "[LocationHandler] Response value: " + responseURL.getProtocol());
+      }
+
+      if (!(configURL.getPath().equals(responseURL.getPath()))) {
+        pass = false;
+        TestUtil.logErr("[LocationHandler] Mismatch between paths:");
+        TestUtil.logErr(
+            "[LocationHandler] Configured value: " + configURL.getPath());
+        TestUtil.logErr(
+            "[LocationHandler] Response value: " + responseURL.getPath());
+      }
+
+      if (configURL.getQuery() == null) {
+        if (responseURL.getQuery() != null) {
+          pass = false;
+          TestUtil.logErr("[LocationHandler] Mismatch between querys:");
+          TestUtil.logErr("[LocationHandler] Configured value is null");
+          TestUtil.logErr("[LocationHandler] Response value is non-null");
+        }
+      } else if (!(configURL.getQuery().equals(responseURL.getQuery()))) {
+        pass = false;
+        TestUtil.logErr("[LocationHandler] Mismatch between querys:");
+        TestUtil.logErr(
+            "[LocationHandler] Configured value: " + configURL.getQuery());
+        TestUtil.logErr(
+            "[LocationHandler] Response value: " + responseURL.getQuery());
+      }
+
+    } catch (MalformedURLException mue) {
+      pass = false;
+      TestUtil.logErr("[LocationHandler] MalformedURLException");
+      TestUtil.printStackTrace(mue);
+    }
+
+    return pass;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java
new file mode 100644
index 0000000..bb3b3ec
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/SetCookieHandler.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+public class SetCookieHandler implements Handler {
+
+  private static final Handler HANDLER = new SetCookieHandler();
+
+  private static final String DELIM = "##";
+
+  private SetCookieHandler() {
+  }
+
+  public static Handler getInstance() {
+    return HANDLER;
+  }
+
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+    String setCookieHeader = responseHeader.getValue().toLowerCase();
+    String expectedValues = configuredHeader.getValue().toLowerCase();
+
+    TestUtil.logTrace(
+        "[SetCookieHandler] Set-Cookie header received: " + setCookieHeader);
+
+    StringTokenizer conf = new StringTokenizer(expectedValues, DELIM);
+    while (conf.hasMoreTokens()) {
+      String token = conf.nextToken();
+      String token1 = token;
+
+      if (token.endsWith("\"") && (token.indexOf("=\"") > 1)) {
+        token1 = token.replace("=\"", "=");
+        token1 = token1.substring(0, token.length() - 2);
+      }
+
+      if (token.startsWith("!")) {
+        String attr = token.substring(1);
+        String attr1 = token1.substring(1);
+        if ((setCookieHeader.indexOf(attr) > -1)
+            || (setCookieHeader.indexOf(attr1) > -1)) {
+          TestUtil.logErr("[SetCookieHandler] Unexpected attribute found "
+              + " Set-Cookie header.  Attribute: " + attr
+              + "\nSet-Cookie header: " + setCookieHeader);
+          return false;
+        }
+      } else {
+        if ((setCookieHeader.indexOf(token) < 0)
+            && (setCookieHeader.indexOf(token1) < 0)) {
+          TestUtil.logErr("[SetCookieHandler] Unable to find '" + token
+              + "' within the Set-Cookie header returned by the server.");
+          return false;
+        } else {
+          TestUtil.logTrace("[SetCookieHandler] Found expected value, '" + token
+              + "' in Set-Cookie header returned by server.");
+        }
+      }
+    }
+
+    return true;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java
new file mode 100644
index 0000000..898df21
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/handler/WWWAuthenticateHandler.java
@@ -0,0 +1,113 @@
+/*
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * Copyright (c) 2000 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ *    if any, must include the following acknowledgment:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowledgment may appear in the software itself,
+ *    if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "Apache" and "Apache Software Foundation" must
+ *    not be used to endorse or promote products derived from this
+ *    software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache",
+ *    nor may "Apache" appear in their name, without prior written
+ *    permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * Portions of this software are based upon public domain software
+ * originally written at the National Center for Supercomputing Applications,
+ * University of Illinois, Urbana-Champaign.
+ */
+
+package jakarta.ws.rs.tck.common.webclient.handler;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * <PRE>
+ * Will handle headers for the following
+ * cases:
+ *   - Server is on port 80 and port value isn't
+ *     propagated back to client (assumed)
+ *   - Port value is in response
+ * </PRE>
+ */
+public class WWWAuthenticateHandler implements Handler {
+
+  private static Handler handler = new WWWAuthenticateHandler();
+
+  /**
+   * Creates new ContentTypeHandler
+   */
+  private WWWAuthenticateHandler() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns an instance of this handler.
+   */
+  public static Handler getInstance() {
+    return handler;
+  }
+
+  /**
+   * Invokes handler logic.
+   * 
+   * @param configuredHeader
+   *          the user configured header
+   * @param responseHeader
+   *          the response header from the server
+   * @return True if the passed match, otherwise false
+   */
+  public boolean invoke(Header configuredHeader, Header responseHeader) {
+
+    TestUtil
+        .logTrace("[WWWAuthenticateHandler] WWAuthenticateHandler invoked.");
+    return true;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java
new file mode 100644
index 0000000..a1aa017
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpRequest.java
@@ -0,0 +1,586 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.io.IOException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.Cookie;
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.HttpConnection;
+import org.apache.commons.httpclient.HttpException;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.UsernamePasswordCredentials;
+import org.apache.commons.httpclient.auth.AuthScope;
+import org.apache.commons.httpclient.cookie.CookiePolicy;
+import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
+import org.apache.commons.httpclient.methods.StringRequestEntity;
+import org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.Protocol;
+import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
+import org.apache.commons.httpclient.protocol.SSLProtocolSocketFactory;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.Util;
+
+/**
+ * Represents an HTTP client Request
+ */
+
+public class HttpRequest {
+
+  static {
+    // if (TestUtil.traceflag) {
+    //   System.setProperty("org.apache.commons.logging.Log",
+    //       "jakarta.ws.rs.tck.common.webclient.log.WebLog");
+    //   System.setProperty(
+    //       "org.apache.commons.logging.simplelog.log.httpclient.wire", "debug");
+    // }
+  }
+
+  /**
+   * Default HTTP port.
+   */
+  public static int DEFAULT_HTTP_PORT = 80;
+
+  /**
+   * Default HTTP SSL port.
+   */
+  public static final int DEFAULT_SSL_PORT = 443;
+
+  /**
+   * No authentication
+   */
+  public static final int NO_AUTHENTICATION = 0;
+
+  /**
+   * Basic authentication
+   */
+  public static final int BASIC_AUTHENTICATION = 1;
+
+  /**
+   * Digest authenctication
+   */
+  public static final int DIGEST_AUTHENTICATION = 2;
+
+  /**
+   * Method representation of request.
+   */
+  private HttpMethod _method = null;
+
+  /**
+   * Target web container host
+   */
+  private String _host = null;
+
+  /**
+   * Target web container port
+   */
+  private int _port = DEFAULT_HTTP_PORT;
+
+  /**
+   * Is the request going over SSL
+   */
+  private boolean _isSecure = false;
+
+  /**
+   * HTTP state
+   */
+  private HttpState _state = null;
+
+  /**
+   * Original request line for this request.
+   */
+  private String _requestLine = null;
+
+  /**
+   * Authentication type for current request
+   */
+  private int _authType = NO_AUTHENTICATION;
+
+  /**
+   * Flag to determine if session tracking will be used or not.
+   */
+  private boolean _useCookies = false;
+
+  /**
+   * Content length of request body.
+   */
+  private int _contentLength = 0;
+
+  /**
+   * FollowRedirects
+   */
+  private boolean _redirect = false;
+
+  Header[] _headers = null;
+
+  protected HttpClient client = null;
+
+  /**
+   * Creates new HttpRequest based of the passed request line. The request line
+   * provied must be in the form of:<br>
+   * 
+   * <pre>
+   *     METHOD PATH HTTP-VERSION
+   *     Ex.  GET /index.html HTTP/1.0
+   * </pre>
+   */
+  public HttpRequest(String requestLine, String host, int port) {
+    client = new HttpClient();
+    _method = MethodFactory.getInstance(requestLine);
+    _method.setFollowRedirects(false);
+    _host = host;
+    _port = port;
+
+    if (port == DEFAULT_SSL_PORT) {
+      _isSecure = true;
+    }
+
+    // If we got this far, the request line is in the proper
+    // format
+    _requestLine = requestLine;
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * <code>getRequestPath</code> returns the request path for this particular
+   * request.
+   *
+   * @return String request path
+   */
+  public String getRequestPath() {
+    return _method.getPath();
+  }
+
+  /**
+   * <code>getRequestMethod</code> returns the request type, i.e., GET, POST,
+   * etc.
+   *
+   * @return String request type
+   */
+  public String getRequestMethod() {
+    return _method.getName();
+  }
+
+  /**
+   * <code>isSecureConnection()</code> indicates if the Request is secure or
+   * not.
+   *
+   * @return boolean whether Request is using SSL or not.
+   */
+  public boolean isSecureRequest() {
+    return _isSecure;
+  }
+
+  /**
+   * <code>setSecureRequest</code> configures this request to use SSL.
+   *
+   * @param secure
+   *          - whether the Request uses SSL or not.
+   */
+  public void setSecureRequest(boolean secure) {
+    _isSecure = secure;
+  }
+
+  /**
+   * <code>setContent</code> will set the body for this request. Note, this is
+   * only valid for POST and PUT operations, however, if called and the request
+   * represents some other HTTP method, it will be no-op'd.
+   *
+   * @param content
+   *          request content
+   */
+  public void setContent(String content) {
+    if (_method instanceof EntityEnclosingMethod) {
+      ((EntityEnclosingMethod) _method)
+          .setRequestEntity(new StringRequestEntity(content));
+    }
+    _contentLength = content.length();
+  }
+
+  /**
+   * <code>setAuthenticationCredentials configures the request to
+   * perform authentication.
+   *
+   * <p><code>username</code> and <code>password</code> cannot be null.
+   * </p>
+   *
+   * <p>
+   * It is legal for <code>realm</code> to be null.
+   * </p>
+   *
+   * @param username
+   *          the user
+   * @param password
+   *          the user's password
+   * @param authType
+   *          authentication type
+   * @param realm
+   *          authentication realm
+   */
+  public void setAuthenticationCredentials(String username, String password,
+      int authType, String realm) {
+    if (username == null) {
+      throw new IllegalArgumentException("Username cannot be null");
+    }
+
+    if (password == null) {
+      throw new IllegalArgumentException("Password cannot be null");
+    }
+
+    UsernamePasswordCredentials cred = new UsernamePasswordCredentials(username,
+        password);
+    AuthScope scope = new AuthScope(_host, _port, realm);
+    getState().setCredentials(scope, cred);
+    TestUtil.logTrace("[HttpRequest] Added credentials for '" + username
+        + "' with password '" + password + "' in realm '" + realm + "'");
+
+    _authType = authType;
+  }
+
+  /**
+   * <code>addRequestHeader</code> adds a request header to this request. If a
+   * request header of the same name already exists, the new value, will be
+   * added to the set of already existing values.
+   *
+   * <strong>NOTE:</strong> that header names are not case-sensitive.
+   *
+   * @param headerName
+   *          request header name
+   * @param headerValue
+   *          request header value
+   */
+  public void addRequestHeader(String headerName, String headerValue) {
+    _method.addRequestHeader(headerName, headerValue);
+    TestUtil.logTrace("[HttpRequest] Added request header: "
+        + _method.getRequestHeader(headerName).toExternalForm());
+  }
+
+  public void addRequestHeader(String header) {
+    StringTokenizer st = new StringTokenizer(header, "|");
+    while (st.hasMoreTokens()) {
+      String h = st.nextToken();
+      if (h.toLowerCase().startsWith("cookie")) {
+        createCookie(h);
+        continue;
+      }
+      int col = h.indexOf(':');
+      addRequestHeader(h.substring(0, col).trim(), h.substring(col + 1).trim());
+    }
+  }
+
+  /**
+   * <code>setRequestHeader</code> sets a request header for this request
+   * overwritting any previously existing header/values with the same name.
+   *
+   * <strong>NOTE:</strong> Header names are not case-sensitive.
+   *
+   * @param headerName
+   *          request header name
+   * @param headerValue
+   *          request header value
+   */
+  public void setRequestHeader(String headerName, String headerValue) {
+    _method.setRequestHeader(headerName, headerValue);
+    TestUtil.logTrace("[HttpRequest] Set request header: "
+        + _method.getRequestHeader(headerName).toExternalForm());
+
+  }
+
+  /**
+   * <code>setFollowRedirects</code> indicates whether HTTP redirects are
+   * followed. By default, redirects are not followed.
+   */
+  public void setFollowRedirects(boolean followRedirects) {
+    _method.setFollowRedirects(followRedirects);
+  }
+
+  /**
+   * <code>getFollowRedirects</code> indicates whether HTTP redirects are
+   * followed.
+   */
+  public boolean getFollowRedirects() {
+    return _method.getFollowRedirects();
+  }
+
+  /**
+   * <code>setState</code> will set the HTTP state for the current request (i.e.
+   * session tracking). This has the side affect
+   */
+  public void setState(HttpState state) {
+    _state = state;
+    _useCookies = true;
+  }
+
+  /**
+   * <code>execute</code> will dispatch the current request to the target
+   * server.
+   *
+   * @return HttpResponse the server's response.
+   * @throws IOException
+   *           if an I/O error occurs during dispatch.
+   */
+  public HttpResponse execute() throws IOException, HttpException {
+    String method;
+    int defaultPort;
+    ProtocolSocketFactory factory;
+
+    if (_method.getFollowRedirects()) {
+      client = new HttpClient();
+
+      if (_isSecure) {
+        method = "https";
+        defaultPort = DEFAULT_SSL_PORT;
+        factory = new SSLProtocolSocketFactory();
+      } else {
+        method = "http";
+        defaultPort = DEFAULT_HTTP_PORT;
+        factory = new DefaultProtocolSocketFactory();
+      }
+
+      Protocol protocol = new Protocol(method, factory, defaultPort);
+      HttpConnection conn = new HttpConnection(_host, _port, protocol);
+
+      if (conn.isOpen()) {
+        throw new IllegalStateException("Connection incorrectly opened");
+      }
+
+      conn.open();
+
+      TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine
+          + "' to target server at '" + _host + ":" + _port + "'");
+
+      addSupportHeaders();
+      _headers = _method.getRequestHeaders();
+
+      TestUtil.logTrace(
+          "########## The real value set: " + _method.getFollowRedirects());
+
+      client.getHostConfiguration().setHost(_host, _port, protocol);
+
+      client.executeMethod(_method);
+
+      return new HttpResponse(_host, _port, _isSecure, _method, getState());
+    } else {
+      if (_isSecure) {
+        method = "https";
+        defaultPort = DEFAULT_SSL_PORT;
+        factory = new SSLProtocolSocketFactory();
+      } else {
+        method = "http";
+        defaultPort = DEFAULT_HTTP_PORT;
+        factory = new DefaultProtocolSocketFactory();
+      }
+
+      Protocol protocol = new Protocol(method, factory, defaultPort);
+      HttpConnection conn = new HttpConnection(_host, _port, protocol);
+
+      if (conn.isOpen()) {
+        throw new IllegalStateException("Connection incorrectly opened");
+      }
+
+      conn.open();
+
+      TestUtil.logMsg("[HttpRequest] Dispatching request: '" + _requestLine
+          + "' to target server at '" + _host + ":" + _port + "'");
+
+      addSupportHeaders();
+      _headers = _method.getRequestHeaders();
+
+      TestUtil.logTrace(
+          "########## The real value set: " + _method.getFollowRedirects());
+
+      _method.execute(getState(), conn);
+
+      return new HttpResponse(_host, _port, _isSecure, _method, getState());
+    }
+  }
+
+  /**
+   * Returns the current state for this request.
+   *
+   * @return HttpState current state
+   */
+  public HttpState getState() {
+    if (_state == null) {
+      _state = new HttpState();
+    }
+    return _state;
+  }
+
+  public String toString() {
+    StringBuffer sb = new StringBuffer(255);
+    sb.append("[REQUEST LINE] -> ").append(_requestLine).append('\n');
+
+    if (_headers != null && _headers.length != 0) {
+
+      for (Header _header : _headers) {
+        sb.append("       [REQUEST HEADER] -> ");
+        sb.append(_header.toExternalForm()).append('\n');
+      }
+    }
+
+    if (_contentLength != 0) {
+      sb.append("       [REQUEST BODY LENGTH] -> ").append(_contentLength);
+      sb.append('\n');
+    }
+
+    return sb.toString();
+
+  }
+
+  /*
+   * private methods
+   * ========================================================================
+   */
+
+  private void createCookie(String cookieHeader) {
+    String cookieLine = cookieHeader.substring(cookieHeader.indexOf(':') + 1)
+        .trim();
+    StringTokenizer st = new StringTokenizer(cookieLine, " ;");
+    Cookie cookie = new Cookie();
+    cookie.setVersion(1);
+
+    getState();
+
+    if (cookieLine.indexOf("$Version") == -1) {
+      cookie.setVersion(0);
+      _method.getParams().setCookiePolicy(CookiePolicy.NETSCAPE);
+    }
+
+    while (st.hasMoreTokens()) {
+      String token = st.nextToken();
+
+      if (token.charAt(0) != '$' && !token.startsWith("Domain")
+          && !token.startsWith("Path")) {
+        cookie.setName(token.substring(0, token.indexOf('=')));
+        cookie.setValue(token.substring(token.indexOf('=') + 1));
+      } else if (token.indexOf("Domain") > -1) {
+        cookie.setDomainAttributeSpecified(true);
+        cookie.setDomain(token.substring(token.indexOf('=') + 1));
+      } else if (token.indexOf("Path") > -1) {
+        cookie.setPathAttributeSpecified(true);
+        cookie.setPath(token.substring(token.indexOf('=') + 1));
+      }
+    }
+    _state.addCookie(cookie);
+
+  }
+
+  /**
+   * Adds any support request headers necessary for this request. These headers
+   * will be added based on the state of the request.
+   */
+  private void addSupportHeaders() {
+
+    // Authentication headers
+    // NOTE: Possibly move logic to generic method
+    switch (_authType) {
+    case NO_AUTHENTICATION:
+      break;
+    case BASIC_AUTHENTICATION:
+      setBasicAuthorizationHeader();
+      break;
+    case DIGEST_AUTHENTICATION:
+      throw new UnsupportedOperationException(
+          "Digest Authentication is not currently " + "supported");
+    }
+
+    // A Host header will be added to each request to handle
+    // cases where virtual hosts are used, or there is no DNS
+    // available on the system where the container is running.
+    setHostHeader();
+
+    // Content length header
+    setContentLengthHeader();
+
+    // Cookies
+    setCookieHeader();
+  }
+
+  /**
+   * Sets a basic authentication header in the request is Request is configured
+   * to use basic authentication
+   */
+  private void setBasicAuthorizationHeader() {
+    UsernamePasswordCredentials cred = (UsernamePasswordCredentials) getState()
+        .getCredentials(new AuthScope(_host, _port, null));
+    String authString = null;
+    if (cred != null) {
+      authString = "Basic " + Util.getBase64EncodedString(
+          cred.getUserName() + ":" + cred.getPassword());
+    } else {
+      TestUtil.logTrace("[HttpRequest] NULL CREDENTIALS");
+    }
+    _method.setRequestHeader("Authorization", authString);
+  }
+
+  /**
+   * Sets a Content-Length header in the request if content is present
+   */
+  private void setContentLengthHeader() {
+    if (_contentLength > 0) {
+      _method.setRequestHeader("Content-Length",
+          Integer.toString(_contentLength));
+    }
+  }
+
+  /**
+   * Sets a host header in the request. If the configured host value is an IP
+   * address, the Host header will be sent, but without any value.
+   *
+   * If we adhered to the HTTP/1.1 spec, the Host header must be empty of the
+   * target server is identified via IP address. However, no user agents I've
+   * tested follow this. And if a custom client library does this, it may not
+   * work properly with the target server. For now, the Host request-header will
+   * always have a value.
+   */
+  private void setHostHeader() {
+    if (_port == DEFAULT_HTTP_PORT || _port == DEFAULT_SSL_PORT) {
+      _method.setRequestHeader("Host", _host);
+    } else {
+      _method.setRequestHeader("Host", _host + ":" + _port);
+    }
+  }
+
+  /**
+   * Sets a Cookie header if this request is using cookies.
+   */
+  private void setCookieHeader() {
+    if (_useCookies) {
+      Cookie[] cookies = _state.getCookies();
+      if (cookies != null && cookies.length > 0) {
+        Header cHeader = CookiePolicy.getCookieSpec(CookiePolicy.RFC_2109)
+            .formatCookieHeader(_state.getCookies());
+        if (cHeader != null) {
+          _method.setRequestHeader(cHeader);
+        }
+      }
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java
new file mode 100644
index 0000000..177d6df
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/HttpResponse.java
@@ -0,0 +1,313 @@
+/*
+ * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpState;
+import org.apache.commons.httpclient.HttpVersion;
+
+import jakarta.ws.rs.tck.common.webclient.Util;
+
+/**
+ * This class represents an HTTP response from the server.
+ */
+
+public class HttpResponse {
+
+  /**
+   * Default encoding based on Servlet Specification
+   */
+  private static final String DEFAULT_ENCODING = "ISO-8859-1";
+
+  /**
+   * Content-Type header
+   */
+  private static final String CONTENT_TYPE = "Content-Type";
+
+  /**
+   * Wrapped HttpMethod used to pull response info from.
+   */
+  private HttpMethod _method = null;
+
+  /**
+   * HttpState obtained after execution of request
+   */
+  private HttpState _state = null;
+
+  /**
+   * Charset encoding returned in the response
+   */
+  private String _encoding = DEFAULT_ENCODING;
+
+  /**
+   * The response body. Initialized after first call to one of the
+   * getResponseBody methods and cached for subsequent calls.
+   */
+  private String _responseBody = null;
+
+  /**
+   * Host name used for processing request
+   */
+  private String _host = null;
+
+  /**
+   * Port number used for processing request
+   */
+  private int _port;
+
+  /**
+   * Issecure
+   */
+  private boolean _isSecure;
+
+  /** Creates new HttpResponse */
+  public HttpResponse(String host, int port, boolean isSecure,
+      HttpMethod method, HttpState state) {
+
+    _host = host;
+    _port = port;
+    _isSecure = isSecure;
+    _method = method;
+    _state = state;
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns the HTTP status code returned by the server
+   *
+   * @return HTTP status code
+   */
+  public String getStatusCode() {
+    return Integer.toString(_method.getStatusCode());
+  }
+
+  /**
+   * Returns the HTTP reason-phrase returned by the server
+   *
+   * @return HTTP reason-phrase
+   */
+  public String getReasonPhrase() {
+    return _method.getStatusText();
+  }
+
+  /**
+   * Returns the headers received in the response from the server.
+   *
+   * @return response headers
+   */
+  public Header[] getResponseHeaders() {
+    return _method.getResponseHeaders();
+  }
+
+  /**
+   * Returns the headers designated by the name provided.
+   *
+   * @return response headers
+   */
+  public Header[] getResponseHeaders(String headerName) {
+    return _method.getResponseHeaders(headerName);
+  }
+
+  /**
+   * Returns the response header designated by the name provided.
+   *
+   * @return a specfic response header or null if the specified header doesn't
+   *         exist.
+   */
+  public Header getResponseHeader(String headerName) {
+    return _method.getResponseHeader(headerName);
+  }
+
+  /**
+   * Returns the response body as a byte array using the charset specified in
+   * the server's response.
+   *
+   * @return response body as an array of bytes.
+   */
+  public byte[] getResponseBodyAsBytes() throws IOException {
+    return getEncodedResponse().getBytes();
+  }
+
+  /**
+   * Returns the response as bytes (no encoding is performed by client.
+   * 
+   * @return the raw response bytes
+   * @throws IOException
+   *           if an error occurs reading from server
+   */
+  public byte[] getResponseBodyAsRawBytes() throws IOException {
+    return _method.getResponseBody();
+  }
+
+  /**
+   * Returns the response body as a string using the charset specified in the
+   * server's response.
+   *
+   * @return response body as a String
+   */
+  public String getResponseBodyAsString() throws IOException {
+    return getEncodedResponse();
+  }
+
+  /**
+   * Returns the response body of the server without being encoding by the
+   * client.
+   * 
+   * @return an unecoded String representation of the response
+   * @throws IOException
+   *           if an error occurs reading from the server
+   */
+  public String getResponseBodyAsRawString() throws IOException {
+    return _method.getResponseBodyAsString();
+  }
+
+  /**
+   * Returns the response body as an InputStream using the encoding specified in
+   * the server's response.
+   *
+   * @return response body as an InputStream
+   */
+  public InputStream getResponseBodyAsStream() throws IOException {
+    return new ByteArrayInputStream(getEncodedResponse().getBytes());
+  }
+
+  /**
+   * Returns the response body as an InputStream without any encoding applied by
+   * the client.
+   * 
+   * @return an InputStream to read the response
+   * @throws IOException
+   *           if an error occurs reading from the server
+   */
+  public InputStream getResponseBodyAsRawStream() throws IOException {
+    return _method.getResponseBodyAsStream();
+  }
+
+  /**
+   * Returns the charset encoding for this response.
+   *
+   * @return charset encoding
+   */
+  public String getResponseEncoding() {
+    Header content = _method.getResponseHeader(CONTENT_TYPE);
+    if (content != null) {
+      String headerVal = content.getValue();
+      int idx = headerVal.indexOf(";charset=");
+      if (idx > -1) {
+        // content encoding included in response
+        _encoding = headerVal.substring(idx + 9);
+      }
+    }
+    return _encoding;
+  }
+
+  /**
+   * Returns the post-request state.
+   *
+   * @return an HttpState object
+   */
+  public HttpState getState() {
+    return _state;
+  }
+
+  /**
+   * Displays a String representation of the response.
+   *
+   * @return string representation of response
+   */
+  public String toString() {
+    StringBuffer sb = new StringBuffer(255);
+
+    sb.append("[RESPONSE STATUS LINE] -> ");
+    sb.append(((HttpMethodBase) _method).getParams().getVersion()
+        .equals(HttpVersion.HTTP_1_1) ? "HTTP/1.1 " : "HTTP/1.0 ");
+    sb.append(_method.getStatusCode()).append(' ');
+    sb.append(_method.getStatusText()).append('\n');
+    Header[] headers = _method.getResponseHeaders();
+    if (headers != null && headers.length != 0) {
+      for (int i = 0; i < headers.length; i++) {
+        sb.append("       [RESPONSE HEADER] -> ");
+        sb.append(headers[i].toExternalForm()).append('\n');
+      }
+    }
+
+    String resBody;
+    try {
+      resBody = _method.getResponseBodyAsString();
+    } catch (IOException ioe) {
+      resBody = "UNEXECTED EXCEPTION: " + ioe.toString();
+    }
+    if (resBody != null && resBody.length() != 0) {
+      sb.append("------ [RESPONSE BODY] ------\n");
+      sb.append(resBody);
+      sb.append("\n-----------------------------\n\n");
+    }
+    return sb.toString();
+  }
+
+  /*
+   * Eventually they need to come from _method
+   */
+
+  public String getHost() {
+    return _host;
+  }
+
+  public int getPort() {
+    return _port;
+  }
+
+  public String getProtocol() {
+    return _isSecure ? "https" : "http";
+  }
+
+  public String getPath() {
+    return _method.getPath();
+  }
+
+  /*
+   * Private Methods
+   * ==========================================================================
+   */
+
+  /**
+   * Returns the response body using the encoding returned in the response.
+   *
+   * @return encoded response String.
+   */
+  private String getEncodedResponse() throws IOException {
+    if (_responseBody == null) {
+      _responseBody = Util.getEncodedStringFromStream(
+          _method.getResponseBodyAsStream(), getResponseEncoding());
+    }
+    return _responseBody;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java
new file mode 100644
index 0000000..0a03141
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/http/MethodFactory.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.http;
+
+import java.util.NoSuchElementException;
+import java.util.StringTokenizer;
+
+import org.apache.commons.httpclient.HttpMethod;
+import org.apache.commons.httpclient.HttpMethodBase;
+import org.apache.commons.httpclient.HttpVersion;
+import org.apache.commons.httpclient.methods.DeleteMethod;
+import org.apache.commons.httpclient.methods.GetMethod;
+import org.apache.commons.httpclient.methods.HeadMethod;
+import org.apache.commons.httpclient.methods.OptionsMethod;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.commons.httpclient.methods.PutMethod;
+
+import jakarta.ws.rs.tck.lib.porting.TSURL;
+
+/**
+ * Simple factory class which returns HttpMethod implementations based on a
+ * request line.
+ * <p>
+ * For example, a request line of <tt>GET /index.jsp HTTP/1.0</tt> would return
+ * an HttpMethod implementation that handles GET requests using HTTP/1.0.
+ * </p>
+ */
+
+public class MethodFactory {
+
+  /**
+   * HTTP GET
+   */
+  private static final String GET_METHOD = "GET";
+
+  /**
+   * HTTP POST
+   */
+  private static final String POST_METHOD = "POST";
+
+  /**
+   * HTTP HEAD
+   */
+  private static final String HEAD_METHOD = "HEAD";
+
+  /**
+   * HTTP PUT
+   */
+  private static final String PUT_METHOD = "PUT";
+
+  /**
+   * HTTP DELETE
+   */
+  private static final String DELETE_METHOD = "DELETE";
+
+  /**
+   * HTTP OPTIONS
+   */
+  private static final String OPTIONS_METHOD = "OPTIONS";
+
+  /**
+   * TSURL implementation
+   */
+  private static final TSURL TS_URL = new TSURL();
+
+  /**
+   * Private constructor as all interaction with this class is through the
+   * getInstance() method.
+   */
+  private MethodFactory() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns the approriate request method based on the provided request string.
+   * The request must be in the format of METHOD URI_PATH HTTP_VERSION, i.e. GET
+   * /index.jsp HTTP/1.1.
+   *
+   * @return HttpMethod based in request.
+   */
+  public static HttpMethod getInstance(String request) {
+    StringTokenizer st = new StringTokenizer(request);
+    String method;
+    String query = null;
+    String uri;
+    String version;
+    try {
+      method = st.nextToken();
+      uri = TS_URL.getRequest(st.nextToken());
+      version = st.nextToken();
+    } catch (NoSuchElementException nsee) {
+      throw new IllegalArgumentException(
+          "Request provided: " + request + " is malformed.");
+    }
+
+    // check to see if there is a query string appended
+    // to the URI
+    int queryStart = uri.indexOf('?');
+    if (queryStart != -1) {
+      query = uri.substring(queryStart + 1);
+      uri = uri.substring(0, queryStart);
+    }
+
+    HttpMethodBase req;
+
+    if (method.equals(GET_METHOD)) {
+      req = new GetMethod(uri);
+    } else if (method.equals(POST_METHOD)) {
+      req = new PostMethod(uri);
+    } else if (method.equals(PUT_METHOD)) {
+      req = new PutMethod(uri);
+    } else if (method.equals(DELETE_METHOD)) {
+      req = new DeleteMethod(uri);
+    } else if (method.equals(HEAD_METHOD)) {
+      req = new HeadMethod(uri);
+    } else if (method.equals(OPTIONS_METHOD)) {
+      req = new OptionsMethod(uri);
+    } else {
+      throw new IllegalArgumentException("Invalid method: " + method);
+    }
+
+    setHttpVersion(version, req);
+
+    if (query != null) {
+      req.setQueryString(query);
+    }
+
+    return req;
+  }
+
+  /*
+   * private methods
+   * ========================================================================
+   */
+
+  /**
+   * Sets the HTTP version for the method in question.
+   *
+   * @param version
+   *          HTTP version to use for this request
+   * @param method
+   *          method to adjust HTTP version
+   */
+  private static void setHttpVersion(String version, HttpMethodBase method) {
+    final String oneOne = "HTTP/1.1";
+    method.getParams().setVersion(
+        (version.equals(oneOne) ? HttpVersion.HTTP_1_1 : HttpVersion.HTTP_1_0));
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java
new file mode 100644
index 0000000..654f181
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/CheckOneOfStatusesTokenizedValidator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import java.io.IOException;
+
+/**
+ * Sometimes it is not clear what result one should get, there might be more two
+ * or more possibilities. This strategy checks the response contains at least
+ * one of the given statuses.
+ * 
+ * The statuses are supposed to be separated by "|" character
+ * 
+ * @author Jan Supol
+ */
+public class CheckOneOfStatusesTokenizedValidator extends TokenizedValidator {
+
+  /**
+   * When WebTestCase contains more expected response codes it always means to
+   * check one of them is present; if present, other statuses are dropped. Super
+   * class method is called to get the logging messages
+   */
+  @Override
+  protected boolean checkStatusCode() throws IOException {
+    String responseCode = _res.getStatusCode();
+    String caseCodes = _case.getStatusCode();
+
+    if (caseCodes != null && caseCodes.charAt(0) != '!'
+        && caseCodes.contains("|") && caseCodes.contains(responseCode))
+      _case.setExpectedStatusCode(responseCode);
+    return super.checkStatusCode();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java
new file mode 100644
index 0000000..0237136
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/TokenizedValidator.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.util.StringTokenizer;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.Goldenfile;
+
+/**
+ * <pre>
+ * This class provides all of the functionality of the
+ * WebValidatorBase class.  Additionally, it will compare
+ * the server's response body with the test case's configured
+ * goldenfile using a StringTokenizer.
+ * </pre>
+ */
+public class TokenizedValidator extends WebValidatorBase {
+
+  /**
+   * System property that will cause the specified goldenfile to be written if
+   * it doesn't already exist.
+   */
+  private static final String RECORD_GF = "ts.record.gf";
+
+  /**
+   * Creates a new instance of TokenizedValidator
+   */
+  public TokenizedValidator() {
+  }
+
+  /*
+   * protected methods
+   * ========================================================================
+   */
+
+  /**
+   * Compare the server response and golenfile using a StringTokenizer.
+   *
+   * @return true if response and goldenfile are the same.
+   * @throws IOException
+   *           if an error occurs will processing the Goldenfile
+   */
+  protected boolean checkGoldenfile() throws IOException {
+    String gf;
+    String path = _case.getGoldenfilePath();
+    String enc = _res.getResponseEncoding();
+
+    if (path == null) {
+      return true;
+    }
+
+    Goldenfile file = new Goldenfile(_case.getGoldenfilePath(), enc);
+
+    try {
+      gf = file.getGoldenFileAsString();
+    } catch (IOException ioe) {
+      TestUtil
+          .logErr("[TokenizedValidator] Unexpected exception while accessing "
+              + "goldenfile! " + ioe.toString());
+      return false;
+    }
+
+    String response = _res.getResponseBodyAsString();
+    StringTokenizer gfTokenizer = new StringTokenizer(gf);
+    StringTokenizer resTokenizer = new StringTokenizer(response);
+    int gfCount = gfTokenizer.countTokens();
+    int resCount = resTokenizer.countTokens();
+
+    // Logic to handle the recording of goldenfiles.
+    if (gf.equals("NO GOLDENFILE FOUND") && Boolean.getBoolean(RECORD_GF)) {
+
+      TestUtil
+          .logTrace("[TokenizedValidator][INFO] RECORDING GOLDENFILE: " + path);
+      OutputStreamWriter out = new OutputStreamWriter(
+          new FileOutputStream(path), enc);
+      out.write(response);
+      out.flush();
+      out.close();
+    }
+
+    // If the token counts are the same, continue checking
+    // each individual token, otherwise, immediately fail.
+    if (gfCount == resCount) {
+      while (gfTokenizer.hasMoreTokens()) {
+        String exp = gfTokenizer.nextToken();
+        String res = resTokenizer.nextToken();
+        if (!exp.equals(res)) {
+          StringBuffer sb = new StringBuffer(255);
+          sb.append("[TokenizedValidator]: Server's response and ");
+          sb.append("goldenfile to not match!\n");
+          sb.append("\n            Goldenfile token: ").append(exp);
+          sb.append("\n            Response token:   ").append(res);
+          TestUtil.logErr(sb.toString());
+          dumpResponseInfo(response, gf);
+          return false;
+        }
+      }
+    } else {
+      TestUtil
+          .logErr("[TokenizedValidator]: Token count between server response "
+              + "and goldenfile do not match.\n Response Token" + "count: "
+              + resCount + "\nGoldenfile Token count: " + gfCount);
+
+      dumpResponseInfo(response, gf);
+      return false;
+    }
+    TestUtil.logTrace("[TokenizedValidator]: Server's response matches the "
+        + "configured goldenfile.");
+    return true;
+  }
+
+  /*
+   * private methods
+   * ========================================================================
+   */
+
+  /**
+   * Dumps the response from the server and the content of the Goldenfile/
+   * 
+   * @param serverResponse
+   *          the response body from the server.
+   * @param goldenFile
+   *          the test goldenfile
+   */
+  private static void dumpResponseInfo(String serverResponse,
+      String goldenFile) {
+    StringBuffer sb = new StringBuffer(255);
+    sb.append("\nServer Response (below):\n");
+    sb.append("------------------------------------------\n");
+    sb.append(serverResponse);
+    sb.append("\n------------------------------------------\n");
+    sb.append("\nGoldenfile (below):\n");
+    sb.append("------------------------------------------\n");
+    sb.append(goldenFile);
+    sb.append("\n------------------------------------------\n");
+    TestUtil.logErr(sb.toString());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java
new file mode 100644
index 0000000..5505d73
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+/**
+ * Returns a ValidationStrategy instance used to validate a response against a
+ * particular WebTestCase
+ *
+ * @author Ryan Lubke
+ * @version %I%
+ */
+public class ValidationFactory {
+
+  /**
+   * Private constructor as all interaction with the class is through the
+   * getInstance() method.
+   */
+  private ValidationFactory() {
+  }
+
+  /*
+   * public methods
+   * ========================================================================
+   */
+
+  /**
+   * Returns a ValidationStrategy instance based on the available factory types.
+   *
+   * @param validator
+   *          Validator instance to obtain
+   * @return a ValidationStrategy instance or null if the instance could not be
+   *         obtained.
+   */
+  public static ValidationStrategy getInstance(String validator) {
+    try {
+      Object o = Thread.currentThread().getContextClassLoader()
+          .loadClass(validator).newInstance();
+      if (o instanceof ValidationStrategy) {
+        return (ValidationStrategy) o;
+      }
+    } catch (Throwable t) {
+      TestUtil.logMsg("[ValidationFactory] Unable to obtain "
+          + "ValidationStrategy instance: " + validator);
+    }
+    return null;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java
new file mode 100644
index 0000000..f8998d9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/ValidationStrategy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+
+/**
+ * A ValidationStrategy is used to compare a server response with a configured
+ * test case. How this validation is performed is up to the concrete
+ * implementation.
+ */
+public interface ValidationStrategy {
+  public boolean validate(WebTestCase testCase);
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java
new file mode 100644
index 0000000..4a0d027
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/webclient/validation/WebValidatorBase.java
@@ -0,0 +1,669 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.common.webclient.validation;
+
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.webclient.WebTestCase;
+import jakarta.ws.rs.tck.common.webclient.handler.Handler;
+import jakarta.ws.rs.tck.common.webclient.handler.HandlerFactory;
+import jakarta.ws.rs.tck.common.webclient.http.HttpRequest;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+
+/**
+ * Base abstract class for WebTestCase validation.
+ */
+public abstract class WebValidatorBase implements ValidationStrategy {
+
+  /**
+   * Used to detect 4xx class HTTP errors to allow fail fast situations when 4xx
+   * errors are not expected.
+   */
+  protected static final char CLIENT_ERROR = '4';
+
+  /**
+   * Used to detect 5xx class HTTP errors to allows fail fast situations when
+   * 5xx errors are not expected.
+   */
+  protected static final char SERVER_ERROR = '5';
+
+  /**
+   * This test case's HttpResponse
+   */
+  protected HttpResponse _res = null;
+
+  /**
+   * This test case's HttpRequest
+   */
+  protected HttpRequest _req = null;
+
+  /**
+   * The test case being validated
+   */
+  protected WebTestCase _case = null;
+
+  /**
+   * <tt>validate</tt> Will validate the response against the configured
+   * TestCase.
+   *
+   *
+   * <ul>
+   * <li>Check the HTTP status-code</li>
+   * <li>Check the HTTP reason-phrase</li>
+   * <li>Check for expected headers</li>
+   * <li>Check from unexpected headers</li>
+   * <li>Check expected search strings</li>
+   * <li>Check unexpected search strings</li>
+   * <li>Check the goldenfile</li>
+   * </ul>
+   */
+  public boolean validate(WebTestCase testCase) {
+    _res = testCase.getResponse();
+    _req = testCase.getRequest();
+    _case = testCase;
+
+    // begin the check
+    try {
+      if (!checkStatusCode() || !checkReasonPhrase() || !checkExpectedHeaders()
+          || !checkUnexpectedHeaders() || !checkSearchStrings()
+          || !checkSearchStringsNoCase() || !checkUnorderedSearchStrings()
+          || !checkUnexpectedSearchStrings() || !checkGoldenfile()) {
+        return false;
+      }
+    } catch (IOException ioe) {
+      TestUtil
+          .logErr("[WebValidatorBase] Unexpected Exception: " + ioe.toString());
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * <code>checkStatusCode</code> will perform status code comparisons based on
+   * the algorithm below
+   * <ul>
+   * <li>Check the HTTP status code</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If status code is -1, then return true
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If test case status code null and response 4xx, return failure, print
+   * error; return false
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If test case status code null and response 5xx, return failure include
+   * response body; return false
+   * <p>
+   * </li>
+   * <li>
+   * <p>
+   * If test case status code null, and response not 4xx or 5xx, return true
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * Test case status code not null, compare it with the response status code;
+   * return true if equal
+   * <p>
+   * <li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected boolean checkStatusCode() throws IOException {
+    String sCode = _case.getStatusCode();
+    String resCode = _res.getStatusCode();
+    if ("-1".equals(sCode))
+      return true;
+
+    if (sCode == null && resCode.charAt(0) == CLIENT_ERROR) {
+      TestUtil
+          .logErr("[WebValidatorBase] Unexpected " + resCode + " received from "
+              + "target server!  Request path: " + _req.getRequestPath());
+      return false;
+    }
+
+    if (sCode == null && (resCode.charAt(0) == SERVER_ERROR)) {
+      String resBody = _res.getResponseBodyAsRawString();
+      StringBuffer sb = new StringBuffer(75 + resBody.length());
+      sb.append("[WebValidatorBase] Unexpected '");
+      sb.append(resCode).append("' received from target server!\n");
+      sb.append("Error response recieved from server:\n");
+      sb.append("------------------------------------------------\n");
+      sb.append(resBody != null ? resBody : "NO RESPONSE");
+      TestUtil.logErr(sb.toString());
+      return false;
+    }
+
+    if (sCode == null) {
+      return true;
+    }
+
+    // test status code not null, compare with that of the response
+    if (sCode.charAt(0) != '!') {
+      if (!sCode.equals(resCode)) {
+        TestUtil.logErr("[WebValidatorBase] Unexpected Status Code "
+            + "recieved from server.  Expected '" + sCode + "' received '"
+            + resCode + "'");
+        return false;
+      }
+
+      TestUtil.logTrace("[WebValidatorBase] Expected Status Code '" + sCode
+          + "' found in response line!");
+    } else {
+      sCode = sCode.substring(1);
+      if (sCode.equals(resCode)) {
+        TestUtil.logErr("[WebValidatorBase] Unexpected Status Code "
+            + "recieved from server.  Expected any value except '" + sCode
+            + "', received '" + resCode + "'");
+        return false;
+      }
+
+      TestUtil.logTrace("[WebValidatorBase] Status Code '" + sCode
+          + "' not found in response line!");
+    }
+
+    return true;
+  }
+
+  /**
+   * <code>checkSearchStrings</code> will scan the response for the configured
+   * strings that are to be expected in the response.
+   * <ul>
+   * <li>Check search strings</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If list of Strings is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If list of Strings is not null, scan response body. If string is found,
+   * return true, otherwise display error and return false.
+   * </p>
+   * </li>
+   * </ul>
+   * </ul>
+   * <em>NOTE:</em> If there are multiple search strings, the search will be
+   * performed as such to preserve the order. For example, if the list of search
+   * strings contains two entities, the search for the second entity will be
+   * started after the index if the first match.
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected boolean checkSearchStrings() throws IOException {
+    List list = _case.getSearchStrings();
+    boolean found = true;
+    if (list != null && !list.isEmpty()) {
+      String responseBody = _res.getResponseBodyAsRawString();
+
+      String search = null;
+
+      for (int i = 0, n = list.size(), startIdx = 0, bodyLength = responseBody
+          .length(); i < n; i++) {
+
+        // set the startIdx to the same value as the body length
+        // and let the test fail (prevents index based runtime
+        // exceptions).
+        if (startIdx >= bodyLength) {
+          startIdx = bodyLength;
+        }
+
+        search = (String) list.get(i);
+        int searchIdx = responseBody.indexOf(search, startIdx);
+
+        TestUtil.logTrace(
+            "[WebValidatorBase] Scanning response for " + "search string: '"
+                + search + "' starting at index " + "location: " + startIdx);
+        if (searchIdx < 0) {
+          found = false;
+          StringBuffer sb = new StringBuffer(255);
+          sb.append("[WebValidatorBase] Unable to find the following ");
+          sb.append("search string in the server's ");
+          sb.append("response: '").append(search).append("' at index: ");
+          sb.append(startIdx);
+          sb.append("\n[WebValidatorBase] Server's response:\n");
+          sb.append("-------------------------------------------\n");
+          sb.append(responseBody);
+          sb.append("\n-------------------------------------------\n");
+          TestUtil.logErr(sb.toString());
+          break;
+        }
+
+        TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+            + "' at index '" + searchIdx + "' in the server's " + "response");
+        // the new searchIdx is the old index plus the lenght of the
+        // search string.
+        startIdx = searchIdx + search.length();
+      }
+    }
+    return found;
+  }
+
+  /**
+   * <code>checkSearchStringsNoCase</code> will scan the response for the
+   * configured case insensitive strings that are to be expected in the
+   * response.
+   * <ul>
+   * <li>Check search strings</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If list of Strings is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If list of Strings is not null, scan response body. If string is found,
+   * return true, otherwise display error and return false.
+   * </p>
+   * </li>
+   * </ul>
+   * </ul>
+   * <em>NOTE:</em> If there are multiple search strings, the search will be
+   * performed as such to preserve the order. For example, if the list of search
+   * strings contains two entities, the search for the second entity will be
+   * started after the index if the first match.
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected boolean checkSearchStringsNoCase() throws IOException {
+    List list = _case.getSearchStringsNoCase();
+    boolean found = true;
+    if (list != null && !list.isEmpty()) {
+      String responseBody = _res.getResponseBodyAsRawString();
+
+      String search = null;
+
+      for (int i = 0, n = list.size(), startIdx = 0, bodyLength = responseBody
+          .length(); i < n; i++) {
+
+        // set the startIdx to the same value as the body length
+        // and let the test fail (prevents index based runtime
+        // exceptions).
+        if (startIdx >= bodyLength) {
+          startIdx = bodyLength;
+        }
+
+        search = (String) list.get(i);
+        int searchIdx = responseBody.toLowerCase().indexOf(search.toLowerCase(),
+            startIdx);
+
+        TestUtil.logTrace(
+            "[WebValidatorBase] Scanning response for " + "search string: '"
+                + search + "' starting at index " + "location: " + startIdx);
+        if (searchIdx < 0) {
+          found = false;
+          StringBuffer sb = new StringBuffer(255);
+          sb.append("[WebValidatorBase] Unable to find the following ");
+          sb.append("search string in the server's ");
+          sb.append("response: '").append(search).append("' at index: ");
+          sb.append(startIdx);
+          sb.append("\n[WebValidatorBase] Server's response:\n");
+          sb.append("-------------------------------------------\n");
+          sb.append(responseBody);
+          sb.append("\n-------------------------------------------\n");
+          TestUtil.logErr(sb.toString());
+          break;
+        }
+
+        TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+            + "' at index '" + searchIdx + "' in the server's " + "response");
+        // the new searchIdx is the old index plus the lenght of the
+        // search string.
+        startIdx = searchIdx + search.length();
+      }
+    }
+    return found;
+  }
+
+  /**
+   * <code>checkUnorderedSearchStrings</code> will scan the response for the
+   * configured strings that are to be expected in the response.
+   * <ul>
+   * <li>Check search strings</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If list of Strings is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If list of Strings is not null, scan response body. If string is found,
+   * return true, otherwise display error and return false.
+   * </p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected boolean checkUnorderedSearchStrings() throws IOException {
+    List list = _case.getUnorderedSearchStrings();
+    boolean found = true;
+    if (list != null && !list.isEmpty()) {
+      String responseBody = _res.getResponseBodyAsRawString();
+
+      String search = null;
+
+      for (int i = 0, n = list.size(); i < n; i++) {
+
+        search = (String) list.get(i);
+        int searchIdx = responseBody.indexOf(search);
+
+        TestUtil.logTrace("[WebValidatorBase] Scanning response for "
+            + "search string: '" + search + "'...");
+        if (searchIdx < 0) {
+          found = false;
+          StringBuffer sb = new StringBuffer(255);
+          sb.append("[WebValidatorBase] Unable to find the following ");
+          sb.append("search string in the server's ");
+          sb.append("response: '").append(search);
+          sb.append("\n[WebValidatorBase] Server's response:\n");
+          sb.append("-------------------------------------------\n");
+          sb.append(responseBody);
+          sb.append("\n-------------------------------------------\n");
+          TestUtil.logErr(sb.toString());
+          break;
+        }
+
+        TestUtil.logTrace("[WebValidatorBase] Found search string: '" + search
+            + "' at index '" + searchIdx + "' in the server's " + "response");
+      }
+    }
+    return found;
+  }
+
+  /**
+   * <code>checkUnexpectedSearchStrings</code> will scan the response for the
+   * configured strings that are not expected in the response.
+   * <ul>
+   * <li>Check unexpected search strings</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If list of Strings is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If list of Strings is not null, scan response body. If string is not found,
+   * return true, otherwise display error and return false.
+   * <p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected boolean checkUnexpectedSearchStrings() throws IOException {
+    List list = _case.getUnexpectedSearchStrings();
+    if (list != null && !list.isEmpty()) {
+      String responseBody = _res.getResponseBodyAsRawString();
+      Iterator iter = list.iterator();
+      while (iter.hasNext()) {
+        String search = (String) iter.next();
+        TestUtil.logTrace("[WebValidatorBase] Scanning response.  The following"
+            + " string should not be present in the response: '" + search
+            + "'");
+        if (responseBody.indexOf(search) > -1) {
+          StringBuffer sb = new StringBuffer(255);
+          sb.append("[WebValidatorBase] Found the following unexpected ");
+          sb.append("search string in the server's ");
+          sb.append("response: '").append(search).append("'");
+          sb.append("\n[WebValidatorBase] Server's response:\n");
+          sb.append("-------------------------------------------\n");
+          sb.append(responseBody);
+          sb.append("\n-------------------------------------------\n");
+          TestUtil.logErr(sb.toString());
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * <code>checkGoldenFile</code> compare the server's response with the
+   * configured goldenfile
+   * <ul>
+   * <li>Check the goldenfile</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If goldenfile is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If goldenfile is not null, compare the goldenfile with the response. If
+   * equal, return true, otherwise display error and return false.
+   * <p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   * @throws IOException
+   *           if an IO error occurs during validation
+   */
+  protected abstract boolean checkGoldenfile() throws IOException;
+
+  /**
+   * <code>checkReasonPhrase</code> will perform comparisons between the
+   * configued reason-phrase and that of the response.
+   * <ul>
+   * <li>Check reason-phrase</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If configured reason-phrase is null, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If configured reason-phrase is not null, compare the reason-phrases with
+   * the response. If equal, return true, otherwise display error and return
+   * false.
+   * <p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   */
+  protected boolean checkReasonPhrase() {
+    String sReason = _case.getReasonPhrase();
+    String resReason = _res.getReasonPhrase();
+
+    if (sReason == null) {
+      return true;
+    } else if (sReason.equalsIgnoreCase(resReason)) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  /**
+   * <code>checkExpectedHeaders</code> will check the response for the
+   * configured expected headers.
+   * <ul>
+   * <li>Check expected headers</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If there are no expected headers, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If there are expected headers, scan the response for the expected headers.
+   * If all expected headers are found, return true, otherwise display an error
+   * and return false.
+   * <p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   */
+  protected boolean checkExpectedHeaders() {
+    Header[] expected = _case.getExpectedHeaders();
+    if (isEmpty(expected)) {
+      return true;
+    } else {
+      boolean found = true;
+      Header currentHeader = null;
+      for (int i = 0; i < expected.length; i++) {
+        currentHeader = expected[i];
+        Header resHeader = _res.getResponseHeader(currentHeader.getName());
+        if (resHeader != null) {
+          Handler handler = HandlerFactory.getHandler(currentHeader.getName());
+          if (!handler.invoke(currentHeader, resHeader)) {
+            found = false;
+            break;
+          }
+        } else {
+          found = false;
+          break;
+        }
+      }
+      if (!found) {
+        StringBuffer sb = new StringBuffer(255);
+        sb.append("[WebValidatorBase] Unable to find the following header");
+        sb.append(" in the server's response: ");
+        sb.append(currentHeader.toExternalForm()).append("\n");
+        sb.append("[WebValidatorBase] Response headers recieved from");
+        sb.append(" server:");
+
+        Header[] resHeaders = _res.getResponseHeaders();
+        for (int i = 0; i < resHeaders.length; i++) {
+          sb.append("\n\tResponseHeader -> ");
+          sb.append(resHeaders[i].toExternalForm());
+        }
+        sb.append("\n");
+        TestUtil.logErr(sb.toString());
+
+        return false;
+      } else {
+        TestUtil.logTrace("[WebValidatorBase] Found expected header: "
+            + currentHeader.toExternalForm());
+        return true;
+      }
+    }
+  }
+
+  /**
+   * <code>checkUnexpectedHeaders</code> will check the response for the
+   * configured unexpected expected headers.
+   * <ul>
+   * <li>Check unexpected headers</li>
+   * <ul>
+   * <li>
+   * <p>
+   * If there are no configured unexpected headers, return true.
+   * </p>
+   * </li>
+   * <li>
+   * <p>
+   * If there are configured unexpected headers, scan the response for the
+   * unexpected headers. If the headers are not found, return true, otherwise
+   * display an error and return false.
+   * <p>
+   * </li>
+   * </ul>
+   * </ul>
+   *
+   * @return boolen result of check
+   */
+  protected boolean checkUnexpectedHeaders() {
+    Header[] unexpected = _case.getUnexpectedHeaders();
+    if (isEmpty(unexpected)) {
+      return true;
+    } else {
+      Header currentHeader = null;
+      for (int i = 0; i < unexpected.length; i++) {
+        currentHeader = unexpected[i];
+        String currName = currentHeader.getName();
+        String currValue = currentHeader.getValue();
+        Header resHeader = _res.getResponseHeader(currName);
+        if (resHeader != null) {
+          if (resHeader.getValue().equals(currValue)) {
+            StringBuffer sb = new StringBuffer(255);
+            sb.append("[WebValidatorBase] Unexpected header found in the ");
+            sb.append("server's response: ");
+            sb.append(currentHeader.toExternalForm()).append("\n");
+            sb.append("[WebValidatorBase] Response headers recieved from");
+            sb.append("server:");
+
+            Header[] resHeaders = _res.getResponseHeaders();
+            for (int j = 0; j < resHeaders.length; j++) {
+              sb.append("\n\tResponseHeader -> ");
+              sb.append(resHeaders[j].toExternalForm());
+            }
+            sb.append("\n");
+            TestUtil.logErr(sb.toString());
+
+            return false;
+          }
+        }
+      }
+    }
+    return true;
+  }
+
+  /**
+   * Utility method to determine of the expected or unexpected headers are empty
+   * or not.
+   */
+  protected boolean isEmpty(Header[] headers) {
+    if (headers == null || headers.length == 0) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java
new file mode 100644
index 0000000..bedbc29
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/JAXRSClientIT.java
@@ -0,0 +1,3258 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.asyncinvoker;
+
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.client.JdkLoggingFilter;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.AsyncInvoker;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -696868584437674095L;
+
+  protected long millis;
+
+  protected int callbackResult = 0;
+
+  protected Throwable callbackException = null;
+
+  private final static String NONEXISTING_SITE = "somenonexisting.domain-site";
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("jaxrs_ee_rs_client_asyncinvoker_web/resource");
+  }
+
+  static final String[] METHODS = { "DELETE", "GET", "OPTIONS" };
+
+  static final String[] ENTITY_METHODS = { "PUT", "POST" };
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template");
+    // Replace the servlet_adaptor in web.xml.template with the System variable set as servlet adaptor
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_asyncinvoker_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  /* Run test */
+  // --------------------------------------------------------------------
+  // ---------------------- DELETE --------------------------------------
+  // --------------------------------------------------------------------
+  /*
+   * @testName: deleteTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:375;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("delete");
+    Future<Response> future = async.delete();
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:375;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    Future<Response> future = async.delete();
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: deleteThrowsExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:375;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void deleteThrowsExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("delete");
+    Future<Response> future = async.delete();
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:376;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithStringClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    Future<String> future = async.delete(String.class);
+    checkFutureString(future, "delete");
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:376;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    Future<Response> future = async.delete(Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:376;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void deleteWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("delete");
+    Future<String> future = async.delete(String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:376;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    Future<String> future = async.delete(String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:376;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    Future<Response> future = async.delete(Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:377;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.delete(generic);
+    checkFutureString(future, "delete");
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:377;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.delete(generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:377;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void deleteWithGenericTypeThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("delete");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.delete(generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:377;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.delete(generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName:
+   * deleteWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:377;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.delete(generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: deleteWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:378;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithCallbackWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    InvocationCallback<Response> callback = createCallback(true);
+    Future<Response> future = async.delete(callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithCallbackStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:378;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void deleteWithCallbackStringWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    InvocationCallback<String> callback = createStringCallback(true);
+    Future<String> future = async.delete(callback);
+    checkFutureString(future, "delete");
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: deleteWithCallbackStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:378;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void deleteWithCallbackStringThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("deleteandwait");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.delete(callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithCallbackStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:378;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithCallbackStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.delete(callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: deleteWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:378;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void deleteWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("deletenotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.delete(callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------GET------------------------------------
+  // ------------------------------------------------------------------
+  /*
+   * @testName: getTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:379;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("get");
+    Future<Response> future = async.get();
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: getWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:379;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    Future<Response> future = async.get();
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: getThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:379;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void getThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("get");
+    Future<Response> future = async.get();
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:380;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithStringClassWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    Future<String> future = async.get(String.class);
+    checkFutureString(future, "get");
+    //return future;
+  }
+
+  /*
+   * @testName: getWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:380;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    Future<Response> future = async.get(Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: getWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:380;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void getWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("get");
+    Future<String> future = async.get(String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:380;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    Future<String> future = async.get(String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:380;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    Future<Response> future = async.get(Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: getWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:381;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.get(generic);
+    checkFutureString(future, "get");
+    //return future;
+  }
+
+  /*
+   * @testName: getWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:381;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.get(generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: getWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:381;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void getWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("get");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.get(generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:381;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.get(generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:381;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.get(generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: getWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:382;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithCallbackWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    InvocationCallback<Response> callback = createCallback(true);
+    Future<Response> future = async.get(callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: getWithCallbackStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:382;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void getWithCallbackStringWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getandwait");
+    InvocationCallback<String> callback = createStringCallback(true);
+    Future<String> future = async.get(callback);
+    checkFutureString(future, "get");
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: getWithCallbackStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:382;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void getWithCallbackStringThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("get");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.get(callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithCallbackStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:382;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithCallbackStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.get(callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: getWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:382;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void getWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("getnotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.get(callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------HEAD-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: headTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:383;
+   * 
+   * @test_Strategy: Invoke HTTP HEAD method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void headTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("head");
+    Future<Response> future = async.head();
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: headWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:383;
+   * 
+   * @test_Strategy: Invoke HTTP HEAD method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void headWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("headandwait");
+    Future<Response> future = async.head();
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: headThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:383;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void headThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("head");
+    Future<Response> future = async.head();
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: headWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:384;
+   * 
+   * @test_Strategy: Invoke HTTP HEAD method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void headWithCallbackWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("headandwait");
+    InvocationCallback<Response> callback = createCallback(true);
+    Future<Response> future = async.head(callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: headWithCallbackStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:384;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void headWithCallbackStringThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("head");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.head(callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------METHOD-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: methodTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:385;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodTest() throws Fault {
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method);
+      checkFutureOkResponseNoTime(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:385;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWhileServerWaitTest() throws Fault {
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:385;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:386;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithStringClassWhileServerWaitTest()
+      throws Fault {
+    Future<String> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, String.class);
+      checkFutureString(future, method);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:386;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, Response.class);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:386;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<String> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method, String.class);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:386;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    Future<String> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, String.class);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:386;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, Response.class);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:387;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, generic);
+      checkFutureString(future, method);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:387;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, generic);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:387;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithGenericTypeThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<Response> future = null;
+    GenericType<Response> generic = createGeneric(Response.class);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method, generic);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:387;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Future<String> future = null;
+    GenericType<String> generic = createGeneric(String.class);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, generic);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:387;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    GenericType<Response> generic = createGeneric(Response.class);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, generic);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:388;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithCallbackWhileServerWaitTest() throws Fault {
+    InvocationCallback<Response> callback = createCallback(true);
+    Future<Response> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, callback);
+      checkFutureOkResponse(future);
+      assertCallbackCall();
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithCallbackStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:388;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithCallbackStringWhileServerWaitTest()
+      throws Fault {
+    InvocationCallback<String> callback = createStringCallback(true);
+    Future<String> future = null;
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      future = async.method(method, callback);
+      checkFutureString(future, method);
+      assertCallbackCall();
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithCallbackThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:388;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithCallbackThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<String> future = null;
+    InvocationCallback<String> callback = createStringCallback(false);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method, callback);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithCallbackThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:388;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithCallbackThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Future<String> future = null;
+    InvocationCallback<String> callback = createStringCallback(false);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, callback);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:388;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    InvocationCallback<Response> callback = createCallback(false);
+    for (String method : METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      future = async.method(method, callback);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:389;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithEntityWhileServerWaitTest() throws Fault {
+    Future<Response> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:389;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithEntityThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<Response> future = null;
+    for (String method : ENTITY_METHODS) {
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      future = async.method(method, entity);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:390;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithStringClassWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<String> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, String.class);
+      checkFutureString(future, method);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithResponseClassWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:390;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithResponseClassWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<Response> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, Response.class);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithClassWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:390;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithClassWithEntityThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Future<String> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, String.class);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithClassWithEntityThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:390;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithClassWithEntityThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Future<String> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, String.class);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithClassWithEntityThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:390;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithClassWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, Response.class);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:391;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithGenericTypeStringWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<String> future = null;
+    GenericType<String> generic = createGeneric(String.class);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, generic);
+      checkFutureString(future, method);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithGenericTypeResponseWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:391;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithGenericTypeResponseWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<Response> future = null;
+    GenericType<Response> generic = createGeneric(Response.class);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, generic);
+      checkFutureOkResponse(future);
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithGenericTypeWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:391;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithGenericTypeWithEntityThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, generic);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeWithEntityThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:391;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeWithEntityThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Future<String> future = null;
+    GenericType<String> generic = createGeneric(String.class);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, generic);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithGenericTypeWithEntityThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:391;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    GenericType<Response> generic = createGeneric(Response.class);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, generic);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithCallbackWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:392;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithCallbackWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<Response> future = null;
+    InvocationCallback<Response> callback = createCallback(true);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, callback);
+      checkFutureOkResponse(future);
+      assertCallbackCall();
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithCallbackStringWithEntityWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:392;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void methodWithCallbackStringWithEntityWhileServerWaitTest()
+      throws Fault {
+    Future<String> future = null;
+    InvocationCallback<String> callback = createStringCallback(true);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "andwait");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, callback);
+      checkFutureString(future, method);
+      assertCallbackCall();
+    }
+    //return future;
+  }
+
+  /*
+   * @testName: methodWithCallbackWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:392;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void methodWithCallbackWithEntityThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = null;
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, callback);
+      assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName: methodWithCallbackWithEntityThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:392;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithCallbackWithEntityThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Future<String> future = null;
+    InvocationCallback<String> callback = createStringCallback(false);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, callback);
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithCallbackWithEntityThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:392;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void methodWithCallbackWithEntityThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Future<Response> future = null;
+    InvocationCallback<Response> callback = createCallback(false);
+    for (String method : ENTITY_METHODS) {
+      AsyncInvoker async = startAsyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = Entity.entity(method, MediaType.WILDCARD_TYPE);
+      future = async.method(method, entity, callback);
+      checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------OPTIONS--------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: optionsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:393;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("options");
+    Future<Response> future = async.options();
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:393;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    Future<Response> future = async.options();
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: optionsThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:393;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void optionsThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("options");
+    Future<Response> future = async.options();
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: optionsWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:394;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithStringClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    Future<String> future = async.options(String.class);
+    checkFutureString(future, "options");
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:394;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    Future<Response> future = async.options(Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:394;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void optionsWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("options");
+    Future<String> future = async.options(String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: optionsWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:394;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    Future<String> future = async.options(String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: optionsWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:394;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    Future<Response> future = async.options(Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:395;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.options(generic);
+    checkFutureString(future, "options");
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:395;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.options(generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:395;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void optionsWithGenericTypeThrowsProcessingExceptionTest()
+      throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("options");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.options(generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:395;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.options(generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName:
+   * optionsWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:395;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.options(generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: optionsWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:396;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithCallbackWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    InvocationCallback<Response> callback = createCallback(true);
+    Future<Response> future = async.options(callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithStringCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:396;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void optionsWithStringCallbackWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsandwait");
+    InvocationCallback<String> callback = createStringCallback(true);
+    Future<String> future = async.options(callback);
+    checkFutureString(future, "options");
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: optionsWithCallbackThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:396;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void optionsWithCallbackThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("options");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.options(callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: optionsWithCallbackThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:396;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithCallbackThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.options(callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName:
+   * optionsWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:396;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void optionsWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("optionsnotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.options(callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------POST-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: postTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:397;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("post");
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity);
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: postWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:397;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: postThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:397;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void postThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("post");
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:398;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWithStringClassWhileServerWaitTest() throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Future<String> future = async.post(entity, String.class);
+    checkFutureString(future, "post");
+    //return future;
+  }
+
+  /*
+   * @testName: postWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:398;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Future<Response> future = async.post(entity, Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: postWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:398;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void postWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("post");
+    Future<String> future = async.post(entity, String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:398;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    Future<String> future = async.post(entity, String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:398;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity, Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: postWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:399;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Future<String> future = async.post(entity, generic);
+    checkFutureString(future, "post");
+    //return future;
+  }
+
+  /*
+   * @testName: postWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:399;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Future<Response> future = async.post(entity, generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: postWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:399;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void postWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    GenericType<String> generic = createGeneric(String.class);
+    AsyncInvoker async = startAsyncInvokerForMethod("post");
+    Future<String> future = async.post(entity, generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:399;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    GenericType<String> generic = createGeneric(String.class);
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    Future<String> future = async.post(entity, generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName:
+   * postWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:399;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity, generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: postWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:400;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void postWithCallbackWhileServerWaitTest() throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    InvocationCallback<Response> callback = createCallback(true);
+    AsyncInvoker async = startAsyncInvokerForMethod("postandwait");
+    Future<Response> future = async.post(entity, callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: postWithCallbackThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:400;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void postWithCallbackThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    InvocationCallback<String> callback = createStringCallback(false);
+    AsyncInvoker async = startAsyncInvokerForMethod("post");
+    Future<String> future = async.post(entity, callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithCallbackThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:400;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithCallbackThrowsWebApplicationExceptionTest() throws Fault {
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    InvocationCallback<String> callback = createStringCallback(false);
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    Future<String> future = async.post(entity, callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: postWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:400;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void postWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("postnotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Entity<String> entity = Entity.entity("post", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.post(entity, callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------PUT -----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: putTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:401;
+   * 
+   * @test_Strategy: Invoke HTTP PUT method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("put");
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.put(entity);
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: putWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:401;
+   * 
+   * @test_Strategy: Invoke HTTP PUT method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.put(entity);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: putThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:401;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void putThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("put");
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    Future<Response> future = async.put(entity);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:402;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithStringClassWhileServerWaitTest() throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<String> future = async.put(entity, String.class);
+    checkFutureString(future, "put");
+    //return future;
+  }
+
+  /*
+   * @testName: putWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:402;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<Response> future = async.put(entity, Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: putWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:402;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void putWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("put");
+    Future<String> future = async.put(entity, String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:402;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    Future<String> future = async.put(entity, String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:402;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    Future<Response> future = async.put(entity, Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: putWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:403;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<String> future = async.put(entity, generic);
+    checkFutureString(future, "put");
+    //return future;
+  }
+
+  /*
+   * @testName: putWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:403;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<Response> future = async.put(entity, generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: putWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:403;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void putWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("put");
+    Future<String> future = async.put(entity, generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:403;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    Future<String> future = async.put(entity, generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:403;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.put(entity, generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: putWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:404;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithCallbackWhileServerWaitTest() throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    InvocationCallback<Response> callback = createCallback(true);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<Response> future = async.put(entity, callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: putWithStringCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:404;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * asynchronously.
+   */
+  @Test
+  public void putWithStringCallbackWhileServerWaitTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    InvocationCallback<String> callback = createStringCallback(true);
+    AsyncInvoker async = startAsyncInvokerForMethod("putandwait");
+    Future<String> future = async.put(entity, callback);
+    checkFutureString(future, "put");
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: putWithCallbackThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:404;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void putWithCallbackThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    InvocationCallback<String> callback = createStringCallback(false);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("put");
+    Future<String> future = async.put(entity, callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithCallbackThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:404;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithCallbackThrowsWebApplicationExceptionTest() throws Fault {
+    InvocationCallback<String> callback = createStringCallback(false);
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    Future<String> future = async.put(entity, callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: putWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:404;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void putWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    Entity<String> entity = Entity.entity("put", MediaType.WILDCARD_TYPE);
+    AsyncInvoker async = startAsyncInvokerForMethod("putnotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.put(entity, callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------TRACE -----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: traceTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:405;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("trace");
+    Future<Response> future = async.trace();
+    checkFutureOkResponseNoTime(future);
+    //return future;
+  }
+
+  /*
+   * @testName: traceWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:405;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<Response> future = async.trace();
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: traceThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:405;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void traceThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("trace");
+    Future<Response> future = async.trace();
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithStringClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:406;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithStringClassWhileServerWaitTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<String> future = async.trace(String.class);
+    checkFutureString(future, "trace");
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithResponseClassWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:406;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithResponseClassWhileServerWaitTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<Response> future = async.trace(Response.class);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:406;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void traceWithClassThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    AsyncInvoker async = startAsyncInvokerForMethod("trace");
+    Future<String> future = async.trace(String.class);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:406;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void traceWithClassThrowsWebApplicationExceptionTest() throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    Future<String> future = async.trace(String.class);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithClassThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:406;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  //@Test
+  public void traceWithClassThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    Future<Response> future = async.trace(Response.class);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: traceWithGenericTypeStringWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:407;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithGenericTypeStringWhileServerWaitTest()
+      throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<String> future = async.trace(generic);
+    checkFutureString(future, "trace");
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithGenericTypeResponseWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:407;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithGenericTypeResponseWhileServerWaitTest()
+      throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<Response> future = async.trace(generic);
+    checkFutureOkResponse(future);
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:407;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void traceWithGenericTypeThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    GenericType<String> generic = createGeneric(String.class);
+    AsyncInvoker async = startAsyncInvokerForMethod("trace");
+    Future<String> future = async.trace(generic);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithGenericTypeThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:407;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void traceWithGenericTypeThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    GenericType<String> generic = createGeneric(String.class);
+    Future<String> future = async.trace(generic);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName:
+   * traceWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:407;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  //@Test
+  public void traceWithGenericTypeThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Future<Response> future = async.trace(generic);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: traceWithCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:408;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithCallbackWhileServerWaitTest() throws Fault {
+    InvocationCallback<Response> callback = createCallback(true);
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<Response> future = async.trace(callback);
+    checkFutureOkResponse(future);
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithStringCallbackWhileServerWaitTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:408;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * asynchronously.
+   */
+  //@Test
+  public void traceWithStringCallbackWhileServerWaitTest()
+      throws Fault {
+    InvocationCallback<String> callback = createStringCallback(true);
+    AsyncInvoker async = startAsyncInvokerForMethod("traceandwait");
+    Future<String> future = async.trace(callback);
+    checkFutureString(future, "trace");
+    assertCallbackCall();
+    //return future;
+  }
+
+  /*
+   * @testName: traceWithCallbackThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:408;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps an
+   * jakarta.ws.rs.ProcessingException thrown in case of an invocation processing
+   * failure.
+   */
+  @Test
+  public void traceWithCallbackThrowsProcessingExceptionTest() throws Fault {
+    _hostname = NONEXISTING_SITE;
+    InvocationCallback<String> callback = createStringCallback(false);
+    AsyncInvoker async = startAsyncInvokerForMethod("trace");
+    Future<String> future = async.trace(callback);
+    assertExceptionWithProcessingExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithCallbackThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:408;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  @Test
+  public void traceWithCallbackThrowsWebApplicationExceptionTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    InvocationCallback<String> callback = createStringCallback(false);
+    Future<String> future = async.trace(callback);
+    assertExceptionWithWebApplicationExceptionIsThrownAndLog(future);
+  }
+
+  /*
+   * @testName: traceWithCallbackThrowsNoWebApplicationExceptionForResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:408;
+   * 
+   * @test_Strategy: Note that calling the Future.get() method on the returned
+   * Future instance may throw an ExecutionException that wraps a
+   * WebApplicationException or one of its subclasses thrown in case the
+   * received response status code is not successful and the specified response
+   * type is not Response.
+   */
+  //@Test
+  public void traceWithCallbackThrowsNoWebApplicationExceptionForResponseTest()
+      throws Fault {
+    AsyncInvoker async = startAsyncInvokerForMethod("tracenotok");
+    InvocationCallback<Response> callback = createCallback(false);
+    Future<Response> future = async.trace(callback);
+    checkFutureStatusResponseNoTime(future, Status.NOT_ACCEPTABLE);
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  // utility methods
+
+  protected String getUrl(String method) {
+    StringBuilder url = new StringBuilder();
+    url.append("http://").append(_hostname).append(":").append(_port);
+    url.append("/").append(getContextRoot()).append("/").append(method);
+    return url.toString();
+  }
+
+  /**
+   * Create AsyncInvoker for given resource method and start time
+   */
+  protected AsyncInvoker startAsyncInvokerForMethod(String methodName) {
+    Client client = ClientBuilder.newClient();
+    client.register(new JdkLoggingFilter(false));
+    WebTarget target = client.target(getUrl(methodName));
+    AsyncInvoker async = target.request().async();
+    setStartTime();
+    return async;
+  }
+
+  protected void assertOkAndLog(Response response, Status status) throws Fault {
+    assertTrue(response.getStatus() == status.getStatusCode(),
+        "Returned unexpected status" +response.getStatus());
+    String msg = new StringBuilder().append("Returned status ")
+        .append(status.getStatusCode()).append(" (").append(status.name())
+        .append(")").toString();
+    TestUtil.logMsg(msg);
+  }
+
+  protected void checkFutureOkResponseNoTime(Future<Response> future)
+      throws Fault {
+    checkFutureStatusResponseNoTime(future, Status.OK);
+  }
+
+  protected void checkFutureStatusResponseNoTime(Future<Response> future,
+      Status status) throws Fault {
+    Response response = null;
+    try {
+      response = future.get();
+    } catch (Exception e) {
+      throw new Fault(e);
+    }
+    assertOkAndLog(response, status);
+  }
+
+  protected void checkFutureOkResponse(Future<Response> future) throws Fault {
+    checkMaxEndTime();
+    assertTrue(!future.isDone(), "Future cannot be done, yet!");
+    checkFutureOkResponseNoTime(future);
+  }
+
+  protected void checkFutureString(Future<String> future, String expectedValue)
+      throws Fault {
+    checkMaxEndTime();
+    assertTrue(!future.isDone(), "Future cannot be done, yet!");
+    String value = null;
+    try {
+      value = future.get();
+    } catch (Exception e) {
+      throw new Fault(e);
+    }
+    assertTrue(expectedValue.equalsIgnoreCase(value), "expected value"+
+        expectedValue+ "differes from acquired value"+ value);
+  }
+
+  protected void //
+      assertExceptionWithWebApplicationExceptionIsThrownAndLog(Future<?> future)
+          throws Fault {
+    try {
+      future.get();
+      throw new Fault("ExecutionException has not been thrown");
+    } catch (ExecutionException e) {
+      assertWebApplicationExceptionIsCauseAndLog(e);
+    } catch (InterruptedException e) {
+      throw new Fault("Unexpected exception thrown", e);
+    }
+  }
+
+  protected void assertExceptionWithProcessingExceptionIsThrownAndLog(
+      Future<?> future) throws Fault {
+    try {
+      future.get();
+      throw new Fault("ExecutionException has not been thrown");
+    } catch (ExecutionException e) {
+      assertProcessingExceptionIsCauseAndLog(e);
+    } catch (InterruptedException e) {
+      throw new Fault("Unexpected exception thrown", e);
+    }
+  }
+
+  protected void //
+      assertProcessingExceptionIsCauseAndLog(ExecutionException e)
+          throws Fault {
+    logMsg("ExecutionException has been thrown as expected", e);
+    assertTrue(hasWrapped(e, jakarta.ws.rs.ProcessingException.class),
+        "ExecutionException wrapped"+ e.getCause()+
+        "rather then ProcessingException");
+    logMsg("ExecutionException.getCause is ProcessingException as expected");
+  }
+
+  protected void //
+      assertWebApplicationExceptionIsCauseAndLog(ExecutionException e)
+          throws Fault {
+    logMsg("ExecutionException has been thrown as expected", e);
+    assertTrue(hasWrapped(e, WebApplicationException.class),
+        "ExecutionException wrapped"+ e.getCause()+
+        "rather then WebApplicationException");
+    logMsg(
+        "ExecutionException.getCause is WebApplicationException as expected");
+  }
+
+  static boolean //
+      hasWrapped(Throwable parent, Class<? extends Throwable> wrapped) {
+    while (parent.getCause() != null) {
+      if (wrapped.isInstance(parent.getCause()))
+        return true;
+      parent = parent.getCause();
+    }
+    return false;
+  }
+
+  protected void sleep(int millis) throws Fault {
+    try {
+      Thread.sleep(millis);
+    } catch (InterruptedException e) {
+      throw new Fault(e);
+    }
+  }
+
+  protected void setStartTime() {
+    millis = System.currentTimeMillis();
+    logMsg("Start time:", millis);
+  }
+
+  protected void checkMaxEndTime() throws Fault {
+    long endMillis = System.currentTimeMillis();
+    long diff = endMillis - millis;
+    logMsg("Client was returned control in", diff, "milliseconds from request");
+    assertTrue(diff <= Resource.SLEEP_TIME,
+        "AsyncInvoker was blocked waiting for a response");
+  }
+
+  protected void checkMinEndTime() throws Fault {
+    long endMillis = System.currentTimeMillis();
+    long diff = endMillis - millis;
+    logMsg("Callback#completed() called in", diff, "milliseconds from request");
+    assertTrue(diff >= Resource.SLEEP_TIME,
+        "AsyncInvoker.completed() was called unexpectedly soon, after"+ diff+
+        "milliseconds");
+  }
+
+  protected void assertCallbackCall() throws Fault {
+    while (callbackResult == 0) {
+      try {
+        Thread.sleep(100L);
+      } catch (InterruptedException e) {
+        throw new Fault(e);
+      }
+    }
+    switch (callbackResult) {
+    case 1:
+      logMsg("Callback completed() call ok");
+      break;
+    case 2:
+    case 3:
+      logMsg("Callback completed() call failed with error");
+      throw new Fault("Callback call failed with error", callbackException);
+    }
+    callbackResult = 0;
+  }
+
+  protected <T> GenericType<T> createGeneric(Class<T> clazz) {
+    return new GenericType<T>(clazz);
+  }
+
+  /**
+   * @param check
+   *          defines whether the test actually cares about methods
+   *          {@link InvocationCallback#completed(Object)} and
+   *          {@link InvocationCallback#failed(Throwable)} being called
+   * @return
+   */
+  protected InvocationCallback<Response> createCallback(boolean check) {
+    InvocationCallback<Response> callback = new Callback<Response>(check) {
+      @Override
+      public void completed(Response response) {
+        checkEndTime();
+      }
+    };
+    return callback;
+  }
+
+  protected InvocationCallback<String> createStringCallback(boolean check) {
+    InvocationCallback<String> callback = new Callback<String>(check) {
+      @Override
+      public void completed(String response) {
+        checkEndTime();
+      }
+    };
+    return callback;
+  }
+
+  abstract class Callback<RESPONSE> implements InvocationCallback<RESPONSE> {
+    protected boolean check;
+
+    public Callback(boolean check) {
+      this.check = check;
+    }
+
+    protected void checkEndTime() {
+      if (check)
+        try {
+          JAXRSClientIT.this.checkMinEndTime();
+          callbackResult = 1;
+        } catch (Fault e) {
+          callbackResult = 2;
+          callbackException = e;
+          throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    public void failed(Throwable throwable) {
+      if (check) {
+        callbackResult = 3;
+        callbackException = throwable;
+        throw new RuntimeException(throwable);
+      }
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java
new file mode 100644
index 0000000..e761d04
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/Resource.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.asyncinvoker;
+
+import jakarta.ws.rs.tck.common.impl.TRACE;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HEAD;
+import jakarta.ws.rs.OPTIONS;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+@Path("resource")
+public class Resource {
+
+  public static final long SLEEP_TIME = 2000L;
+
+  @GET
+  @Path("get")
+  public String get() {
+    return "get";
+  }
+
+  @GET
+  @Path("getandwait")
+  public String getAndWait() throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return "get";
+  }
+
+  @GET
+  @Path("getnotok")
+  public Response getReturnsStatusNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @HEAD
+  @Path("head")
+  public String head() {
+    return "head";
+  }
+
+  @HEAD
+  @Path("headandwait")
+  public String headAndWait() throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return "head";
+  }
+
+  @HEAD
+  @Path("headnotok")
+  public Response headReturnsStatusNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @PUT
+  @Path("put")
+  public String put(String value) {
+    return value;
+  }
+
+  @PUT
+  @Path("putandwait")
+  public String putAndWait(String value) throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return value;
+  }
+
+  @PUT
+  @Path("putnotok")
+  public Response putReturnsStatusNotOk(String value) {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @POST
+  @Path("post")
+  public String post(String value) {
+    return value;
+  }
+
+  @POST
+  @Path("postandwait")
+  public String postAndWait(String value) throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return value;
+  }
+
+  @POST
+  @Path("postnotok")
+  public Response postReturnsStatusNotOk(String string) {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @DELETE
+  @Path("delete")
+  public String delete() {
+    return "delete";
+  }
+
+  @DELETE
+  @Path("deleteandwait")
+  public String deleteAndWait() throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return "delete";
+  }
+
+  @DELETE
+  @Path("deletenotok")
+  public Response deleteReturnsStatusNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @OPTIONS
+  @Path("options")
+  public String options() {
+    return "options";
+  }
+
+  @OPTIONS
+  @Path("optionsandwait")
+  public String optionsAndWait() throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return "options";
+  }
+
+  @OPTIONS
+  @Path("optionsnotok")
+  public Response optionsReturnsStatusNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @TRACE
+  @Path("trace")
+  public String trace() {
+    return "trace";
+  }
+
+  @TRACE
+  @Path("tracenotok")
+  public Response traceReturnsStatusNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @TRACE
+  @Path("traceandwait")
+  public String traceAndWait() throws InterruptedException {
+    Thread.sleep(SLEEP_TIME);
+    return trace();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java
new file mode 100644
index 0000000..9dd436c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.asyncinvoker;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(Resource.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/JAXRSClientIT.java
new file mode 100644
index 0000000..c61353c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/JAXRSClientIT.java
@@ -0,0 +1,539 @@
+/*
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.request;
+
+import org.apache.commons.httpclient.Header;
+import java.util.Properties;
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import org.jboss.arquillian.junit5.ArquillianExtension;
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.StringAsset;
+import org.jboss.shrinkwrap.api.spec.WebArchive;
+import org.jboss.shrinkwrap.api.exporter.ZipExporter;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.junit.jupiter.api.TestInfo;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.AfterEach;
+
+import jakarta.ws.rs.core.Response.Status;
+
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = 1L;
+
+  private static final String IF_MODIFIED_SINCE = "If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT";
+
+  private static final String IF_UNMODIFIED_SINCE = "If-Unmodified-Since: Sat, 29 Oct 1994 19:43:31 GMT";
+
+  private static final String IF_NONE_MATCH = "If-None-Match: \"AAA\"";
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_request_web/RequestTest");
+  }
+
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template");
+    // Replace the servlet_adaptor in web.xml.template with the System variable set as servlet adaptor
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_request_web.war");
+    archive.addClasses(TSAppConfig.class, RequestTest.class);
+    archive.setWebXML(new StringAsset(webXml));
+    //archive.addAsWebInfResource(JAXRSClientIT.class.getPackage(), "web.xml.template", "web.xml"); //can use if the web.xml.template doesn't need to be modified.    
+    return archive;
+
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+
+  /*
+   * @testName: getMethodGetRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:118; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.getMethod works.
+   */
+  @Test
+  public void getMethodGetRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "GetMethodGetTest"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: getMethodPutRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:118;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.getMethod works.
+   */
+  @Test
+  public void getMethodPutRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("PUT", "GetMethodPutTest"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: getMethodPostRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:118;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.getMethod works.
+   */
+  @Test
+  public void getMethodPostRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("POST", "GetMethodPostTest"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: getMethodDeleteRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:118;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.getMethod works.
+   */
+  @Test
+  public void getMethodDeleteRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("DELETE", "GetMethodDeleteTest"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: getMethodHeadRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:118;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.getMethod works.
+   */
+  @Test
+  public void getMethodHeadRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("HEAD", "GetMethodHeadTest"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: selectVariantGetRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:119;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.selectVariantTest(List vs) works when vs is null.
+   */
+  @Test
+  public void selectVariantGetRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "SelectVariantTestGet"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: selectVariantPutRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:119;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.selectVariantTest(List vs) works when vs is null.
+   */
+  @Test
+  public void selectVariantPutRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("PUT", "SelectVariantTestPut"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: selectVariantPostRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:119;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.selectVariantTest(List vs) works when vs is null.
+   */
+  @Test
+  public void selectVariantPostRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("POST", "SelectVariantTestPost"));
+    setProperty(Property.CONTENT, "POST");
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: selectVariantDeleteRequestTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:119;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that
+   * Request.selectVariantTest(List vs) works when vs is null.
+   */
+  @Test
+  public void selectVariantDeleteRequestTest() throws Fault {
+    setProperty(REQUEST, buildRequest("DELETE", "SelectVariantTestDelete"));
+    setProperty(SEARCH_STRING, "PASSED");
+    invoke();
+  }
+
+  /*
+   * @testName: selectVariantResponseVaryTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:119; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check if the response contains VARY
+   */
+  @Test
+  public void selectVariantResponseVaryTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "SelectVariantTestResponse"));
+    setProperty(Property.REQUEST_HEADERS, "Accept: application/json");
+    setProperty(Property.REQUEST_HEADERS, "Accept-Encoding: *");
+    setProperty(Property.REQUEST_HEADERS, "Accept-Language: *");
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+
+    HttpResponse response = _testCase.getResponse();
+    Header[] headers = response.getResponseHeaders("Vary");
+    assertTrue(headers.length != 0, "Expected at least 1 Vary response header");
+
+    boolean accept = false, lang = false, encoding = false;
+    for (Header header : headers)
+      for (String vary : header.getValue().split(",")) {
+        lang |= vary.contains("Accept-Language");
+        encoding |= vary.contains("Accept-Encoding");
+        accept |= (vary.contains("Accept") && !vary.contains("Accept-"));
+      }
+    assertTrue(lang, "Vary should contain Accept-Language");
+    assertTrue(encoding, "Vary should contain Accept-Encoding");
+    assertTrue(accept, "Vary should contain Accept");
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagNullAndSimpleGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Verify null and Simple Tag for GET
+   * 
+   */
+  @Test
+  public void evaluatePreconditionsTagNullAndSimpleGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsSimpleGet"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsEntityTagIfMatchAAAGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Match: AAA Tag for GET
+   */
+  @Test
+  public void evaluatePreconditionsEntityTagIfMatchAAAGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+    setProperty(REQUEST_HEADERS, "If-Match: \"AAA\"");
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsEntityTagIfMatchBBBGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Match: BBB Tag for GET
+   */
+  @Test
+  public void evaluatePreconditionsEntityTagIfMatchBBBGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+    setProperty(REQUEST_HEADERS, "If-Match: \"BBB\"");
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsEntityTagIfMatchAAAPutTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Match: AAA Tag for PUT
+   */
+  @Test
+  public void evaluatePreconditionsEntityTagIfMatchAAAPutTest() throws Fault {
+    setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+    setProperty(REQUEST_HEADERS, "If-Match: \"AAA\"");
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsEntityTagIfMatchBBBPutTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Match: BBB Tag for PUT
+   */
+  @Test
+  public void evaluatePreconditionsEntityTagIfMatchBBBPutTest() throws Fault {
+    setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+    setProperty(REQUEST_HEADERS, "If-Match: \"BBB\"");
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfNonMatchAAAGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+   * GET
+   */
+  @Test
+  public void evaluatePreconditionsTagIfNonMatchAAAGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAAAGet"));
+    setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfNonMatchAAAPutTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+   * PUT
+   */
+  @Test
+  public void evaluatePreconditionsTagIfNonMatchAAAPutTest() throws Fault {
+    setProperty(REQUEST, buildRequest("PUT", "preconditionsAAAPut"));
+    setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfNonMatchGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:298;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-None-Match No Tag for
+   * GET
+   */
+  @Test
+  public void evaluatePreconditionsTagIfNonMatchGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsGet"));
+    setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfNonMatchAAAHeadTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:115;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-None-Match: AAA Tag for
+   * HEAD
+   */
+  @Test
+  public void evaluatePreconditionsTagIfNonMatchAAAHeadTest() throws Fault {
+    setProperty(REQUEST, buildRequest("HEAD", "preconditionsAAAHead"));
+    setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsIfNonMatchHeadTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:298;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-None-Match No Tag for
+   * HEAD
+   */
+  @Test
+  public void evaluatePreconditionsIfNonMatchHeadTest() throws Fault {
+    setProperty(REQUEST, buildRequest("HEAD", "preconditionsHead"));
+    setProperty(REQUEST_HEADERS, IF_NONE_MATCH);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsIfModSinceAgesAgoGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:116;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since, but was
+   * not modified for GET
+   */
+  @Test
+  public void evaluatePreconditionsIfModSinceAgesAgoGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAgesAgoGet"));
+    setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsIfUnmodSinceAgesAgoGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:116;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Unmodified-Since, but
+   * was not modified for GET
+   */
+  @Test
+  public void evaluatePreconditionsIfUnmodSinceAgesAgoGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAgesAgoGet"));
+    setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsIfModSinceNowGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:116;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+   * was modified
+   */
+  @Test
+  public void evaluatePreconditionsIfModSinceNowGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsNowGet"));
+    setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsIfUnmodSinceNowGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:116;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+   * was modified
+   */
+  @Test
+  public void evaluatePreconditionsIfUnmodSinceNowGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsNowGet"));
+    setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfModAAASinceGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:117;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since, but was
+   * not modified for GET
+   */
+  @Test
+  public void evaluatePreconditionsTagIfModAAASinceGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAAAAgesAgoGet"));
+    setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfUnmodSinceAAAGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:117;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Unmodified-Since, but
+   * was not modified for GET
+   */
+  @Test
+  public void evaluatePreconditionsTagIfUnmodSinceAAAGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsAAAAgesAgoGet"));
+    setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfModSinceNowAAAGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:117;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+   * was modified
+   */
+  @Test
+  public void evaluatePreconditionsTagIfModSinceNowAAAGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsNowAAAGet"));
+    setProperty(REQUEST_HEADERS, IF_MODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: evaluatePreconditionsTagIfUnmodSinceNowAAAGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:117;
+   * 
+   * @test_Strategy: Verify evaluatePreconditions for If-Modified-Since for GET,
+   * was modified
+   */
+  @Test
+  public void evaluatePreconditionsTagIfUnmodSinceNowAAAGetTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "preconditionsNowAAAGet"));
+    setProperty(REQUEST_HEADERS, IF_UNMODIFIED_SINCE);
+    setProperty(STATUS_CODE, getStatusCode(Status.PRECONDITION_FAILED));
+    invoke();
+  }
+
+}
\ No newline at end of file
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java
new file mode 100644
index 0000000..f503c40
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/RequestTest.java
@@ -0,0 +1,284 @@
+/*
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.request;
+
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HEAD;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Variant;
+
+@Path(value = "/RequestTest")
+public class RequestTest {
+
+  // ------------------ GET METHOD ----------------------------
+
+  private static Response assertResponse(String expectedMethod,
+      String actualMethod) {
+    if (actualMethod.equalsIgnoreCase(expectedMethod)) {
+      return Response.ok("Test PASSED").build();
+    } else {
+      return Response.ok("Test FAILED with " + actualMethod).build();
+    }
+  }
+
+  @GET
+  @Path("/GetMethodGetTest")
+  public Response getTest(@Context Request req) {
+    String method = req.getMethod();
+    return assertResponse("GET", method);
+  }
+
+  @PUT
+  @Path("/GetMethodPutTest")
+  public Response putTest(@Context Request req) {
+    String method = req.getMethod();
+    return assertResponse("PUT", method);
+  }
+
+  @POST
+  @Path("/GetMethodPostTest")
+  public Response postTest(@Context Request req) {
+    String method = req.getMethod();
+    return assertResponse("POST", method);
+  }
+
+  @DELETE
+  @Path("/GetMethodDeleteTest")
+  public Response deleteTest(@Context Request req) {
+    String method = req.getMethod();
+    return assertResponse("DELETE", method);
+  }
+
+  @HEAD
+  @Path("/GetMethodHeadTest")
+  public Response headTest(@Context Request req) {
+    String method = req.getMethod();
+
+    if (method.equalsIgnoreCase("HEAD")) {
+      return Response.ok().build();
+    } else {
+      return Response.status(400).build();
+    }
+  }
+
+  // ------------------ SELECT VARIANT ----------------------------
+
+  @GET
+  @Path("/SelectVariantTestGet")
+  public Response selectVariantTestGet(@Context Request req) {
+    List<Variant> vs = null;
+
+    try {
+      req.selectVariant(vs);
+      return Response.ok("Test FAILED - no exception thrown").build();
+    } catch (IllegalArgumentException ile) {
+      return Response.ok("Test PASSED - expected exception thrown").build();
+    } catch (Throwable th) {
+      return Response
+          .ok("Test FAILED - wrong type exception thrown" + th.getMessage())
+          .build();
+    }
+  }
+
+  @PUT
+  @Path("/SelectVariantTestPut")
+  public Response selectVariantTestPut(@Context Request req) {
+    return selectVariantTestGet(req);
+  }
+
+  @POST
+  @Path("/SelectVariantTestPost")
+  public Response selectVariantTestPost(@Context Request req) {
+    return selectVariantTestGet(req);
+  }
+
+  @DELETE
+  @Path("/SelectVariantTestDelete")
+  public Response selectVariantTestDelete(@Context Request req) {
+    return selectVariantTestGet(req);
+  }
+
+  @GET
+  @Path("/SelectVariantTestResponse")
+  public Response selectVariantTestResponse(@Context Request req) {
+    List<Variant> list = Variant.encodings("CP1250", "UTF-8")
+        .languages(Locale.ENGLISH).mediaTypes(MediaType.APPLICATION_JSON_TYPE)
+        .add().build();
+    Variant selectedVariant = req.selectVariant(list);
+    if (null == selectedVariant)
+      return Response.notAcceptable(list).build();
+    return Response.ok("entity").build();
+  }
+
+  // ------------------ EVALUATE PRECONDITIONS ----------------------------
+  private static boolean evaluatePreconditionsEntityTagNull(Request req) {
+    try {
+      req.evaluatePreconditions((EntityTag) null);
+      return false;
+    } catch (IllegalArgumentException iae) {
+      return true;
+    }
+  }
+
+  private static boolean evaluatePreconditionsNowEntityTagNull(Request req) {
+    try {
+      Date now = Calendar.getInstance().getTime();
+      req.evaluatePreconditions(now, (EntityTag) null);
+      return false;
+    } catch (IllegalArgumentException iae) {
+      return true;
+    }
+  }
+
+  private static boolean evaluatePreconditionsDateEntityTag(Request req,
+      Date date, String tag) {
+    ResponseBuilder rb = req.evaluatePreconditions(date, createTag(tag));
+    return rb == null;
+  }
+
+  private static boolean evaluatePreconditionsDate(Request req, Date date) {
+    ResponseBuilder rb = req.evaluatePreconditions(date);
+    return rb == null;
+  }
+
+  private static boolean evaluatePreconditions(Request req) {
+    ResponseBuilder rb = req.evaluatePreconditions();
+    return rb == null;
+  }
+
+  private static EntityTag createTag(String tag) {
+    String xtag = new StringBuilder().append("\"").append(tag).append("\"")
+        .toString();
+    return EntityTag.valueOf(xtag);
+  }
+
+  private static boolean evaluatePreconditionsEntityTag(Request req,
+      String tag) {
+    ResponseBuilder rb = req.evaluatePreconditions(createTag(tag));
+    return rb == null;
+  }
+
+  private static Response createResponse(boolean ok) {
+    Status status = ok ? Status.OK : Status.PRECONDITION_FAILED;
+    return Response.status(status).build();
+  }
+
+  private static Date getYear1900() {
+    Calendar calendar = Calendar.getInstance();
+    calendar.set(Calendar.YEAR, 1900);
+    return calendar.getTime();
+  }
+
+  @GET
+  @Path("/preconditionsSimpleGet")
+  public Response evaluatePreconditionsEntityTagGetSimpleTest(
+      @Context Request req) {
+    boolean ok = evaluatePreconditionsEntityTag(req, "AAA");
+    if (!ok)
+      return Response.status(Status.GONE).build();
+    ok &= evaluatePreconditionsNowEntityTagNull(req);
+    if (!ok)
+      return Response.status(Status.NOT_ACCEPTABLE).build();
+    ok &= evaluatePreconditionsEntityTagNull(req);
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsAAAGet")
+  public Response evaluatePreconditionsEntityTagAAAGetTest(
+      @Context Request req) {
+    boolean ok = evaluatePreconditionsEntityTag(req, "AAA");
+    return createResponse(ok);
+  }
+
+  @PUT
+  @Path("/preconditionsAAAPut")
+  public Response evaluatePreconditionsEntityTagAAAPutTest(
+      @Context Request req) {
+    return evaluatePreconditionsEntityTagAAAGetTest(req);
+  }
+
+  @HEAD
+  @Path("/preconditionsAAAHead")
+  public Response evaluatePreconditionsEntityTagAAAHeadTest(
+      @Context Request req) {
+    return evaluatePreconditionsEntityTagAAAGetTest(req);
+  }
+
+  @GET
+  @Path("/preconditionsAAAAgesAgoGet")
+  public Response evaluatePreconditionsAgesAgoEntityTagAAAGetTest(
+      @Context Request req) {
+    Date date = getYear1900();
+    boolean ok = evaluatePreconditionsDateEntityTag(req, date, "AAA");
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsNowAAAGet")
+  public Response evaluatePreconditionsDateEntityTagAAAGetTest(
+      @Context Request req) {
+    Date date = Calendar.getInstance().getTime();
+    boolean ok = evaluatePreconditionsDateEntityTag(req, date, "AAA");
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsNowGet")
+  public Response evaluatePreconditionsDateGetTest(@Context Request req) {
+    Date date = Calendar.getInstance().getTime();
+    boolean ok = evaluatePreconditionsDate(req, date);
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsAgesAgoGet")
+  public Response evaluatePreconditionsAgesAgoGetTest(@Context Request req) {
+    Date date = getYear1900();
+    boolean ok = evaluatePreconditionsDate(req, date);
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsGet")
+  public Response evaluatePreconditionsGetTest(@Context Request req) {
+    boolean ok = evaluatePreconditions(req);
+    return createResponse(ok);
+  }
+
+  @GET
+  @Path("/preconditionsHead")
+  public Response evaluatePreconditionsHeadTest(@Context Request req) {
+    boolean ok = evaluatePreconditions(req);
+    return createResponse(ok);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java
new file mode 100644
index 0000000..a483d2a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/request/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.request;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(RequestTest.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java
new file mode 100644
index 0000000..6d24903
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyManagerInterface.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.deliverable;
+
+import java.util.Properties;
+
+/**
+ * This class serves as a well known place for harness, util, and porting
+ * classes to retrieve property values.
+ *
+ * @author Kyle Grucci
+ */
+public interface PropertyManagerInterface {
+
+  /**
+   * This method swaps all of the following interop values in
+   * TSPropertyManager...
+   *
+   */
+  public void swapInteropPropertyValues(String sDirection);
+
+  /**
+   * gets a new properties containing all entries in the property manager. Any
+   * operation on the returned properties will have no effect on property
+   * manager
+   */
+  public Properties getJteProperties();
+
+  /**
+   * gets property value with default
+   *
+   * @param sKey - Property to retrieve
+   * @param default - default value to use
+   * @return String - property value
+   */
+  public String getProperty(String sKey, String def);
+
+  /**
+   * This method is called to get a property value
+   *
+   * @param sKey
+   *          - Property to retrieve
+   * @return String - property value
+   */
+  public String getProperty(String sKey) throws PropertyNotSetException;
+
+  /**
+   * This method is called to set a property on the property manager
+   *
+   * @param skey - key to be used
+   * @param sVal - value to use
+   */
+  public void setProperty(String sKey, String sVal);
+
+  /**
+   * This method is called by the test harness to retrieve all properties needed
+   * by a particular test.
+   *
+   * @param sPropKeys - Properties to retrieve
+   * @return Properties - property/value pairs
+   */
+  public Properties getTestSpecificProperties(String[] sPropKeys)
+      throws PropertyNotSetException;
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java
new file mode 100644
index 0000000..2debdde
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/deliverable/PropertyNotSetException.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+ package jakarta.ws.rs.tck.lib.deliverable;
+
+public class PropertyNotSetException extends java.lang.Exception {
+  public PropertyNotSetException(String s) {
+    super(s);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java
new file mode 100644
index 0000000..e1956ca
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/common/SunRIURL.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.implementation.sun.common;
+
+import java.net.*;
+import jakarta.ws.rs.tck.lib.util.*;
+import jakarta.ws.rs.tck.lib.porting.*;
+
+/**
+ * This is a J2EE Reference specific implementation of the TSURLInterface which
+ * is to be used for J2EE-TS testing. TS tests use this interface to obtain the
+ * URL String to use to access a given web component. If a given J2EE Server
+ * implmentation requires that URLs be created in a different manner, then this
+ * implementation can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public class SunRIURL implements TSURLInterface {
+  private URL url = null;
+
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL object.
+   */
+  public URL getURL(String protocol, String host, int port, String file)
+      throws MalformedURLException {
+    try {
+      url = new URL(protocol, host, port, file);
+    } catch (MalformedURLException e) {
+      TestUtil.logErr("Failed during URL creation", e);
+      throw e;
+    }
+    return url;
+  }
+
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL as a String.
+   */
+  public String getURLString(String protocol, String host, int port,
+      String file) {
+    if (file.startsWith("/"))
+      return protocol + "://" + host + ":" + port + file;
+    else
+      return protocol + "://" + host + ":" + port + "/" + file;
+  }
+
+  /**
+   * This method is called by TS tests to get the request string to use to
+   * access a given web component.
+   *
+   * @param request
+   *          - the request file.
+   * @return a valid String object.
+   */
+  public String getRequest(String request) {
+    return request;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java
new file mode 100644
index 0000000..2fd13d5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/implementation/sun/jersey/TSWebConfiguration.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2008, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+
+package jakarta.ws.rs.tck.lib.implementation.sun.jersey;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import jakarta.ws.rs.tck.lib.deliverable.PropertyManagerInterface;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Properties;
+
+/**
+ * This is a utility class that borrowed from Kyle Grucci's original work in
+ * TSRuntimeConfiguration.java. It is called to replace any configurable
+ * properties in the web xml files with the implementation specific values
+ * specified in ts.jte. A copy is made of each web xml file (with the
+ * substituted values) in the same location with file extension .new.
+ *
+ * @author Dianne Jiao
+ */
+public class TSWebConfiguration {
+
+  // whether running with s1as or j2sdkee RI
+  private static Boolean runningS1AS;
+
+  public final static String WEB_XML = "web.xml.template";
+
+  private File tempFile;
+
+  private PrintWriter log;
+
+  private static Hashtable htReplacementProps = new Hashtable();
+
+  private Hashtable htReplacerTable = new Hashtable();
+
+  private static String sTempDir = "";
+
+  private StringReplacer replacer = new StringReplacer();
+
+  private static File jteFile = new File(System.getProperty("TS_HOME")
+      + File.separator + "bin" + File.separator + "ts.jte");
+
+  private static String servlet_adaptor = "servlet_adaptor";
+
+  private static String implementation_name = "jaxrs_impl_name";
+
+  private PropertyManagerInterface propMgr;
+
+  static Properties props;
+
+  static List<String> props_name = Arrays.asList("servlet_adaptor");
+
+  public TSWebConfiguration() {
+    System.out.println("Dummy TSWebConfiguration Conctructor");
+  }
+
+  public static void main(String[] args) {
+
+    TSWebConfiguration webconfig = new TSWebConfiguration();
+
+    implementation_name = webconfig.findProps(implementation_name);
+    System.out.println("++++++++++++=" + implementation_name);
+
+    servlet_adaptor = webconfig.findProps(servlet_adaptor);
+    servlet_adaptor = servlet_adaptor.replace(".class", "").replace("/", ".");
+    System.out
+        .println("Replacement value for servlet_adaptor =" + servlet_adaptor);
+
+    PrintWriter logOut = new PrintWriter(System.out, true);
+
+    File fileList = new File(System.getProperty("TS_HOME") + File.separator
+        + "bin" + File.separator + "jaxrs_filelist");
+
+    try {
+      BufferedReader input = new BufferedReader(new FileReader(fileList));
+
+      try {
+        String line = null; // not declared within while loop
+        while ((line = input.readLine()) != null) {
+          System.out.println("Processing file " + line);
+          File file = new File(
+              System.getProperty("TS_HOME") + File.separator + line);
+          try {
+            htReplacementProps.put("servlet_adaptor", servlet_adaptor);
+            webconfig.sweepwebFile(file);
+            System.out.println("Done with file " + file.toString());
+          } catch (Exception e) {
+            e.printStackTrace();
+            System.out
+                .println("Failed to modify xml files with correct settings.  "
+                    + "Please check the values of");
+          }
+        }
+      } finally {
+        input.close();
+      }
+    } catch (IOException ex) {
+      ex.printStackTrace();
+    }
+    System.exit(0);
+  }
+
+  String findProps(String prop) {
+    System.out.println("Processing jte file");
+    String replace = null;
+
+    try {
+      BufferedReader input = new BufferedReader(new FileReader(jteFile));
+
+      try {
+        String line = null;
+        while ((line = input.readLine()) != null) {
+          if (line.startsWith(prop)) {
+            replace = line.split("=")[1];
+            return replace;
+          }
+        }
+      } finally {
+        input.close();
+      }
+    } catch (IOException ex) {
+      ex.printStackTrace();
+    }
+    return null;
+  }
+
+  /// I am here now
+  public String sweepwebFile(File file)
+      throws FileNotFoundException, IOException {
+    if (htReplacerTable != null && !(htReplacerTable.isEmpty())) {
+      htReplacerTable = replaceOnWebInfoStrings(htReplacerTable);
+    }
+    String dir = file.getParent();
+    File xml = new File(dir + File.separator + file.getName());
+
+    return replacer.replace(file, htReplacementProps, htReplacerTable, dir);
+  }
+
+  final class StringReplacer {
+
+    public String sFindString; // string we are searching for
+
+    public String sReplaceString; // replace sFindString with this
+
+    public String sDirString;
+
+    public String sFileNameStringToReplace;
+
+    public String sNewFileNameString;
+
+    public int iHowMany = -1;
+
+    public String[] sFileList;
+
+    public boolean bNewFile = false;
+
+    private Hashtable htFindAndReplace = null;
+
+    private Hashtable htCustomTable = null;
+
+    private Vector vInfoObjects = new Vector();
+
+    private Vector vMatchingInfoObjects = new Vector();
+
+    private Vector vNonMatchingInfoObjects = new Vector();
+
+    private boolean bSomethingWasReplaced = false;
+
+    public String replace(File file, Hashtable htStrings,
+        Hashtable htReplacerTable, String sTempDir) {
+      String[] sFileList = null;
+      htFindAndReplace = htStrings;
+      htCustomTable = htReplacerTable;
+      String sTemp = "";
+      ReplacementInfo ri = null;
+      String sNewFileName = "";
+      StringBuffer sFoundBuffer = new StringBuffer();
+      char c;
+      bSomethingWasReplaced = false;
+      BufferedReader fReader = null;
+      BufferedWriter fNewWriter = null;
+      try {
+        vInfoObjects = new Vector();
+        String sKey = "";
+        // create ReplacementInfo objects
+        for (Enumeration e = htFindAndReplace.keys(); e.hasMoreElements();) {
+          sKey = (String) e.nextElement();
+          vInfoObjects.addElement(
+              new ReplacementInfo(sKey, (String) htFindAndReplace.get(sKey)));
+        }
+        // add in the table the custom table of replacement strings
+        // if any
+        if (htCustomTable != null) {
+          for (Enumeration e = htCustomTable.keys(); e.hasMoreElements();) {
+            sKey = (String) e.nextElement();
+            vInfoObjects.addElement(
+                new ReplacementInfo(sKey, (String) htCustomTable.get(sKey)));
+
+          }
+        }
+        // reader of the file that we're searching
+        fReader = new BufferedReader(new FileReader(file));
+        System.out.println("File to read: " + file.getAbsolutePath());
+        StringWriter sWriter = new StringWriter();
+        // stores new file contents
+
+        // The following code is here to account for the fact that we
+        // have some properties to replace which are substrings of other
+        // properties. We need to be sure that we will be able to
+        // replace either. Thus, we check the char after certain props
+        // to see if they continue to match another property. If so,
+        // then we will replace with the longer property value
+        boolean bCheckForDot = false;
+        String sHold = "";
+        int iCharRead; // holds each char that we read
+        vMatchingInfoObjects.addAll(vInfoObjects);
+        while ((iCharRead = fReader.read()) != -1) {
+          c = (char) iCharRead;
+
+          if (bCheckForDot) {
+            if (c != '.') {
+              // hold the dot and let the old processing happen
+              sHold = new String((new Character(c)).toString());
+              System.out.println("sHold = " + sHold);
+            } else {
+              sFoundBuffer.append(c);
+              bCheckForDot = false;
+              continue;
+              // since there is no need to just check .
+            }
+          } else {
+            if (sHold != null) {
+              // just write the char that we were holding. This
+              // assumes that this char is not the beginning of a
+              // string we want to replace
+              sWriter.write(sHold);
+              sHold = null;
+            }
+
+            sFoundBuffer.append(c);
+          }
+
+          sTemp = new String(sFoundBuffer);
+
+          // get all ris that still match
+          for (Enumeration e = vMatchingInfoObjects.elements(); e
+              .hasMoreElements();) {
+
+            ri = (ReplacementInfo) e.nextElement();
+            if (ri.sFind.startsWith(sTemp)) {
+              if (ri.sFind.equals(sTemp)) {
+
+                // what if we have a substring of another string that
+                // we are searching for?
+
+                System.out.println(
+                    "REPLACER:MATCH found:  " + ri.sFind + " matches " + sTemp);
+                ri.foundOccurance();
+                bSomethingWasReplaced = true;
+                sWriter.write(ri.sReplace);
+                // reset sFoundBuffer
+                sFoundBuffer = new StringBuffer();
+                // reset matchers to all again
+                vMatchingInfoObjects.removeAllElements();
+                vMatchingInfoObjects.addAll(vInfoObjects);
+                break;
+              }
+            } else {
+              vNonMatchingInfoObjects.addElement(ri);
+              // the char that we just read causes our string not
+              // to match the string we're looking for. Write the
+              // old string to the new file and reset sFoundBuffer.
+              // this will never happen!!!
+            }
+          }
+          // remove all non-matching ri's
+          vMatchingInfoObjects.removeAll(vNonMatchingInfoObjects);
+          vNonMatchingInfoObjects.removeAllElements();
+          // reset everything if there are none left matching
+          if (vMatchingInfoObjects.isEmpty()) {
+            sWriter.write(sTemp);
+            sFoundBuffer = new StringBuffer();
+            vMatchingInfoObjects.removeAllElements();
+            vMatchingInfoObjects.addAll(vInfoObjects);
+          }
+        }
+        fReader.close();
+        if (bSomethingWasReplaced) {
+          sNewFileName = sTempDir + File.separator + "web.xml."
+              + implementation_name;
+          System.out.println("New filename:" + sNewFileName);
+          fNewWriter = new BufferedWriter(
+              new FileWriter(new File(sNewFileName)));
+          fNewWriter.write(sWriter.toString());
+          fNewWriter.flush();
+        } else {
+          sNewFileName = null;
+        }
+      } catch (Exception e) {
+        e.printStackTrace();
+      } finally {
+        if (fNewWriter != null) {
+          try {
+            fNewWriter.close();
+          } catch (IOException exp) {
+          }
+        }
+      }
+      return sNewFileName;
+    }
+
+    class ReplacementInfo {
+
+      private int iFoundOccurances = 0;
+
+      private String sFind = null;
+
+      private String sReplace = null;
+
+      ReplacementInfo(String sFindString, String sReplaceString) {
+        sFind = sFindString;
+        sReplace = sReplaceString;
+        iFoundOccurances = 0;
+      }
+
+      public void foundOccurance() {
+        iFoundOccurances++;
+        if (TestUtil.harnessDebug) {
+          System.out.println("we found an occurance #" + iFoundOccurances
+              + " of '" + sFind + "'");
+        }
+      }
+    }
+  }
+
+  /**
+   * Parse the HashTable which contains strings retrieved via calls into the
+   * porting classes for deployment. We must substitute on these strings prior
+   * to substituting them into the web.xml.
+   */
+  private Hashtable replaceOnWebInfoStrings(Hashtable extras) {
+
+    boolean changeIt = false;
+
+    String searchFor[] = { "servlet_adaptor" };
+
+    for (Enumeration e = extras.keys(); e.hasMoreElements();) {
+      String sKey = (String) e.nextElement();
+      String val = (String) extras.get(sKey);
+      String oldJndi = val;
+      changeIt = false;
+      String buff = null;
+      int startPos = 0;
+      for (int i = 0; i < searchFor.length; i++) {
+        System.out.println("\n###Searching for=" + searchFor[i]);
+        if ((startPos = val.lastIndexOf(searchFor[i])) != -1) {
+          changeIt = true;
+          String startBuff = val.substring(0, startPos);
+          buff = (String) htReplacementProps.get(searchFor[i]);
+          val = startBuff + buff
+              + val.substring(startPos + searchFor[i].length());
+        }
+      }
+      if (changeIt) {
+        extras.put((String) sKey, val);
+        System.out.println(
+            "\n###\nold webInfo Val=" + oldJndi + "\nNew webInfo Val = " + val);
+      }
+    }
+    return extras;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java
new file mode 100644
index 0000000..3c12b5e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURL.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.porting;
+
+import java.net.*;
+import java.io.Serializable;
+import jakarta.ws.rs.tck.lib.util.*;
+
+/**
+ * This is a Java EE Reference specific implementation of the TSURLInterface
+ * which is to be used for Java EE TCK testing. TS tests use this interface to
+ * obtain the URL String to use to access a given web component. If a given Java
+ * EE Server implmentation requires that URLs be created in a different manner,
+ * then this implementation can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public class TSURL implements TSURLInterface, Serializable {
+  private TSURLInterface ctsURL = null;
+
+  private String sClass = "porting.ts.url.class.1";
+
+  public TSURL() {
+    // we'll initialize the impl when the individual method is called
+    // this constructor assumes sClass = "porting.ts.url.class.1".
+  }
+
+  public TSURL(String sClassName) {
+    sClass = sClassName;
+  }
+
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL object.
+   */
+  public URL getURL(String protocol, String host, int port, String file)
+      throws MalformedURLException {
+    if (ctsURL == null) {
+      try {
+        // create and initialize a new instance of TSURLInterface
+        Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+        ctsURL = (TSURLInterface) c.newInstance();
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+
+    return ctsURL.getURL(protocol, host, port, file);
+  }
+
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL as a String.
+   */
+  public String getURLString(String protocol, String host, int port,
+      String file) {
+    if (ctsURL == null) {
+      try {
+        // create and initialize a new instance of TSURLInterface
+        Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+        ctsURL = (TSURLInterface) c.newInstance();
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+    return ctsURL.getURLString(protocol, host, port, file);
+  }
+
+  /**
+   * This method is called by TS tests to get the request string to use to
+   * access a given web component.
+   *
+   * @param request
+   *          - the request file.
+   * @return a valid String object.
+   */
+  public String getRequest(String request) {
+    if (ctsURL == null) {
+      try {
+        // create and initialize a new instance of TSURLInterface
+        Class c = Class.forName(System.getProperty(sClass, "jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL"));
+        ctsURL = (TSURLInterface) c.newInstance();
+      } catch (Exception e) {
+        e.printStackTrace();
+      }
+    }
+    return ctsURL.getRequest(request);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java
new file mode 100644
index 0000000..ee00989
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/porting/TSURLInterface.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.porting;
+
+import java.net.*;
+
+/**
+ * An implementation of the TSURLInterface is to be used for Java EE TCK
+ * testing. TS tests use this interface to obtain the URL String to use to
+ * access a given web component. If a given Java EE Server implmentation
+ * requires that URLs be created in a different manner, then this implementation
+ * can be replaced.
+ *
+ * @author Kyle Grucci
+ */
+public interface TSURLInterface {
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL object.
+   */
+  public URL getURL(String protocol, String host, int port, String file)
+      throws MalformedURLException;
+
+  /**
+   * This method is called by TS tests to get the URL to use to access a given
+   * web component.
+   *
+   * @param protocol
+   *          - the name of the protocol.
+   * @param host
+   *          - the name of the host.
+   * @param port
+   *          - the port number.
+   * @param file
+   *          - the host file.
+   * @return a valid URL as a String.
+   */
+  public String getURLString(String protocol, String host, int port,
+      String file);
+
+  /**
+   * This method is called by TS tests to get the request to use to access a
+   * given web component.
+   *
+   * @param request
+   *          - the request file.
+   * @return a valid String object.
+   */
+  public String getRequest(String request);
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java
new file mode 100644
index 0000000..c66eff9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Decoder.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1995, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.OutputStream;
+import java.io.PushbackInputStream;
+import java.io.PrintStream;
+
+/**
+ * This class implements a BASE64 Character decoder as specified in RFC1521.
+ *
+ * This RFC is part of the MIME specification which is published by the Internet
+ * Engineering Task Force (IETF). Unlike some other encoding schemes there is
+ * nothing in this encoding that tells the decoder where a buffer starts or
+ * stops, so to use it you will need to isolate your encoded data into a single
+ * chunk and then feed them this decoder. The simplest way to do that is to read
+ * all of the encoded data into a string and then use:
+ * 
+ * <pre>
+ * byte mydata[];
+ * BASE64Decoder base64 = new BASE64Decoder();
+ *
+ * mydata = base64.decodeBuffer(bufferString);
+ * </pre>
+ * 
+ * This will decode the String in <i>bufferString</i> and give you an array of
+ * bytes in the array <i>myData</i>.
+ *
+ * On errors, this class throws a CEFormatException with the following detail
+ * strings:
+ * 
+ * <pre>
+ * "BASE64Decoder: Not enough bytes for an atom."
+ * </pre>
+ *
+ * @author Chuck McManis
+ * @see CharacterEncoder
+ * @see BASE64Decoder
+ */
+
+public class BASE64Decoder extends CharacterDecoder {
+
+  /** This class has 4 bytes per atom */
+  protected int bytesPerAtom() {
+    return (4);
+  }
+
+  /** Any multiple of 4 will do, 72 might be common */
+  protected int bytesPerLine() {
+    return (72);
+  }
+
+  /**
+   * This character array provides the character to value map based on RFC1521.
+   */
+  private final static char pem_array[] = {
+      // 0 1 2 3 4 5 6 7
+      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
+      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
+      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
+      'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
+      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
+      'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
+      'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
+      '4', '5', '6', '7', '8', '9', '+', '/' // 7
+  };
+
+  private final static byte pem_convert_array[] = new byte[256];
+
+  static {
+    for (int i = 0; i < 255; i++) {
+      pem_convert_array[i] = -1;
+    }
+    for (int i = 0; i < pem_array.length; i++) {
+      pem_convert_array[pem_array[i]] = (byte) i;
+    }
+  }
+
+  byte decode_buffer[] = new byte[4];
+
+  /**
+   * Decode one BASE64 atom into 1, 2, or 3 bytes of data.
+   */
+  protected void decodeAtom(PushbackInputStream inStream,
+      OutputStream outStream, int rem) throws java.io.IOException {
+    int i;
+    byte a = -1, b = -1, c = -1, d = -1;
+
+    if (rem < 2) {
+      throw new CEFormatException(
+          "BASE64Decoder: Not enough bytes for an atom.");
+    }
+    do {
+      i = inStream.read();
+      if (i == -1) {
+        throw new CEStreamExhausted();
+      }
+    } while (i == '\n' || i == '\r');
+    decode_buffer[0] = (byte) i;
+
+    i = readFully(inStream, decode_buffer, 1, rem - 1);
+    if (i == -1) {
+      throw new CEStreamExhausted();
+    }
+
+    if (rem > 3 && decode_buffer[3] == '=') {
+      rem = 3;
+    }
+    if (rem > 2 && decode_buffer[2] == '=') {
+      rem = 2;
+    }
+    switch (rem) {
+    case 4:
+      d = pem_convert_array[decode_buffer[3] & 0xff];
+      // NOBREAK
+    case 3:
+      c = pem_convert_array[decode_buffer[2] & 0xff];
+      // NOBREAK
+    case 2:
+      b = pem_convert_array[decode_buffer[1] & 0xff];
+      a = pem_convert_array[decode_buffer[0] & 0xff];
+      break;
+    }
+
+    switch (rem) {
+    case 2:
+      outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+      break;
+    case 3:
+      outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+      outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
+      break;
+    case 4:
+      outStream.write((byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)));
+      outStream.write((byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)));
+      outStream.write((byte) (((c << 6) & 0xc0) | (d & 0x3f)));
+      break;
+    }
+    return;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java
new file mode 100644
index 0000000..dfd7032
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/BASE64Encoder.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * 
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+
+import java.io.OutputStream;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+
+/**
+ * This class implements a BASE64 Character encoder as specified in RFC1521.
+ * This RFC is part of the MIME specification as published by the Internet
+ * Engineering Task Force (IETF). Unlike some other encoding schemes there is
+ * nothing in this encoding that indicates where a buffer starts or ends.
+ *
+ * This means that the encoded text will simply start with the first line of
+ * encoded text and end with the last line of encoded text.
+ *
+ * @version 1.23, 11/17/05
+ * @author Chuck McManis
+ * @see CharacterEncoder
+ * @see BASE64Decoder
+ */
+
+public class BASE64Encoder extends CharacterEncoder {
+
+  /** this class encodes three bytes per atom. */
+  protected int bytesPerAtom() {
+    return (3);
+  }
+
+  /**
+   * this class encodes 57 bytes per line. This results in a maximum of 57/3 * 4
+   * or 76 characters per output line. Not counting the line termination.
+   */
+  protected int bytesPerLine() {
+    return (57);
+  }
+
+  /** This array maps the characters to their 6 bit values */
+  private final static char pem_array[] = {
+      // 0 1 2 3 4 5 6 7
+      'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', // 0
+      'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', // 1
+      'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', // 2
+      'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', // 3
+      'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', // 4
+      'o', 'p', 'q', 'r', 's', 't', 'u', 'v', // 5
+      'w', 'x', 'y', 'z', '0', '1', '2', '3', // 6
+      '4', '5', '6', '7', '8', '9', '+', '/' // 7
+  };
+
+  /**
+   * encodeAtom - Take three bytes of input and encode it as 4 printable
+   * characters. Note that if the length in len is less than three is encodes
+   * either one or two '=' signs to indicate padding characters.
+   */
+  protected void encodeAtom(OutputStream outStream, byte data[], int offset,
+      int len) throws IOException {
+    byte a, b, c;
+
+    if (len == 1) {
+      a = data[offset];
+      b = 0;
+      c = 0;
+      outStream.write(pem_array[(a >>> 2) & 0x3F]);
+      outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+      outStream.write('=');
+      outStream.write('=');
+    } else if (len == 2) {
+      a = data[offset];
+      b = data[offset + 1];
+      c = 0;
+      outStream.write(pem_array[(a >>> 2) & 0x3F]);
+      outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+      outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
+      outStream.write('=');
+    } else {
+      a = data[offset];
+      b = data[offset + 1];
+      c = data[offset + 2];
+      outStream.write(pem_array[(a >>> 2) & 0x3F]);
+      outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]);
+      outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]);
+      outStream.write(pem_array[c & 0x3F]);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java
new file mode 100644
index 0000000..0b2c0b0
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEFormatException.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 1995, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.IOException;
+
+public class CEFormatException extends IOException {
+  public CEFormatException(String s) {
+    super(s);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java
new file mode 100644
index 0000000..b935609
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CEStreamExhausted.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 1995, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.IOException;
+
+/** This exception is thrown when EOF is reached */
+public class CEStreamExhausted extends IOException {
+};
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java
new file mode 100644
index 0000000..8143a77
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterDecoder.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright (c) 1995, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.PushbackInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This class defines the decoding half of character encoders. A character
+ * decoder is an algorithim for transforming 8 bit binary data that has been
+ * encoded into text by a character encoder, back into original binary form.
+ *
+ * The character encoders, in general, have been structured around a central
+ * theme that binary data can be encoded into text that has the form:
+ *
+ * <pre>
+ *      [Buffer Prefix]
+ *      [Line Prefix][encoded data atoms][Line Suffix]
+ *      [Buffer Suffix]
+ * </pre>
+ *
+ * Of course in the simplest encoding schemes, the buffer has no distinct prefix
+ * of suffix, however all have some fixed relationship between the text in an
+ * 'atom' and the binary data itself.
+ *
+ * In the CharacterEncoder and CharacterDecoder classes, one complete chunk of
+ * data is referred to as a <i>buffer</i>. Encoded buffers are all text, and
+ * decoded buffers (sometimes just referred to as buffers) are binary octets.
+ *
+ * To create a custom decoder, you must, at a minimum, overide three abstract
+ * methods in this class.
+ * <DL>
+ * <DD>bytesPerAtom which tells the decoder how many bytes to expect from
+ * decodeAtom
+ * <DD>decodeAtom which decodes the bytes sent to it as text.
+ * <DD>bytesPerLine which tells the encoder the maximum number of bytes per
+ * line.
+ * </DL>
+ *
+ * In general, the character decoders return error in the form of a
+ * CEFormatException. The syntax of the detail string is
+ * 
+ * <pre>
+ *      DecoderClassName: Error message.
+ * </pre>
+ *
+ * Several useful decoders have already been written and are referenced in the
+ * See Also list below.
+ *
+ * @author Chuck McManis
+ * @see CEFormatException
+ * @see CharacterEncoder
+ * @see UCDecoder
+ * @see UUDecoder
+ * @see BASE64Decoder
+ */
+
+public abstract class CharacterDecoder {
+
+  /** Return the number of bytes per atom of decoding */
+  abstract protected int bytesPerAtom();
+
+  /** Return the maximum number of bytes that can be encoded per line */
+  abstract protected int bytesPerLine();
+
+  /** decode the beginning of the buffer, by default this is a NOP. */
+  protected void decodeBufferPrefix(PushbackInputStream aStream,
+      OutputStream bStream) throws IOException {
+  }
+
+  /** decode the buffer suffix, again by default it is a NOP. */
+  protected void decodeBufferSuffix(PushbackInputStream aStream,
+      OutputStream bStream) throws IOException {
+  }
+
+  /**
+   * This method should return, if it knows, the number of bytes that will be
+   * decoded. Many formats such as uuencoding provide this information. By
+   * default we return the maximum bytes that could have been encoded on the
+   * line.
+   */
+  protected int decodeLinePrefix(PushbackInputStream aStream,
+      OutputStream bStream) throws IOException {
+    return (bytesPerLine());
+  }
+
+  /**
+   * This method post processes the line, if there are error detection or
+   * correction codes in a line, they are generally processed by this method.
+   * The simplest version of this method looks for the (newline) character.
+   */
+  protected void decodeLineSuffix(PushbackInputStream aStream,
+      OutputStream bStream) throws IOException {
+  }
+
+  /**
+   * This method does an actual decode. It takes the decoded bytes and writes
+   * them to the OutputStream. The integer <i>l</i> tells the method how many
+   * bytes are required. This is always <= bytesPerAtom().
+   */
+  protected void decodeAtom(PushbackInputStream aStream, OutputStream bStream,
+      int l) throws IOException {
+    throw new CEStreamExhausted();
+  }
+
+  /**
+   * This method works around the bizarre semantics of BufferedInputStream's
+   * read method.
+   */
+  protected int readFully(InputStream in, byte buffer[], int offset, int len)
+      throws java.io.IOException {
+    for (int i = 0; i < len; i++) {
+      int q = in.read();
+      if (q == -1)
+        return ((i == 0) ? -1 : i);
+      buffer[i + offset] = (byte) q;
+    }
+    return len;
+  }
+
+  /**
+   * Decode the text from the InputStream and write the decoded octets to the
+   * OutputStream. This method runs until the stream is exhausted.
+   * 
+   * @exception CEFormatException
+   *              An error has occured while decoding
+   * @exception CEStreamExhausted
+   *              The input stream is unexpectedly out of data
+   */
+  public void decodeBuffer(InputStream aStream, OutputStream bStream)
+      throws IOException {
+    int i;
+    int totalBytes = 0;
+
+    PushbackInputStream ps = new PushbackInputStream(aStream);
+    decodeBufferPrefix(ps, bStream);
+    while (true) {
+      int length;
+
+      try {
+        length = decodeLinePrefix(ps, bStream);
+        for (i = 0; (i + bytesPerAtom()) < length; i += bytesPerAtom()) {
+          decodeAtom(ps, bStream, bytesPerAtom());
+          totalBytes += bytesPerAtom();
+        }
+        if ((i + bytesPerAtom()) == length) {
+          decodeAtom(ps, bStream, bytesPerAtom());
+          totalBytes += bytesPerAtom();
+        } else {
+          decodeAtom(ps, bStream, length - i);
+          totalBytes += (length - i);
+        }
+        decodeLineSuffix(ps, bStream);
+      } catch (CEStreamExhausted e) {
+        break;
+      }
+    }
+    decodeBufferSuffix(ps, bStream);
+  }
+
+  /**
+   * Alternate decode interface that takes a String containing the encoded
+   * buffer and returns a byte array containing the data.
+   * 
+   * @exception CEFormatException
+   *              An error has occured while decoding
+   */
+  public byte decodeBuffer(String inputString)[] throws IOException {
+    byte inputBuffer[] = new byte[inputString.length()];
+    ByteArrayInputStream inStream;
+    ByteArrayOutputStream outStream;
+
+    inputString.getBytes(0, inputString.length(), inputBuffer, 0);
+    inStream = new ByteArrayInputStream(inputBuffer);
+    outStream = new ByteArrayOutputStream();
+    decodeBuffer(inStream, outStream);
+    return (outStream.toByteArray());
+  }
+
+  /**
+   * Decode the contents of the inputstream into a buffer.
+   */
+  public byte decodeBuffer(InputStream in)[] throws IOException {
+    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+    decodeBuffer(in, outStream);
+    return (outStream.toByteArray());
+  }
+
+  /**
+   * Decode the contents of the String into a ByteBuffer.
+   */
+  public ByteBuffer decodeBufferToByteBuffer(String inputString)
+      throws IOException {
+    return ByteBuffer.wrap(decodeBuffer(inputString));
+  }
+
+  /**
+   * Decode the contents of the inputStream into a ByteBuffer.
+   */
+  public ByteBuffer decodeBufferToByteBuffer(InputStream in)
+      throws IOException {
+    return ByteBuffer.wrap(decodeBuffer(in));
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java
new file mode 100644
index 0000000..feb23b3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/CharacterEncoder.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+/**
+ * This class defines the encoding half of character encoders. A character
+ * encoder is an algorithim for transforming 8 bit binary data into text
+ * (generally 7 bit ASCII or 8 bit ISO-Latin-1 text) for transmition over text
+ * channels such as e-mail and network news.
+ *
+ * The character encoders have been structured around a central theme that, in
+ * general, the encoded text has the form:
+ *
+ * <pre>
+ *	[Buffer Prefix]
+ *	[Line Prefix][encoded data atoms][Line Suffix]
+ *	[Buffer Suffix]
+ * </pre>
+ *
+ * In the CharacterEncoder and CharacterDecoder classes, one complete chunk of
+ * data is referred to as a <i>buffer</i>. Encoded buffers are all text, and
+ * decoded buffers (sometimes just referred to as buffers) are binary octets.
+ *
+ * To create a custom encoder, you must, at a minimum, overide three abstract
+ * methods in this class.
+ * <DL>
+ * <DD>bytesPerAtom which tells the encoder how many bytes to send to encodeAtom
+ * <DD>encodeAtom which encodes the bytes sent to it as text.
+ * <DD>bytesPerLine which tells the encoder the maximum number of bytes per
+ * line.
+ * </DL>
+ *
+ * Several useful encoders have already been written and are referenced in the
+ * See Also list below.
+ *
+ * @version 1.38, 11/17/05
+ * @author Chuck McManis
+ * @see CharacterDecoder;
+ * @see UCEncoder
+ * @see UUEncoder
+ * @see BASE64Encoder
+ */
+public abstract class CharacterEncoder {
+
+  /** Stream that understands "printing" */
+  protected PrintStream pStream;
+
+  /** Return the number of bytes per atom of encoding */
+  abstract protected int bytesPerAtom();
+
+  /** Return the number of bytes that can be encoded per line */
+  abstract protected int bytesPerLine();
+
+  /**
+   * Encode the prefix for the entire buffer. By default is simply opens the
+   * PrintStream for use by the other functions.
+   */
+  protected void encodeBufferPrefix(OutputStream aStream) throws IOException {
+    pStream = new PrintStream(aStream);
+  }
+
+  /**
+   * Encode the suffix for the entire buffer.
+   */
+  protected void encodeBufferSuffix(OutputStream aStream) throws IOException {
+  }
+
+  /**
+   * Encode the prefix that starts every output line.
+   */
+  protected void encodeLinePrefix(OutputStream aStream, int aLength)
+      throws IOException {
+  }
+
+  /**
+   * Encode the suffix that ends every output line. By default this method just
+   * prints a <newline> into the output stream.
+   */
+  protected void encodeLineSuffix(OutputStream aStream) throws IOException {
+    pStream.println();
+  }
+
+  /** Encode one "atom" of information into characters. */
+  abstract protected void encodeAtom(OutputStream aStream, byte someBytes[],
+      int anOffset, int aLength) throws IOException;
+
+  /**
+   * This method works around the bizarre semantics of BufferedInputStream's
+   * read method.
+   */
+  protected int readFully(InputStream in, byte buffer[])
+      throws java.io.IOException {
+    for (int i = 0; i < buffer.length; i++) {
+      int q = in.read();
+      if (q == -1)
+        return i;
+      buffer[i] = (byte) q;
+    }
+    return buffer.length;
+  }
+
+  /**
+   * Encode bytes from the input stream, and write them as text characters to
+   * the output stream. This method will run until it exhausts the input stream,
+   * but does not print the line suffix for a final line that is shorter than
+   * bytesPerLine().
+   */
+  public void encode(InputStream inStream, OutputStream outStream)
+      throws IOException {
+    int j;
+    int numBytes;
+    byte tmpbuffer[] = new byte[bytesPerLine()];
+
+    encodeBufferPrefix(outStream);
+
+    while (true) {
+      numBytes = readFully(inStream, tmpbuffer);
+      if (numBytes == 0) {
+        break;
+      }
+      encodeLinePrefix(outStream, numBytes);
+      for (j = 0; j < numBytes; j += bytesPerAtom()) {
+
+        if ((j + bytesPerAtom()) <= numBytes) {
+          encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+        } else {
+          encodeAtom(outStream, tmpbuffer, j, (numBytes) - j);
+        }
+      }
+      if (numBytes < bytesPerLine()) {
+        break;
+      } else {
+        encodeLineSuffix(outStream);
+      }
+    }
+    encodeBufferSuffix(outStream);
+  }
+
+  /**
+   * Encode the buffer in <i>aBuffer</i> and write the encoded result to the
+   * OutputStream <i>aStream</i>.
+   */
+  public void encode(byte aBuffer[], OutputStream aStream) throws IOException {
+    ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+    encode(inStream, aStream);
+  }
+
+  /**
+   * A 'streamless' version of encode that simply takes a buffer of bytes and
+   * returns a string containing the encoded buffer.
+   */
+  public String encode(byte aBuffer[]) {
+    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+    ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+    String retVal = null;
+    try {
+      encode(inStream, outStream);
+      // explicit ascii->unicode conversion
+      retVal = outStream.toString("8859_1");
+    } catch (Exception IOException) {
+      // This should never happen.
+      throw new Error("CharacterEncoder.encode internal error");
+    }
+    return (retVal);
+  }
+
+  /**
+   * Return a byte array from the remaining bytes in this ByteBuffer.
+   * <P>
+   * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+   * <P>
+   * To avoid an extra copy, the implementation will attempt to return the byte
+   * array backing the ByteBuffer. If this is not possible, a new byte array
+   * will be created.
+   */
+  private byte[] getBytes(ByteBuffer bb) {
+    /*
+     * This should never return a BufferOverflowException, as we're careful to
+     * allocate just the right amount.
+     */
+    byte[] buf = null;
+
+    /*
+     * If it has a usable backing byte buffer, use it. Use only if the array
+     * exactly represents the current ByteBuffer.
+     */
+    if (bb.hasArray()) {
+      byte[] tmp = bb.array();
+      if ((tmp.length == bb.capacity()) && (tmp.length == bb.remaining())) {
+        buf = tmp;
+        bb.position(bb.limit());
+      }
+    }
+
+    if (buf == null) {
+      /*
+       * This class doesn't have a concept of encode(buf, len, off), so if we
+       * have a partial buffer, we must reallocate space.
+       */
+      buf = new byte[bb.remaining()];
+
+      /*
+       * position() automatically updated
+       */
+      bb.get(buf);
+    }
+
+    return buf;
+  }
+
+  /**
+   * Encode the <i>aBuffer</i> ByteBuffer and write the encoded result to the
+   * OutputStream <i>aStream</i>.
+   * <P>
+   * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+   */
+  public void encode(ByteBuffer aBuffer, OutputStream aStream)
+      throws IOException {
+    byte[] buf = getBytes(aBuffer);
+    encode(buf, aStream);
+  }
+
+  /**
+   * A 'streamless' version of encode that simply takes a ByteBuffer and returns
+   * a string containing the encoded buffer.
+   * <P>
+   * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+   */
+  public String encode(ByteBuffer aBuffer) {
+    byte[] buf = getBytes(aBuffer);
+    return encode(buf);
+  }
+
+  /**
+   * Encode bytes from the input stream, and write them as text characters to
+   * the output stream. This method will run until it exhausts the input stream.
+   * It differs from encode in that it will add the line at the end of a final
+   * line that is shorter than bytesPerLine().
+   */
+  public void encodeBuffer(InputStream inStream, OutputStream outStream)
+      throws IOException {
+    int j;
+    int numBytes;
+    byte tmpbuffer[] = new byte[bytesPerLine()];
+
+    encodeBufferPrefix(outStream);
+
+    while (true) {
+      numBytes = readFully(inStream, tmpbuffer);
+      if (numBytes == 0) {
+        break;
+      }
+      encodeLinePrefix(outStream, numBytes);
+      for (j = 0; j < numBytes; j += bytesPerAtom()) {
+        if ((j + bytesPerAtom()) <= numBytes) {
+          encodeAtom(outStream, tmpbuffer, j, bytesPerAtom());
+        } else {
+          encodeAtom(outStream, tmpbuffer, j, (numBytes) - j);
+        }
+      }
+      encodeLineSuffix(outStream);
+      if (numBytes < bytesPerLine()) {
+        break;
+      }
+    }
+    encodeBufferSuffix(outStream);
+  }
+
+  /**
+   * Encode the buffer in <i>aBuffer</i> and write the encoded result to the
+   * OutputStream <i>aStream</i>.
+   */
+  public void encodeBuffer(byte aBuffer[], OutputStream aStream)
+      throws IOException {
+    ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+    encodeBuffer(inStream, aStream);
+  }
+
+  /**
+   * A 'streamless' version of encode that simply takes a buffer of bytes and
+   * returns a string containing the encoded buffer.
+   */
+  public String encodeBuffer(byte aBuffer[]) {
+    ByteArrayOutputStream outStream = new ByteArrayOutputStream();
+    ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer);
+    try {
+      encodeBuffer(inStream, outStream);
+    } catch (Exception IOException) {
+      // This should never happen.
+      throw new Error("CharacterEncoder.encodeBuffer internal error");
+    }
+    return (outStream.toString());
+  }
+
+  /**
+   * Encode the <i>aBuffer</i> ByteBuffer and write the encoded result to the
+   * OutputStream <i>aStream</i>.
+   * <P>
+   * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+   */
+  public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream)
+      throws IOException {
+    byte[] buf = getBytes(aBuffer);
+    encodeBuffer(buf, aStream);
+  }
+
+  /**
+   * A 'streamless' version of encode that simply takes a ByteBuffer and returns
+   * a string containing the encoded buffer.
+   * <P>
+   * The ByteBuffer's position will be advanced to ByteBuffer's limit.
+   */
+  public String encodeBuffer(ByteBuffer aBuffer) {
+    byte[] buf = getBytes(aBuffer);
+    return encodeBuffer(buf);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java
new file mode 100644
index 0000000..89f8a4e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/RemoteLoggingInitException.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+/**
+ * This exception is thrown by the init method of the TestUtil class, if
+ * anything goes wrong while establishing a socket connection back to the
+ * harness host.
+ * 
+ * @author Kyle Grucci
+ */
+public class RemoteLoggingInitException extends java.lang.Exception {
+  /**
+   * creates a RemoteLoggingInitException
+   */
+  public RemoteLoggingInitException() {
+    super();
+  }
+
+  /**
+   * creates a RemoteLoggingInitException with a message
+   * 
+   * @param s
+   *          the message
+   */
+  public RemoteLoggingInitException(String s) {
+    super(s);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java
new file mode 100644
index 0000000..fe19465
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/lib/util/TestUtil.java
@@ -0,0 +1,1071 @@
+/*
+ * Copyright (c) 2007, 2021 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0, which is available at
+ * http://www.eclipse.org/legal/epl-2.0.
+ *
+ * This Source Code may also be made available under the following Secondary
+ * Licenses when the conditions for such availability set forth in the
+ * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+ * version 2 with the GNU Classpath Exception, which is available at
+ * https://www.gnu.org/software/classpath/license.html.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+ */
+
+/*
+ * $Id$
+ */
+
+package jakarta.ws.rs.tck.lib.util;
+
+import java.io.*;
+import java.util.*;
+import java.net.*;
+import java.text.SimpleDateFormat;
+
+/**
+ * TestUtil is a final utility class responsible for implementing logging across
+ * multiple VMs. It also contains many convenience methods for logging property
+ * object contents, stacktraces, and header lines.
+ *
+ * @author Kyle Grucci
+ *
+ */
+public final class TestUtil {
+  public static boolean traceflag = Boolean.getBoolean("junit.log.traceflag");
+
+  // this can be set in TestUtil's start logging method!!
+  public static String sTestName;
+
+  public static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+  public static final int VM_UNDER_TEST = 0;
+
+  public static final int VM_HARNESS = 1; // this is really the test client VM
+
+  public static final int VM_JAVATEST = 2;
+
+  public static final int DEBUG_OUTPUT_LEVEL = 2;
+
+  public static final int NORMAL_OUTPUT_LEVEL = 3;
+
+  public static final int ERROR_STREAM = 4;
+
+  public static final int OUTPUT_STREAM = 5;
+
+  public static String NEW_LINE = System.getProperty("line.separator", "\n");
+
+  // by default so the testers don't have to do anything
+  public static int iWhereAreWe = VM_UNDER_TEST;
+
+  private static PrintWriter out = null;
+
+  private static PrintWriter err = null;
+
+  private static PrintWriter additionalWriter = null;
+
+  private static ObjectOutputStream objectOutputStream = null;
+
+  private static ObjectOutputStream objectInputStream = null;
+
+  private static Socket socketOnRemoteVM = null;
+
+  private static boolean bAlreadyInitialized = false;
+
+  private static Object socketMutex = new Object();
+
+  private static int portOfHarness = 2000;
+
+  private static String hostOfHarness = "unset host";
+
+  private static Vector vBuffereredOutput = new Vector();
+
+  // Transaction Attribute Value Mapping Table
+  private static final String UNRECOGNIZED_STATUS = "UNRECOGNIZED_STATUS";
+
+  private static final String transactionTable[] = { "STATUS_ACTIVE", // 0
+      "STATUS_MARKED_ROLLBACK", // 1
+      "STATUS_PREPARED", // 2
+      "STATUS_COMMITTED", // 3
+      "STATUS_ROLLEDBACK", // 4
+      "STATUS_UNKNOWN", // 5
+      "STATUS_NO_TRANSACTION", // 6
+      "STATUS_PREPARING", // 7
+      "STATUS_COMMITTING", // 8
+      "STATUS_ROLLING_BACK", // 9
+  };
+
+  // debug flag for printing TS harness debug output
+  public static boolean harnessDebug;
+
+  // hang onto the props that are passed in during logging init calls
+  private static Properties testProps = null;
+
+  private static SimpleDateFormat df = new SimpleDateFormat(
+      "MM-dd-yyyy HH:mm:ss");
+
+  static {
+    harnessDebug = Boolean.getBoolean("cts.harness.debug");
+  }
+
+  /**
+   * used by harness to log debug output to the standard output stream
+   * 
+   * @param s
+   *          the output string
+   */
+  public static void logHarnessDebug(String s) {
+    if (harnessDebug) {
+      logHarness(s, null);
+    }
+  }
+
+  /**
+   * used by TSTestFinder and TSScript to log output to the standard output
+   * stream
+   *
+   * @param s
+   *          the output string
+   * @param t
+   *          a Throwable whose stacktrace gets printed
+   */
+  public static void logHarness(String s, Throwable t) {
+    synchronized (System.out) {
+      System.out.println(df.format(new Date()) + ":" + s);
+      //logToAdditionalWriter(s, t);
+      if (t != null) {
+        t.printStackTrace();
+      }
+    }
+  }
+
+  public static void logHarness(String s) {
+    logHarness(s, null);
+  }
+
+  private static void logToAdditionalWriter(String s) {
+    logToAdditionalWriter(s, null);
+  }
+
+  private static void logToAdditionalWriter(String s, Throwable t) {
+    if (additionalWriter != null)
+      additionalWriter.println(s);
+    if (t != null) {
+      t.printStackTrace(additionalWriter);
+    }
+  }
+
+  /**
+   * This method returns the properties object
+   *
+   * @return the properties object
+   */
+  public static Properties getProperties() {
+    if (testProps == null) {
+      testProps = getPropsFromFile();
+    }
+    return testProps;
+  }
+
+  /**
+   * This method returns the property value for the appropriate property key
+   *
+   * @param s
+   *          the property name
+   * @return the property value
+   */
+  public static String getProperty(String s) {
+    Properties p = getProperties();
+    return p.getProperty(s);
+  }
+
+  /**
+   * This method returns the property value for the appropriate property key
+   * 
+   * @param s
+   *          the property name
+   * @return the property value
+   */
+  public static String getProperty(String s, String defaultValue) {
+    Properties p = getProperties();
+    return p.getProperty(s, defaultValue);
+  }
+
+  /**
+   * returns the transaction status value as a String given its integer
+   * representation
+   *
+   * @param status
+   *          integer representation of a transaction status
+   * @return string representation of a transaction status
+   */
+  public static String getTransactionStatus(int status) {
+    if (status < 0 || status > transactionTable.length - 1)
+      return UNRECOGNIZED_STATUS;
+    else
+      return transactionTable[status];
+  }
+
+  /**
+   * prints the transaction status value as a String given its integer
+   * representation
+   *
+   * @param status
+   *          integer representation of a transaction status
+   */
+  public static void printTransactionStatus(int status) {
+    logMsg("TRANSACTION_STATUS: " + getTransactionStatus(status));
+  }
+
+  // MilliSeconds Multiple
+  public static final int MILLI = 1000;
+
+  /**
+   * pauses the calling thread for the specified number of seconds
+   *
+   * @param s
+   *          number of seconds
+   */
+  public static void sleepSec(int s) {
+    logTrace("Sleeping " + s + " seconds");
+    try {
+      Thread.sleep(s * MILLI);
+    } catch (InterruptedException e) {
+      logErr("Exception: " + e);
+    }
+  }
+
+  /**
+   * pauses the calling thread for the specified number of milliseconds
+   *
+   * @param s
+   *          number of milliseconds
+   */
+  public static void sleep(int s) {
+    sleepMsec(s);
+  }
+
+  /**
+   * pauses the calling thread for the specified number of milliseconds
+   *
+   * @param s
+   *          number of milliseconds
+   */
+  public static void sleepMsec(int s) {
+    logTrace("Sleeping " + s + " milliseconds");
+    try {
+      Thread.sleep(s);
+    } catch (InterruptedException e) {
+      logErr("Exception: " + e);
+    }
+  }
+
+  public static void flushStream() {
+    synchronized (socketMutex) {
+      try {
+        objectOutputStream.flush();
+      } catch (Throwable t) {
+        // Ignore
+        // System.out.println("EXCEPTION WHILE FLUSHING");
+      }
+    }
+  }
+
+  public static void writeObject(TestReportInfo info) {
+    synchronized (socketMutex) {
+      flushStream();
+      try {
+        objectOutputStream.writeObject(info);
+        // System.out.println("WROTE: " + info.sOutput);
+      } catch (Exception e) {
+        // System.out.println("EXCEPTION WHILE WRITING: " + info.sOutput);
+        synchronized (vBuffereredOutput) {
+          vBuffereredOutput.addElement(info);
+          // System.out.println("ADDED THIS STRING TO BUFFERED OUT: " +
+          // info.sOutput);
+        }
+      }
+      flushStream();
+    }
+  }
+
+  private static void sendBufferedData() throws Exception {
+    TestReportInfo tri = null;
+    synchronized (vBuffereredOutput) {
+      try {
+        // logMsg("vBuffereredOutput size = " + vBuffereredOutput.size());
+        synchronized (socketMutex) {
+          for (int ii = 0; ii < vBuffereredOutput.size(); ii++) {
+            tri = (TestReportInfo) vBuffereredOutput.elementAt(ii);
+            writeObject(tri);
+            // System.out.println("WRITING_bufferedoutput: " + tri.sOutput);
+            // objectOutputStream.writeObject(tri);
+            // objectOutputStream.flush();
+            // logMsg("writing: " + ii);
+            // logMsg("writing: " + tri.sOutput);
+          }
+        }
+        // logMsg("wrote buffered output");
+      } catch (Exception e) {
+        throw e;
+      } finally {
+        vBuffereredOutput.removeAllElements();
+        // logMsg("reinititialized buffered output vector");
+      }
+    }
+  }
+
+  private static final String PROPS_FILE_NAME = "-cts-props.txt";
+
+  private static final String PROPS_FILE;
+
+  static {
+    String userName = System.getProperty("user.name");
+    String tmpDir = System.getProperty("java.io.tmpdir",
+        File.separator + "tmp");
+    if (tmpDir.endsWith(File.separator)) {
+      PROPS_FILE = tmpDir + userName + PROPS_FILE_NAME;
+    } else {
+      PROPS_FILE = tmpDir + File.separator + userName + PROPS_FILE_NAME;
+    }
+    System.out.println(
+        "************************************************************");
+    System.out.println("* props file set to \"" + PROPS_FILE + "\"");
+    System.out.println(
+        "************************************************************");
+  }
+
+  private static Properties getPropsFromFile() {
+    FileInputStream in = null;
+    Properties p = new Properties();
+    try {
+      in = new FileInputStream(PROPS_FILE);
+      p.load(in);
+    } catch (Exception e) {
+      logErr("Error reading the Properties object", e);
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (Exception e) {
+        }
+      }
+    }
+    return p;
+  }
+
+  private static void savePropsToFile(Properties p) {
+    FileOutputStream out = null;
+    try {
+      out = new FileOutputStream(PROPS_FILE);
+      p.store(out, "CTS Test Properties File");
+    } catch (Exception e) {
+      logErr("Error saving the Properties object", e);
+    } finally {
+      if (out != null) {
+        try {
+          out.close();
+        } catch (Exception e) {
+        }
+      }
+    }
+  }
+
+  /**
+   * This static method must be called once by each new remote VM. Once called,
+   * a socket connection is created back to the host running the test harness.
+   * All calls to logMsg, logErr, and logTrace are immediately sent back to the
+   * harness host.
+   *
+   * @param p
+   *          properties containing harness host, port, and trace flag
+   * @exception RemoteLoggingInitException
+   *              if an exception occurs while the server side is setting up the
+   *              socket connection back to the client host
+   */
+  public static void init(Properties p) throws RemoteLoggingInitException {
+    savePropsToFile(p); // persist properties to a disk file
+    // System.out.println("INIT_CALLED");
+    synchronized (socketMutex) {
+      try {
+        // TSPropertyManager.createTSPropertyManager(p);
+        testProps = p;
+        if (p.isEmpty()) {
+          throw new RemoteLoggingInitException(
+              "Init: Error - Empty properties object passed to TestUtil.init");
+        }
+        NEW_LINE = p.getProperty("line.separator");
+        if (socketOnRemoteVM != null) {
+          socketOnRemoteVM.close();
+        }
+        if (objectOutputStream != null) {
+          objectOutputStream.close();
+        }
+        if (true) {
+          // System.out.println("INIT_CALLED AND SOCKET = NULL");
+          traceflag = Boolean
+              .valueOf(p.getProperty("harness.log.traceflag", "true"))
+              .booleanValue();
+          hostOfHarness = p.getProperty("harness.host");
+          portOfHarness = Integer
+              .parseInt(p.getProperty("harness.log.port", "2000"));
+          if (hostOfHarness == null) {
+            throw new RemoteLoggingInitException(
+                "Init: Error while trying to getProperty(harness.host) - returned null");
+          }
+          socketOnRemoteVM = new Socket(hostOfHarness, portOfHarness);
+          objectOutputStream = new ObjectOutputStream(
+              socketOnRemoteVM.getOutputStream());
+          sendBufferedData();
+          // logMsg("socketOnRemoteVM=null, renewed everything");
+        } else {
+          // we'll never get here now...
+          // call flush to make sure that we still have an open connection.
+          // if the client went away and a new client is being run, we will
+          // get an IOException, in which case we will reconnect.
+          // logMsg("socketOnRemoteVM != null, calling flush");
+          // objectOutputStream.flush();
+          // if this fails, then the connection is gone
+          // this is better than flush, because flush seems to always fail
+          TestReportInfo tri = new TestReportInfo("SVR: " + "Logging check",
+              OUTPUT_STREAM, DEBUG_OUTPUT_LEVEL, null);
+          objectOutputStream.writeObject(tri);
+          // System.out.println("WROTE TEST OBJECT");
+        }
+      } catch (UnknownHostException e) {
+        throw new RemoteLoggingInitException(
+            "You must pass a valid host string to init()");
+      } catch (IOException e) {
+        // System.out.println("EXCEPTION WHILE WRITING TEST OBJECT");
+        // the client VM may have shutdown, so establish a new connection
+        try {
+          // System.out.println("INIT_CALLED AND TRYING TO ESABLISH CONN. AFTER
+          // IOEXCEPTION");
+          traceflag = Boolean
+              .valueOf(p.getProperty("harness.log.traceflag", "true"))
+              .booleanValue();
+          hostOfHarness = p.getProperty("harness.host");
+          portOfHarness = Integer
+              .parseInt(p.getProperty("harness.log.port", "2000"));
+          if (hostOfHarness == null) {
+            throw new RemoteLoggingInitException(
+                "Init: Error while trying to getProperty(harness.host) - returned null");
+          }
+          socketOnRemoteVM.close();
+          socketOnRemoteVM = new Socket(hostOfHarness, portOfHarness);
+          objectOutputStream = new ObjectOutputStream(
+              socketOnRemoteVM.getOutputStream());
+          sendBufferedData();
+          // logMsg("caught IOException from flush(), renewed everything");
+        } catch (IOException e2) {
+          e2.printStackTrace();
+          throw new RemoteLoggingInitException(
+              "IOException in TestUtil.init()");
+        } catch (Exception e2) {
+          e2.printStackTrace();
+          throw new RemoteLoggingInitException(
+              "got a random exception in init()");
+        }
+      } catch (NumberFormatException e) {
+        throw new RemoteLoggingInitException(
+            "You must pass a valid port number string to init()");
+      } catch (Exception e) {
+        e.printStackTrace();
+        throw new RemoteLoggingInitException(
+            "got a random exception in init()");
+      }
+    }
+  }
+
+  /*
+   * This method is called by our harness code to allow code that is shared
+   * between the harness and the tests and calls TestUtil logMsg and logTrace to
+   * do the right thing inside of the JavaTest VM. These calls will call to our
+   * logHarness methods.
+   */
+  public static void initJavaTest() {
+    iWhereAreWe = VM_JAVATEST;
+  }
+
+  public static void setAdditionalWriter(PrintWriter pw) {
+    iWhereAreWe = VM_JAVATEST;
+    additionalWriter = pw;
+  }
+
+  /**
+   * This static method must be called once by a VM which does not rely upon any
+   * remote logging.
+   *
+   * param p properties containing harness trace flag
+   */
+  public static void initNoLogging(Properties p) {
+    if (bAlreadyInitialized)
+      return;
+
+    testProps = p;
+    NEW_LINE = p.getProperty("line.separator");
+    traceflag = Boolean.valueOf(p.getProperty("harness.log.traceflag", "true"))
+        .booleanValue();
+    iWhereAreWe = VM_HARNESS;
+    bAlreadyInitialized = true;
+  }
+
+  /**
+   * This static method must be called once by the harness VM. Once called, a
+   * serversocket begins listening for Remote VMs to connect on the port
+   * specified by harness.log.port.
+   *
+   * @param p
+   *          properties containing harness trace flag
+   */
+  public static void initClient(Properties p) {
+    if (bAlreadyInitialized)
+      return;
+    // start listener thread
+    try {
+      testProps = p;
+      NEW_LINE = p.getProperty("line.separator");
+      traceflag = Boolean
+          .valueOf(p.getProperty("harness.log.traceflag", "true"))
+          .booleanValue();
+      iWhereAreWe = VM_HARNESS;
+      ServerSocket ss = getServerSocket(p);
+      new Acceptor(ss);
+      bAlreadyInitialized = true;
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+
+  private static ServerSocket getServerSocket(Properties p) throws IOException {
+    ServerSocket result = null;
+    int port = 2000;
+    int retry = 10;
+    final int delaySeconds = 1;
+    try {
+      port = Integer.parseInt(p.getProperty("harness.log.port", "2000"));
+    } catch (NumberFormatException e1) {
+      e1.printStackTrace();
+      System.err.println("Invalid value for harness.log.port,"
+          + " using default harness.log.port of " + port);
+    }
+    try {
+      retry = Integer
+          .parseInt(p.getProperty("harness.socket.retry.count", "10"));
+    } catch (NumberFormatException e2) {
+      e2.printStackTrace();
+      System.err.println("Invalid value for harness.socket.retry.count,"
+          + " using default harness.socket.retry.count of " + retry);
+    }
+    logTrace(
+        "#######  Value of harness.socket.retry.count is \"" + retry + "\"");
+    logTrace("#######  Value of harness.log.port is \"" + port + "\"");
+    result = getServerSocket0(port, retry, delaySeconds);
+    while (result == null) {
+      port++;
+      result = getServerSocket0(port, retry, delaySeconds);
+    }
+    p.setProperty("harness.log.port", Integer.toString(port));
+    logTrace(
+        "#######  Actual bind value of harness.log.port is \"" + port + "\"");
+    return result;
+  }
+
+  private static ServerSocket getServerSocket0(int port, int retry,
+      int delaySeconds) {
+    ServerSocket result = null;
+    for (int i = 0; i < retry; i++) {
+      try {
+        result = new ServerSocket(port);
+        break;
+      } catch (IOException e3) {
+        try {
+          Thread.sleep(delaySeconds * 1000);
+        } catch (InterruptedException e4) {
+        }
+      }
+    }
+    return result;
+  }
+
+  /**
+   * This static method must be called once by the harness VM in order to set
+   * the output and error streams and the name of the current test.
+   *
+   * @param testName
+   *          the currently running testname as specified in the source code
+   *          tags
+   * @param outStream
+   *          stream printed to by the logMsg and logTrace methods
+   * @param errStream
+   *          stream printed to by the logErr methods
+   */
+  public static void setCurrentTest(String testName, PrintWriter outStream,
+      PrintWriter errStream) {
+    sTestName = testName;
+    out = outStream;
+    err = outStream;
+  }
+
+  /**
+   * prints a string to the log stream. All tests should use this method for
+   * standard logging messages
+   *
+   * @param s
+   *          string to print to the log stream
+   */
+  public static void logMsg(String s) {
+    logHarness(s);
+  }
+
+  /**
+   * prints a string as well as the provided Throwable's stacktrace to the log
+   * stream. All tests should use this method for standard logging messages
+   *
+   * @param s
+   *          string to print to the log stream
+   * @param t
+   *          - throwable whose stacktrace gets printed*
+   *
+   */
+  public static void logMsg(String s, Throwable t) {
+    logHarnessDebug(s);
+    if (t != null) {
+      t.printStackTrace();
+    }
+  }
+
+  /**
+   * turns on/off debugging. Once on, all calls to the logTrace method result in
+   * messages being printed to the log stream. If off, all logTrace calls are
+   * not printed.
+   *
+   * @param b
+   *          If <code>true</code>, debugging is on. If false, debugging is
+   *          turned off.
+   */
+  public static void setTrace(boolean b) {
+    traceflag = b;
+  }
+
+  /**
+   * prints a debug string to the log stream. All tests should use this method
+   * for verbose logging messages. Whether or not the string is printed is
+   * determined by the last call to the setTrace method.
+   *
+   * @param s
+   *          string to print to the log stream
+   */
+  public static void logTrace(String s) {
+    logTrace(s, null);
+  }
+
+  /**
+   * Prints a debug string as well as the provided Throwable's stacktrace. Use
+   * this if certain exceptions are only desired while tracing.
+   *
+   * @param s
+   *          - string to print to the log stream
+   * @param t
+   *          - throwable whose stactrace gets printed
+   */
+  public static void logTrace(String s, Throwable t) {
+    if (traceflag) {
+      logHarnessDebug(s);
+      if (t != null) {
+        t.printStackTrace();
+      }
+    }
+  }
+
+  /**
+   * prints an error string to the error stream. All tests should use this
+   * method for error messages.
+   *
+   * @param s
+   *          string to print to the error stream
+   * @param e
+   *          a Throwable whose stacktrace gets printed
+   */
+  public static void logErr(String s, Throwable e) {
+    logHarness(s);
+    if (e != null) {
+      e.printStackTrace();
+    }
+  }
+
+  /**
+   * prints an error string to the error stream. All tests should use this
+   * method for error messages.
+   *
+   * @param s
+   *          string to print to the error stream
+   */
+  public static void logErr(String s) {
+    logErr(s, null);
+  }
+
+  /**
+   * prints the contents of a properties object to the logging stream
+   *
+   * @param p
+   *          properties to print
+   */
+  public static void list(Properties p) {
+    StringBuffer sb = new StringBuffer();
+    if (p == null)
+      return;
+    sb.append("--- Property Listing ---").append(TestUtil.NEW_LINE);
+    Enumeration e = p.propertyNames();
+    String key = null;
+    while (e.hasMoreElements()) {
+      key = (String) e.nextElement();
+      sb.append(key).append("=").append(p.getProperty(key))
+          .append(TestUtil.NEW_LINE);
+    }
+    sb.append("--- End Property Listing ---").append(TestUtil.NEW_LINE);
+    logTrace(new String(sb));
+  }
+
+  /**
+   * prints the stacktrace of a Throwable to the logging stream
+   *
+   * @param e
+   *          exception to print the stacktrace of
+   */
+  public static void printStackTrace(Throwable e) {
+    if (e == null) {
+      return;
+    }
+    try {
+      StringWriter sw = new StringWriter();
+      PrintWriter writer = new PrintWriter(sw);
+      e.printStackTrace(writer);
+      logErr(sw.toString());
+      writer.close();
+    } catch (Exception E) {
+    }
+  }
+
+  /**
+   * prints the stacktrace of a Throwable to a string
+   *
+   * @param e
+   *          exception to print the stacktrace of
+   */
+  public static String printStackTraceToString(Throwable e) {
+    String sTrace = "";
+    if (e == null)
+      return "";
+    try {
+      StringWriter sw = new StringWriter();
+      PrintWriter writer = new PrintWriter(sw);
+      e.printStackTrace(writer);
+      sTrace = sw.toString();
+      writer.close();
+    } catch (Exception E) {
+    }
+    return sTrace;
+  }
+
+  /**
+   * prints a line of asterisks to the logging stream
+   */
+  public static void separator2() {
+    logMsg("**************************************************"
+        + "******************************");
+  }
+
+  /**
+   * prints a line of dashes to the logging stream
+   */
+  public static void separator1() {
+    logMsg("--------------------------------------------------"
+        + "------------------------------");
+  }
+
+  /**
+   * Convience method to handle sucking in the data from a connection.
+   */
+  public static String getResponse(URLConnection connection)
+      throws IOException {
+    StringBuffer content;
+    BufferedReader in;
+    // set up the streams / readers
+    InputStream instream = connection.getInputStream();
+    InputStreamReader inreader = new InputStreamReader(instream);
+    in = new BufferedReader(inreader);
+    // data structures
+    content = new StringBuffer(1024);
+    char[] chars = new char[1024];
+    int length = 0;
+    // pull the data into the content buffer
+    while (length != -1) {
+      content.append(chars, 0, length);
+      length = in.read(chars, 0, chars.length);
+    }
+    // return
+    instream.close(); // john feb 16
+    inreader.close(); // john feb 16
+    in.close(); // john feb 16
+    return content.toString();
+  }
+
+  /**
+   * Loads any properties that might be in a given String.
+   */
+  public static Properties getResponseProperties(String string)
+      throws IOException {
+    Properties props;
+    ByteArrayInputStream in;
+    byte[] bytes;
+    props = new Properties();
+    bytes = string.getBytes();
+    in = new ByteArrayInputStream(bytes);
+    props.load(in);
+    in.close();
+    return props;
+  }
+
+  /**
+   * One shot method to get Properties directly from a URLConnection.
+   */
+  public static Properties getResponseProperties(URLConnection connection)
+      throws IOException {
+    Properties props;
+    String input;
+    input = getResponse(connection);
+    props = getResponseProperties(input);
+    return props;
+  }
+
+  public static String toEncodedString(Properties args) {
+    StringBuffer buf = new StringBuffer();
+    Enumeration names = args.propertyNames();
+    while (names.hasMoreElements()) {
+      String name = (String) names.nextElement();
+      String value = args.getProperty(name);
+      buf.append(URLEncoder.encode(name)).append("=")
+          .append(URLEncoder.encode(value));
+      if (names.hasMoreElements())
+        buf.append("&");
+    }
+    return buf.toString();
+  }
+
+  public static URLConnection sendPostData(Properties p, URL url)
+      throws IOException {
+    TestUtil.logMsg("Openning url connection to: " + url.toString());
+    URLConnection urlConn = url.openConnection();
+    // Begin POST of properties to SERVLET
+    String argString = TestUtil.toEncodedString(p);
+    urlConn.setDoOutput(true);
+    urlConn.setDoInput(true);
+    urlConn.setUseCaches(false);
+    DataOutputStream out = new DataOutputStream(urlConn.getOutputStream());
+    out.writeBytes(argString);
+    out.flush();
+    out.close();
+    // End POST
+    return urlConn;
+  }
+
+  /**
+   * Parse a the table name from the ddl string such as: "create table foo" or
+   * "delete from foo"
+   * 
+   * @param value
+   *          buffer to parse
+   * @return The name of the table
+   */
+  public static String getTableName(String value) {
+    String tableName = "";
+    if (value != null) {
+      tableName = value.trim();
+      int pos = tableName.lastIndexOf(" ");
+      tableName = tableName.substring(pos + 1);
+    } else {
+      TestUtil.logMsg("Error: Null value passed for table Name");
+    }
+    return (tableName);
+  } // END -- getTableName
+
+  public static String srcToDist(String src) {
+    return replaceLastSrc(src, "dist");
+  }
+
+  public static String replaceLastSrc(String src, String replacement) {
+    // find last index of /src/, remove "src", then replace it with replacement
+    StringBuffer sbToConvert = new StringBuffer(src);
+    int iStart = src.lastIndexOf("src");
+    if (iStart != -1) {
+      if (harnessDebug) {
+        TestUtil.logHarnessDebug("Pre-converted src dir = " + sbToConvert);
+      }
+      sbToConvert.replace(iStart, iStart + 3, replacement);
+
+      if (harnessDebug) {
+        TestUtil.logHarnessDebug(
+            "Converted " + replacement + " dir = " + sbToConvert);
+      }
+    }
+    return sbToConvert.toString();
+  }
+
+  public static String getDistString() {
+    // we may need to default to src until we are ready to convert for good
+    return "dist";
+  }
+
+  public static String getRelativePath(String oldVal) {
+    if (oldVal == null) {
+      return oldVal;
+    }
+    String result = oldVal;
+    oldVal = oldVal.replace('\\', '/');
+    while (oldVal.endsWith("/")) {
+      oldVal = oldVal.substring(0, oldVal.length() - 1);
+    }
+    if (oldVal.endsWith("/src")) {
+      return result;
+    }
+    int pos = oldVal.indexOf("/src/");
+    if (pos == -1) {
+      pos = oldVal.indexOf("/dist/");
+      if (pos == -1) {
+        result = oldVal;
+      } else {
+        result = oldVal.substring(pos + 6); // len of '/dist/'
+      }
+    } else {
+      result = oldVal.substring(pos + 5);
+    }
+    return result;
+  }
+
+  // Convert the given string of key-value-pair into a properties object
+  //
+  // for example :
+  // DatabaseName=derbyDB:user=cts1:password=cts1:serverName=localhost:portNumber=1527
+  //
+  public static Properties strToProps(String strProps) {
+
+    logTrace("Props String = " + strProps);
+    Properties props = new Properties();
+    String strArray[] = strProps.split(":"); // Split the given string into
+                                             // array of key value pairs
+
+    for (String keyValuePair : strArray) {
+      String strArray2[] = keyValuePair.split("="); // Take the key value pair
+                                                    // and store it into
+                                                    // properties
+      logTrace("Setting property " + strArray2[0] + " = " + strArray2[1]);
+      props.setProperty(strArray2[0], strArray2[1]);
+    }
+
+    return props;
+
+  }
+
+  public static void printProperties(Properties props) {
+    Set<String> propertyNames = props.stringPropertyNames();
+    for (String key : propertyNames) {
+      logTrace(key + " = " + props.getProperty(key));
+    }
+  }
+
+}
+
+// ======================= end of class TestUtil ======================
+
+class Acceptor extends Thread {
+  ServerSocket serverSocket;
+
+  private Socket outputSocket = null;
+
+  public Acceptor(ServerSocket ss) {
+    serverSocket = ss;
+    this.start();
+  }
+
+  public void run() {
+    while (true) {
+      try {
+        outputSocket = serverSocket.accept();
+        new SocketReader(outputSocket);
+        // System.out.println("new connection!!!!!");
+      } catch (IOException ex) {
+        ex.printStackTrace();
+      }
+    }
+  }
+}
+
+class TestReportInfo implements Serializable {
+  public int iDebugLevel = TestUtil.NORMAL_OUTPUT_LEVEL;
+
+  public String sOutput = ""; // Constants.EMPTY_STRING;
+
+  public Throwable exception = null;
+
+  public int iStream = TestUtil.OUTPUT_STREAM;
+
+  public TestReportInfo(String output, int stream, int level, Throwable e) {
+    if (sOutput != null)
+      sOutput = output;
+    iDebugLevel = level;
+    exception = e;
+    iStream = stream;
+  }
+}
+
+class SocketReader extends Thread {
+  private Socket outputSocket = null;
+
+  public SocketReader(Socket s) {
+    outputSocket = s;
+    this.start();
+  }
+
+  public void run() {
+    ObjectInputStream objIn;
+    TestReportInfo tri = null;
+    try {
+      objIn = new ObjectInputStream(outputSocket.getInputStream());
+      // while((tri = (TestReportInfo)objIn.readObject()) != null)
+      while (true) {
+        tri = (TestReportInfo) objIn.readObject();
+        if (tri.iDebugLevel == TestUtil.DEBUG_OUTPUT_LEVEL) {
+          // System.out.println("about to call logTrace");
+          TestUtil.logTrace(tri.sOutput);
+        } else {
+          if (tri.iStream == TestUtil.ERROR_STREAM) {
+            if (tri.exception == null)
+              TestUtil.logErr(tri.sOutput);
+            else
+              TestUtil.logErr(tri.sOutput, tri.exception);
+            // System.out.println("about to call logErr");
+          } else // assume outputstream
+          {
+            // System.out.println("about to call logMsg");
+            TestUtil.logMsg(tri.sOutput);
+          }
+        }
+      }
+    } catch (EOFException e) {
+      // do nothing since the eof broke us out of the loop
+    } catch (ClassNotFoundException e) {
+      e.printStackTrace();
+    } catch (IOException e) {
+      e.printStackTrace();
+    }
+    // cleanup socket no matter what happens
+    /*
+     * try { outputSocket.close(); outputSocket = null; } catch(IOException e) {
+     * 
+     * }
+     */
+  }
+}
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template
new file mode 100644
index 0000000..5f08e7e
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/asyncinvoker/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+    <servlet>
+        <servlet-name>CTS_JAXRS_SPEC_CLIENT_ASYNC_INVOKER</servlet-name>
+        <servlet-class>servlet_adaptor</servlet-class>
+        <init-param>
+            <param-name>jakarta.ws.rs.Application</param-name>
+            <param-value>jakarta.ws.rs.tck.ee.rs.client.asyncinvoker.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTS_JAXRS_SPEC_CLIENT_ASYNC_INVOKER</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template
new file mode 100644
index 0000000..1a7f175
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/request/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2007, 2020 Oracle and/or its affiliates. All rights reserved.
+
+    This program and the accompanying materials are made available under the
+    terms of the Eclipse Public License v. 2.0, which is available at
+    http://www.eclipse.org/legal/epl-2.0.
+
+    This Source Code may also be made available under the following Secondary
+    Licenses when the conditions for such availability set forth in the
+    Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
+    version 2 with the GNU Classpath Exception, which is available at
+    https://www.gnu.org/software/classpath/license.html.
+
+    SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
+
+-->
+
+<web-app version="5.0" xmlns="https://jakarta.ee/xml/ns/jakartaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd">
+    <servlet>
+        <servlet-name>CTSJAX-RSCOREREQUEST</servlet-name>
+        <servlet-class>servlet_adaptor</servlet-class>
+        <init-param>
+            <param-name>jakarta.ws.rs.Application</param-name>
+            <param-value>jakarta.ws.rs.tck.ee.rs.core.request.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAX-RSCOREREQUEST</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+</web-app>
diff --git a/jersey-tck/pom.xml b/jersey-tck/pom.xml
index 1699011..b53bcad 100644
--- a/jersey-tck/pom.xml
+++ b/jersey-tck/pom.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" ?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.glassfish.jersey.core</groupId>
@@ -11,16 +12,28 @@
     <description>This test verifies the compliance of Eclipse Jersey with Jakarta REST</description>
 
     <properties>
-        <maven.compiler.source>1.8</maven.compiler.source>
-        <maven.compiler.target>1.8</maven.compiler.target>
+        <maven.compiler.source>11</maven.compiler.source>
+        <maven.compiler.target>11</maven.compiler.target>
+        <jersey.version>3.0.0</jersey.version>
+        <glassfish.container.version>6.1.0</glassfish.container.version>
+        <jakarta.platform.version>9.1.0</jakarta.platform.version>
+        <junit.jupiter.version>5.7.2</junit.jupiter.version>
+        <jakarta.rest.version>3.0.0</jakarta.rest.version>
     </properties>
 
     <dependencyManagement>
         <dependencies>
             <dependency>
+                <groupId>org.junit</groupId>
+                <artifactId>junit-bom</artifactId>
+                <version>${junit.jupiter.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+            <dependency>
                 <groupId>org.glassfish.jersey</groupId>
                 <artifactId>jersey-bom</artifactId>
-                <version>3.0.0</version>
+                <version>${jersey.version}</version>
                 <type>pom</type>
                 <scope>import</scope>
             </dependency>
@@ -29,6 +42,18 @@
 
     <dependencies>
         <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2-locator</artifactId>
+            <version>3.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.jboss.arquillian.container</groupId>
+            <artifactId>arquillian-glassfish-managed-6</artifactId>
+            <version>1.0.0.Alpha1</version>
+        </dependency>
+
+        <dependency>
             <groupId>jakarta.ws.rs</groupId>
             <artifactId>jakarta.ws.rs-tck</artifactId>
             <version>3.1-SNAPSHOT</version>
@@ -36,24 +61,38 @@
         </dependency>
 
         <dependency>
-            <groupId>org.glassfish.jersey.inject</groupId>
-            <artifactId>jersey-hk2</artifactId>
-            <scope>test</scope>
+            <groupId>org.glassfish.main.common</groupId>
+            <artifactId>simple-glassfish-api</artifactId>
+            <version>${glassfish.container.version}</version>
         </dependency>
 
         <dependency>
-            <groupId>org.glassfish.jersey.core</groupId>
-            <artifactId>jersey-server</artifactId>
-            <scope>test</scope>
+            <groupId>org.jboss.arquillian.junit5</groupId>
+            <artifactId>arquillian-junit5-container</artifactId>
+            <version>1.7.0.Alpha10</version>
         </dependency>
 
         <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-grizzly2-http</artifactId>
-            <scope>test</scope>
+            <groupId>jakarta.platform</groupId>
+            <artifactId>jakarta.jakartaee-api</artifactId>
+            <version>${jakarta.platform.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-httpclient</groupId>
+            <artifactId>commons-httpclient</artifactId>
+            <version>3.1</version>
         </dependency>
     </dependencies>
 
+
+    <profiles>
+        <profile>
+            <id>arq-glassfish-managed</id>
+        </profile>
+    </profiles>
+
     <build>
         <plugins>
             <plugin>
@@ -67,6 +106,136 @@
                         </goals>
                         <configuration>
                             <dependenciesToScan>jakarta.ws.rs:jakarta.ws.rs-tck</dependenciesToScan>
+                            <systemPropertyVariables>
+                                <GLASSFISH_HOME>${project.build.directory}/glassfish6</GLASSFISH_HOME>
+                                <servlet_adaptor>org.glassfish.jersey.servlet.ServletContainer</servlet_adaptor>
+                                <webServerHost>localhost</webServerHost>
+                                <webServerPort>8080</webServerPort>
+                                <junit.log.traceflag>true</junit.log.traceflag>
+                                <porting.ts.url.class.1>jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL</porting.ts.url.class.1>
+                            </systemPropertyVariables>
+                            <environmentVariables>
+                                <GLASSFISH_HOME>${project.build.directory}/glassfish6</GLASSFISH_HOME>
+                            </environmentVariables>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.2.0</version>
+                <executions>
+                    <execution>
+                        <id>unpack</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>unpack</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.glassfish.main.distributions</groupId>
+                                    <artifactId>glassfish</artifactId>
+                                    <version>${glassfish.container.version}</version>
+                                    <type>zip</type>
+                                    <overWrite>false</overWrite>
+                                    <outputDirectory>${project.build.directory}</outputDirectory>
+                                </artifactItem>
+                            </artifactItems>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>copy</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>copy</goal>
+                        </goals>
+                        <configuration>
+                            <artifactItems>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-client</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-client.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-server</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-server.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.core</groupId>
+                                    <artifactId>jersey-common</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-common.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-grizzly2-http</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-grizzly2-http.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-servlet-core</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-servlet-core.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.containers</groupId>
+                                    <artifactId>jersey-container-servlet</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-container-servlet.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.media</groupId>
+                                    <artifactId>jersey-media-sse</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-media-sse.jar</destFileName>
+                                </artifactItem>
+                                <artifactItem>
+                                    <groupId>org.glassfish.jersey.media</groupId>
+                                    <artifactId>jersey-media-json-binding</artifactId>
+                                    <version>${jersey.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jersey-media-json-binding.jar</destFileName>
+                                </artifactItem>
+                                 <artifactItem>
+                                    <groupId>jakarta.ws.rs</groupId>
+                                    <artifactId>jakarta.ws.rs-api</artifactId>
+                                    <version>${jakarta.rest.version}</version>
+                                    <type>jar</type>
+                                    <overWrite>true</overWrite>
+                                    <outputDirectory>${project.build.directory}/glassfish6/glassfish/modules</outputDirectory>
+                                    <destFileName>jakarta.ws.rs-api.jar</destFileName>
+                                </artifactItem>
+                            </artifactItems>
                         </configuration>
                     </execution>
                 </executions>
