diff --git a/jaxrs-tck/pom.xml b/jaxrs-tck/pom.xml
index 16e7867..5119ba6 100644
--- a/jaxrs-tck/pom.xml
+++ b/jaxrs-tck/pom.xml
@@ -153,7 +153,11 @@
             <version>2.0.1</version>
         </dependency>
 
-
+        <dependency>
+            <groupId>jakarta.validation</groupId>
+            <artifactId>jakarta.validation-api</artifactId>
+            <version>3.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/client/clientrequestcontext/ContextProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/ContextProvider.java
new file mode 100644
index 0000000..742c11d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/ContextProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ContextProvider implements ClientRequestFilter {
+
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    throw new Fault("this TCK method is not implemented yet");
+  }
+
+  @Override
+  public void filter(ClientRequestContext context) throws IOException {
+    try {
+      checkFilterContext(context);
+    } catch (Fault e) {
+      throw new IOException(e);
+    }
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java
new file mode 100644
index 0000000..153725a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesIsImmutableProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+/**
+ * Counter should remain the same as any change would suggest that the
+ * getPropertyNames collection is not immutable
+ */
+public class GetPropertyNamesIsImmutableProvider extends ContextProvider {
+  private AtomicInteger counter;
+
+  public static final String NEWNAME = "AnyNewNameAddedToPropertyNames";
+
+  public GetPropertyNamesIsImmutableProvider(AtomicInteger counter) {
+    super();
+    this.counter = counter;
+  }
+
+  @Override
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    Collection<String> properties = context.getPropertyNames();
+    try {
+      properties.add(NEWNAME);
+    } catch (Exception e) {
+      // any possible exception here is ok as collection should be
+      // immutable
+    }
+    properties = context.getPropertyNames();
+    if (properties.contains(NEWNAME))
+      counter.set(counter.get() + 100);
+    context.abortWith(Response.ok(counter.get()).build());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java
new file mode 100644
index 0000000..0ea80fc
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetPropertyNamesProvider.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.Collection;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class GetPropertyNamesProvider extends ContextProvider {
+  private AtomicInteger counter;
+
+  public GetPropertyNamesProvider(AtomicInteger counter) {
+    super();
+    this.counter = counter;
+  }
+
+  @Override
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    if (counter.incrementAndGet() == 2) {
+      Collection<String> properties = context.getPropertyNames();
+      String entity = properties == null ? "NULL"
+          : JaxrsUtil.iterableToString(";", properties);
+      Response r = Response.ok(entity).build();
+      context.abortWith(r);
+    } else {
+      context.setProperty("PROPERTY1", "value1");
+      context.setProperty("PROPERTY2", "value2");
+    }
+  }
+
+  protected static <T> String collectionToString(Collection<T> collection) {
+    StringBuilder sb = new StringBuilder();
+    for (T t : collection)
+      sb.append(t).append(";");
+    return sb.toString();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java
new file mode 100644
index 0000000..56ae44a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/GetSetPropertyProvider.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class GetSetPropertyProvider extends ContextProvider {
+  private AtomicInteger counter;
+
+  public GetSetPropertyProvider(AtomicInteger counter) {
+    super();
+    this.counter = counter;
+  }
+
+  @Override
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    Object property = context.getProperty("PROPERTY");
+    String entity = property == null ? "NULL" : property.toString();
+    if (counter.incrementAndGet() == 2) {
+      Response r = Response.ok(entity).build();
+      context.abortWith(r);
+    } else
+      context.setProperty("PROPERTY", "value");
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java
new file mode 100644
index 0000000..3686107
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/JAXRSClient.java
@@ -0,0 +1,1485 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.io.ByteArrayInputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+import jakarta.ws.rs.tck.common.provider.StringBeanWithAnnotation;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.GenericEntity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.Variant;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ *                     ts_home;
+ */
+public class JAXRSClient extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = 8883841555516513076L;
+
+  /**
+   * Entry point for different-VM execution. It should delegate to method
+   * run(String[], PrintWriter, PrintWriter), and this method should not contain
+   * any test configuration.
+   */
+  // public static void main(String[] args) {
+  //   new JAXRSClient().run(args);
+  // }
+
+  /* Run test */
+
+  /*
+   * @testName: abortWithTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:427; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Abort the filter chain with a response. This method breaks
+   * the filter chain processing and returns the provided response back to the
+   * client. The provided response goes through the chain of applicable response
+   * filters.
+   * 
+   * ClientRequestFilter.filter ClientRequestFilter.abortWith
+   */
+  public void abortWithTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Response r = Response.status(Status.CREATED).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation i = buildInvocation(provider);
+    Response r = invoke(i);
+    assertStatus(r, Status.CREATED);
+  }
+
+  /*
+   * @testName: getAcceptableLanguagesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a list of languages that are acceptable for the
+   * response. Returns: a read-only list of acceptable languages sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.filter ClientRequestFilter.abortWith
+   */
+  public void getAcceptableLanguagesTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<Locale> locales = context.getAcceptableLanguages();
+        String languages = JaxrsUtil.iterableToString(";", locales);
+        Response r = Response.ok(languages).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation.Builder builder = buildBuilder(provider);
+    Invocation invocation;
+    invocation = builder.acceptLanguage(Locale.CANADA_FRENCH)
+        .acceptLanguage(Locale.PRC).buildGet();
+    Response response = invoke(invocation);
+    String entity = response.readEntity(String.class);
+    assertContains(entity, Locale.CANADA_FRENCH.toString());
+    assertContains(entity, Locale.PRC.toString());
+  }
+
+  /*
+   * @testName: getAcceptableLanguagesByWeightsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: a read-only list of requested response media types sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.filter ClientRequestFilter.abortWith
+   */
+  public void getAcceptableLanguagesByWeightsTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<Locale> locales = context.getAcceptableLanguages();
+        String languages = JaxrsUtil.iterableToString(";", locales);
+        Response r = Response.ok(languages).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation.Builder builder = buildBuilder(provider);
+    Invocation invocation;
+    invocation = builder.acceptLanguage("da, en-gb;q=0.6, en-us;q=0.7")
+        .buildGet();
+    Response response = invoke(invocation);
+    String entity = response.readEntity(String.class).toLowerCase();
+    assertContains(entity, "da");
+    assertContains(entity, "gb");
+    assertContains(entity, "us");
+    int indexDa = entity.indexOf("da");
+    int indexUs = entity.indexOf("us");
+    int indexGb = entity.indexOf("gb");
+
+    assertTrue(indexDa < indexUs && indexUs < indexGb,
+        "List of acceptable languages"+ entity+ "is not sorted by q values");
+  }
+
+  /*
+   * @testName: getAcceptableLanguagesIsImmutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:428; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: a read-only list of requested response media types sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getAcceptableLanguagesIsImmutableTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<Locale> locales = context.getAcceptableLanguages();
+        try {
+          locales.add(Locale.JAPAN);
+        } catch (Exception e) {
+          // either exception is thrown, or add does nothing
+        }
+        locales = context.getAcceptableLanguages();
+        boolean b = locales.contains(Locale.JAPAN);
+        assertTrue(!b, "getAcceptableLanguages is not read-only");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    WebTarget target = buildTarget(provider);
+    Invocation.Builder builder = target.request();
+    Invocation invocation;
+    invocation = builder
+        .header("Accept-Language", "da, en-gb;q=0.6, en-us;q=0.7").buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getAcceptableMediaTypesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a list of media types that are acceptable for the
+   * response. Returns a read-only list of requested response media types sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getAcceptableMediaTypesTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<MediaType> types = context.getAcceptableMediaTypes();
+        String medias = JaxrsUtil.iterableToString(";", types);
+        Response r = Response.ok(medias).build();
+        context.abortWith(r);
+      }
+    };
+    String media = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5";
+    Invocation.Builder builder = buildBuilder(provider);
+    Invocation invocation = builder.header("Accept", media).buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "text/*");
+    assertContains(entity, "text/html");
+    assertContains(entity, "*/*");
+  }
+
+  /*
+   * @testName: getAcceptableMediaTypesIsSortedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a list of media types that are acceptable for the
+   * response. Returns a read-only list of requested response media types sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getAcceptableMediaTypesIsSortedTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<MediaType> types = context.getAcceptableMediaTypes();
+        String medias = JaxrsUtil.iterableToString(";", types);
+        Response r = Response.ok(medias).build();
+        context.abortWith(r);
+      }
+    };
+    String media = "text/plain;q=0.3, text/html;q=0.7, text/xml;level=1, text/java;level=2;q=0.4, */*;q=0.5";
+    Invocation.Builder builder = buildBuilder(provider);
+    Invocation invocation = builder.header("Accept", media).buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class).toLowerCase();
+    int indexXml = entity.indexOf(MediaType.TEXT_XML);
+    int indexHtml = entity.indexOf(MediaType.TEXT_HTML);
+    int indexAny = entity.indexOf(MediaType.WILDCARD);
+    int indexJava = entity.indexOf("text/java");
+    int indexPlain = entity.indexOf(MediaType.TEXT_PLAIN);
+
+    assertTrue(indexXml < indexHtml && indexHtml < indexAny
+        && indexAny < indexJava && indexJava < indexPlain, "Media Types"+
+        entity+ "are not sorted");
+  }
+
+  /*
+   * @testName: getAcceptableMediaTypesIsImmutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:429; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a list of media types that are acceptable for the
+   * response. Returns a read-only list of requested response media types sorted
+   * according to their q-value, with highest preference first.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getAcceptableMediaTypesIsImmutableTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        List<MediaType> types = context.getAcceptableMediaTypes();
+        try {
+          types.add(MediaType.APPLICATION_JSON_TYPE);
+        } catch (Exception e) {
+          // either exception is thrown or add does nothing
+        }
+        types = context.getAcceptableMediaTypes();
+        boolean b = types.contains(MediaType.APPLICATION_JSON_TYPE);
+        assertTrue(!b, "getAcceptableMediaTypes is not read only");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    String media = "text/*;q=0.3, text/html;q=0.7, text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5";
+    Invocation.Builder builder = buildBuilder(provider);
+    Invocation invocation = builder.header("Accept", media).buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getClientTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:430; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the client instance associated with the request.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getClientTest() throws Fault {
+    final Client client = ClientBuilder.newClient();
+
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Client contextClient = context.getClient();
+        assertTrue(client == contextClient,
+            "the client instance is different from the context one");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    client.register(provider);
+    WebTarget target = client.target(getUrl());
+    Invocation invocation = target.request().buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getConfigurationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:977; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the immutable configuration of the request.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getConfigurationTest() throws Fault {
+    final Client client = ClientBuilder.newClient();
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Client contextClient = context.getClient();
+        assertEquals(contextClient, client,
+            "the client instance is different from the context one");
+        Configuration contextConfig = context.getConfiguration();
+        assertNotNull(contextConfig,
+            "context.getConfiguration() returned null");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    client.register(provider);
+    WebTarget target = client.target(getUrl());
+    Invocation invocation = target.request().buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getCookiesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:432; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get any cookies that accompanied the request. Returns a
+   * read-only map of cookie name (String) to Cookie.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getCookiesTest() throws Fault {
+    Cookie cts = new Cookie("cts", "cts");
+    Cookie tck = new Cookie("tck", "tck");
+    Cookie jee = new Cookie("jee", "jee");
+
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        String cookies = JaxrsUtil.iterableToString(";",
+            context.getCookies().values());
+        Response r = Response.ok(cookies).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).cookie(cts).cookie(tck)
+        .cookie(jee).buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "cts");
+    assertContains(entity, "tck");
+    assertContains(entity, "jee");
+  }
+
+  /*
+   * @testName: getCookiesIsImmutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:432; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get any cookies that accompanied the request. Returns a
+   * read-only map of cookie name (String) to Cookie.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getCookiesIsImmutableTest() throws Fault {
+    final Cookie cts = new Cookie("cts", "cts");
+
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Map<String, Cookie> cookies = context.getCookies();
+        try {
+          cookies.put("test", cts);
+        } catch (Exception e) {
+          // either exception is thrown or put does nothing
+        }
+        cookies = context.getCookies();
+        Cookie cookie = cookies.get("test");
+        assertTrue(cookie == null, "getCookies is not read-only");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).cookie(cts).buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getDateNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:433; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get message date. Returns: the message date, otherwise null
+   * if not present.
+   *
+   * ClientRequestFilter.abortWith
+   */
+  public void getDateNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Date date = context.getDate();
+        Response r = Response.ok(date == null ? "NULL" : date.toString())
+            .build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildInvocation(provider);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "NULL");
+  }
+
+  /*
+   * @testName: getDateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:433; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get message date. Returns: the message date, otherwise null
+   * if not present.
+   *
+   * ClientRequestFilter.abortWith
+   */
+  public void getDateTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Date date = context.getDate();
+        Response r = Response.ok(date.toString()).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider)
+        .header("Date", "Tue, 15 Nov 1994 08:12:31 GMT").buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "Nov");
+    assertContains(entity, "1994");
+    assertContains(entity, "31");
+  }
+
+  /*
+   * @testName: getEntityNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:434; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the message entity Java instance. Returns null if the
+   * message does not contain an entity.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Object entity = context.getEntity();
+        Response r = Response.ok(entity == null ? "NULL" : entity.toString())
+            .build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildInvocation(provider);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "NULL");
+  }
+
+  /*
+   * @testName: getEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:434; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get the message entity Java instance. Returns null if the
+   * message does not contain an entity.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Object entity = context.getEntity();
+        Response r = Response.ok(entity.toString()).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> post = createEntity("test");
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "test");
+  }
+
+  /*
+   * @testName: getEntityAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the annotations attached to the entity. Note that the
+   * returned annotations array contains only those annotations explicitly
+   * attached to entity instance (such as the ones attached using
+   * Entity.Entity(Object, jakarta.ws.rs.core.MediaType,
+   * java.lang.annotation.Annotation[]) method).
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityAnnotationsTest() throws Fault {
+    Annotation[] annotations = ContextProvider.class.getAnnotations();
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Annotation[] annotations = context.getEntityAnnotations();
+        String first = annotations == null ? "NULL"
+            : annotations.length == 0 ? "0"
+                : annotations[0].annotationType().getName();
+        Response r = Response.ok(first).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> post = Entity.entity("test", MediaType.WILDCARD_TYPE,
+        annotations);
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, annotations[0].annotationType().getName());
+  }
+
+  /*
+   * @testName: getEntityAnnotationsIsNotTakenFromEntityClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the annotations attached to the entity. Note that the
+   * returned annotations array contains only those annotations explicitly
+   * attached to entity instance (such as the ones attached using
+   * Entity.Entity(Object, jakarta.ws.rs.core.MediaType,
+   * java.lang.annotation.Annotation[]) method). The entity instance annotations
+   * array does not include annotations declared on the entity implementation
+   * class or its ancestors.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityAnnotationsIsNotTakenFromEntityClassTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Annotation[] annotations = context.getEntityAnnotations();
+        String first = annotations == null ? "0"
+            : String.valueOf(annotations.length);
+        Response r = Response.ok(first).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<StringBeanWithAnnotation> post = createEntity(
+        new StringBeanWithAnnotation("test"));
+    Invocation invocation = buildTarget(provider)
+        .register(StringBeanEntityProvider.class).request().buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "0");
+  }
+
+  /*
+   * @testName: getEntityAnnotationsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:435; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the annotations attached to the entity.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityAnnotationsNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Annotation[] annotations = context.getEntityAnnotations();
+        String len = annotations == null ? "0"
+            : String.valueOf(annotations.length);
+        Response r = Response.ok(len).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> post = createEntity("test");
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "0");
+  }
+
+  /*
+   * @testName: getEntityClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:436; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the raw entity type information.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityClassTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Class<?> clazz = context.getEntityClass();
+        Response r = Response.ok(clazz.getName()).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<ByteArrayInputStream> post = createEntity(
+        new ByteArrayInputStream("test".getBytes()));
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, ByteArrayInputStream.class.getName());
+  }
+
+  /*
+   * @testName: getEntityClassListStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:436; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the raw entity type information.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityClassListStringTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Class<?> clazz = context.getEntityClass();
+        Response r = Response.ok(clazz.getName()).build();
+        context.abortWith(r);
+      }
+    };
+    List<String> list = new ArrayList<String>();
+    Entity<List<String>> post = createEntity(list);
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, ArrayList.class.getName());
+  }
+
+  /*
+   * @testName: getEntityTypeListStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:438; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the generic entity type information.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getEntityTypeListStringTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Type type = context.getEntityType();
+        String entity = type.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    List<String> list = new ArrayList<String>();
+    GenericEntity<List<String>> generic = new GenericEntity<List<String>>(
+        list) {
+    };
+    Entity<GenericEntity<List<String>>> post = createEntity(generic);
+    Invocation invocation = buildBuilder(provider).buildPost(post);
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, String.class.getName());
+  }
+
+  /*
+   * @testName: getHeadersTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:439; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the mutable request headers multivalued map.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getHeadersTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MultivaluedMap<String, Object> headers = context.getHeaders();
+        String entity = JaxrsUtil.iterableToString(";", headers.keySet());
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider)
+        .header("Accept", MediaType.TEXT_HTML).header("tck", "cts")
+        .header("Date", "Tue, 15 Nov 1994 08:12:31 GMT").buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "Accept");
+    assertContains(entity, "Date");
+    assertContains(entity, "tck");
+  }
+
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the mutable request headers multivalued map.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getHeadersIsMutableTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MultivaluedMap<String, Object> headers = context.getHeaders();
+        headers.add("Accept", MediaType.APPLICATION_JSON);
+
+        headers = context.getHeaders();
+        String entity = JaxrsUtil.iterableToString(";", headers.keySet());
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).buildGet();
+    Response response = invoke(invocation);
+
+    String entity = response.readEntity(String.class);
+    assertContains(entity, "Accept");
+  }
+
+  /*
+   * @testName: getHeaderStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a message header as a single string value.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getHeaderStringTest() throws Fault {
+    final String TCK = "cts";
+    final String DATE = "Tue, 15 Nov 1994 08:12:31 GMT";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        String value;
+        value = context.getHeaderString("tck");
+        assertContainsIgnoreCase(value, TCK, "The expected value", TCK,
+            "was not found, found", value, "instead");
+        value = context.getHeaderString("accept");
+        assertContainsIgnoreCase(value, MediaType.TEXT_HTML,
+            "The expected value", MediaType.TEXT_HTML, "was not found, found",
+            value, "instead");
+        value = context.getHeaderString("date");
+        assertContainsIgnoreCase(value, DATE, "The expected value", DATE,
+            "was not found, found", value, "instead");
+        Response r = Response.ok().build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider)
+        .header("Accept", MediaType.TEXT_HTML)
+        .header("tck", new StringBuffer().append(TCK)) // toString()
+        .header("Date", DATE).buildGet();
+    Response response = invoke(invocation);
+    assertStatus(response, Status.OK);
+  }
+
+  /*
+   * @testName: getHeaderStringUsingHeaderDelegateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:440; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a message header as a single string value. Each single
+   * header value is converted to String using a RuntimeDelegate.HeaderDelegate.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getHeaderStringUsingHeaderDelegateTest() throws Fault {
+    final String name = "BEAN";
+    final StringBean bean = new StringBean(name);
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        String value = context.getHeaderString(name);
+        Response r = Response.ok(value).build();
+        context.abortWith(r);
+      }
+    };
+    RuntimeDelegate original = RuntimeDelegate.getInstance();
+    RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(original));
+    try {
+      Invocation invocation = buildBuilder(provider).header(name, bean)
+          .buildGet();
+      Response response = invoke(invocation);
+      String body = response.readEntity(String.class);
+      assertContains(name.toLowerCase(), body.toLowerCase());
+    } finally {
+      RuntimeDelegate.setInstance(original);
+      StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+    }
+  }
+
+  /*
+   * @testName: getLanguageIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:441; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the language of the entity. Returns: the language of
+   * the entity or null if not specified
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getLanguageIsNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Locale lang = context.getLanguage();
+        String entity = lang == null ? "NULL" : lang.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> entity = createEntity("TEST");
+    Invocation invocation = buildBuilder(provider).buildPost(entity);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "NULL");
+  }
+
+  /*
+   * @testName: getLanguageTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:441; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the language of the entity. Returns: the language of
+   * the entity or null if not specified
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getLanguageTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Locale lang = context.getLanguage();
+        String entity = lang == null ? "NULL" : lang.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Locale locale = Locale.TRADITIONAL_CHINESE;
+    Variant variant = new Variant(MediaType.TEXT_XML_TYPE, locale, null);
+    Entity<String> entity = Entity.entity("TEST", variant);
+    Invocation invocation = buildBuilder(provider).buildPost(entity);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class).toLowerCase().replace('-',
+        '_');
+    assertContains(body, locale.toString().toLowerCase());
+  }
+
+  /*
+   * @testName: getMediaTypeIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:442; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the media type of the entity. Returns: the media type
+   * or null if not specified (e.g. there's no request entity).
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getMediaTypeIsNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MediaType media = context.getMediaType();
+        String entity = media == null ? "NULL" : media.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).buildGet();
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "NULL");
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:442; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the media type of the entity. Returns: the media type
+   * or null if not specified (e.g. there's no request entity).
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getMediaTypeTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MediaType media = context.getMediaType();
+        String entity = media == null ? "NULL" : media.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> entity = Entity.entity("TEST",
+        MediaType.APPLICATION_FORM_URLENCODED);
+    Invocation invocation = buildBuilder(provider).buildPost(entity);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, MediaType.APPLICATION_FORM_URLENCODED);
+  }
+
+  /*
+   * @testName: getMethodTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:443; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the request method.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getMethodTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        String method = context.getMethod();
+        Response r = Response.ok(method).build();
+        context.abortWith(r);
+      }
+    };
+    Entity<String> entity = createEntity("TEST");
+    Invocation invocation;
+    Response response;
+
+    for (String method : new String[] { "OPTIONS", "DELETE", "GET", "TRACE" }) {
+      invocation = buildBuilder(provider).build(method);
+      response = invoke(invocation);
+      String body = response.readEntity(String.class).toUpperCase();
+      assertContains(body, method);
+    }
+
+    for (String method : new String[] { "PUT", "POST" }) {
+      invocation = buildBuilder(provider).build(method, entity);
+      response = invoke(invocation);
+      String body = response.readEntity(String.class).toUpperCase();
+      assertContains(body, method);
+    }
+  }
+
+  /*
+   * @testName: getPropertyIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:444; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Returns the property with the given name registered in the
+   * current request/response exchange context, or null if there is no property
+   * by that name.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getPropertyIsNullTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        Object property = context.getProperty("PROPERTY");
+        String entity = property == null ? "NULL" : property.toString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).buildGet();
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "NULL");
+  }
+
+  /*
+   * @testName: getSetPropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:444; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+   * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Returns the property with the given name registered in the
+   * current request/response exchange context, or null if there is no property
+   * by that name.
+   * 
+   * Binds an object to a given property name in the current request/response
+   * exchange context.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getSetPropertyTest() throws Fault {
+    final AtomicInteger counter = new AtomicInteger(0);
+    ContextProvider provider = new GetSetPropertyProvider(counter);
+    ContextProvider provider2 = new GetSetPropertyProvider(counter) {
+    };
+
+    Invocation invocation = buildInvocation(provider, provider2);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "value");
+  }
+
+  /*
+   * @testName: getPropertyNamesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:978; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+   * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Returns an immutable collection containing the property
+   * names available within the context of the current request/response exchange
+   * context.
+   * 
+   * Binds an object to a given property name in the current request/response
+   * exchange context.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getPropertyNamesTest() throws Fault {
+    final AtomicInteger counter = new AtomicInteger(0);
+    ContextProvider provider = new GetPropertyNamesProvider(counter);
+    ContextProvider provider2 = new GetPropertyNamesProvider(counter) {
+    };
+
+    Invocation invocation = buildInvocation(provider, provider2);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "PROPERTY1");
+    assertContains(body, "PROPERTY2");
+  }
+
+  /*
+   * @testName: getPropertyNamesIsImmutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:978; JAXRS:JAVADOC:453; JAXRS:JAVADOC:455;
+   * JAXRS:JAVADOC:456; JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Returns an immutable collection containing the property
+   * names available within the context of the current request/response exchange
+   * context.
+   * 
+   * Binds an object to a given property name in the current request/response
+   * exchange context.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getPropertyNamesIsImmutableTest() throws Fault {
+    final AtomicInteger counter = new AtomicInteger(0);
+    ContextProvider provider = new GetPropertyNamesIsImmutableProvider(counter);
+
+    Invocation invocation = buildInvocation(provider);
+    Response response = invoke(invocation);
+    String body = response.readEntity(String.class);
+    assertEqualsInt(0, counter.get(),
+        "getPropertyNames collection is not immutable");
+    assertEquals("0", body, "getPropertyNames collection is not immutable");
+    logMsg("getPropertyNames is immutable as expected");
+  }
+
+  /*
+   * @testName: getStringHeadersTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a string view of header values associated with the
+   * message.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getStringHeadersTest() throws Fault {
+    final String TCK = "cts";
+    final String DATE = "Tue, 15 Nov 1994 08:12:31 GMT";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MultivaluedMap<String, String> map;
+        map = context.getStringHeaders();
+        StringBuilder value = new StringBuilder();
+        value.append(map.getFirst("Accept")).append(" ");
+        value.append(map.getFirst("tck")).append(" ");
+        value.append(map.getFirst("Date"));
+        Response r = Response.ok(value.toString()).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider)
+        .header("Accept", MediaType.TEXT_HTML).header("tck", TCK)
+        .header("Date", DATE).buildGet();
+    Response response = invoke(invocation);
+    String body = response.readEntity(String.class);
+    assertContains(body, MediaType.TEXT_HTML);
+    assertContains(body, TCK);
+    assertContains(body, DATE);
+  }
+
+  /*
+   * @testName: getStringHeadersReflectsTheUnderlayingMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a string view of header values associated with the
+   * message. Changes in the underlying headers map are reflected in this view.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getStringHeadersReflectsTheUnderlayingMapTest() throws Fault {
+    final String TCK = "cts";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        context.getHeaders().add(TCK, TCK);
+        MultivaluedMap<String, String> map;
+        map = context.getStringHeaders();
+        String value = map.getFirst(TCK);
+        Response r = Response.ok(value).build();
+        context.abortWith(r);
+      }
+    };
+    Invocation invocation = buildBuilder(provider).buildGet();
+    Response response = invoke(invocation);
+    String body = response.readEntity(String.class);
+    assertContains(body, TCK);
+  }
+
+  /*
+   * @testName: getStringHeadersUsingHeaderDelegateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:446; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get a string view of header values associated with the
+   * message. The method converts the non-string header values to strings using
+   * a RuntimeDelegate.HeaderDelegate
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getStringHeadersUsingHeaderDelegateTest() throws Fault {
+    final String TCK = "cts";
+    final StringBean bean = new StringBean(TCK);
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MultivaluedMap<String, String> map;
+        map = context.getStringHeaders();
+        StringBuilder value = new StringBuilder();
+        value.append(map.getFirst(TCK));
+        Response r = Response.ok(value.toString()).build();
+        context.abortWith(r);
+      }
+    };
+    RuntimeDelegate delegate = RuntimeDelegate.getInstance();
+    RuntimeDelegate.setInstance(new StringBeanRuntimeDelegate(delegate));
+    try {
+      Invocation invocation = buildBuilder(provider).header(TCK, bean)
+          .buildGet();
+      Response response = invoke(invocation);
+      String body = response.readEntity(String.class);
+      assertContains(body, TCK);
+    } finally {
+      RuntimeDelegate.setInstance(delegate);
+      StringBeanRuntimeDelegate.assertNotStringBeanRuntimeDelegate();
+    }
+  }
+
+  /*
+   * @testName: getUriTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:447; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Get the request URI.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void getUriTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        URI uri = context.getUri();
+        String entity = uri.toASCIIString();
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+
+    Invocation invocation = buildInvocation(provider);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, getUrl());
+  }
+
+  /*
+   * @testName: hasEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:448; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy: Check if there is an entity available in the request. The
+   * method returns true if the entity is present, returns false otherwise.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void hasEntityTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        boolean has = context.hasEntity();
+        String entity = String.valueOf(has);
+        Response r = Response.ok(entity).build();
+        context.abortWith(r);
+      }
+    };
+
+    Invocation invocation = buildInvocation(provider);
+    Response response = invoke(invocation);
+    String body = response.readEntity(String.class);
+    assertContains(body, "false");
+
+    Entity<String> entity = createEntity("TEST");
+    WebTarget target = buildTarget(provider);
+    invocation = target.request().buildPost(entity);
+    response = invoke(invocation);
+    body = response.readEntity(String.class);
+    assertContains(body, "true");
+  }
+
+  /*
+   * @testName: removePropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:449; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * JAXRS:SPEC:85; JAXRS:JAVADOC:427;
+   * 
+   * @test_Strategy:Removes a property with the given name from the current
+   * request/response exchange context. After removal, subsequent calls to
+   * getProperty(java.lang.String) to retrieve the property value will return
+   * null.
+   *
+   * ClientRequestFilter.abortWith
+   */
+  public void removePropertyTest() throws Fault {
+    final AtomicInteger counter = new AtomicInteger(0);
+    ContextProvider provider = new RemovePropertyProvider(counter);
+    ContextProvider provider2 = new RemovePropertyProvider(counter) {
+    };
+    ContextProvider provider3 = new RemovePropertyProvider(counter) {
+    };
+
+    Invocation invocation = buildInvocation(provider, provider2, provider3);
+    Response response = invoke(invocation);
+
+    String body = response.readEntity(String.class);
+    assertContains(body, "NULL");
+  }
+
+  /*
+   * @testName: setEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:450; JAXRS:JAVADOC:434; JAXRS:JAVADOC:435;
+   * JAXRS:JAVADOC:438; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Set a new response message entity. It is the callers
+   * responsibility to wrap the actual entity with
+   * jakarta.ws.rs.core.GenericEntity if preservation of its generic type is
+   * required.
+   * 
+   * ClientRequestFilter.abortWith
+   */
+  public void setEntityTest() throws Fault {
+    final AtomicInteger counter = new AtomicInteger(0);
+
+    ContextProvider provider = new SetEntityProvider(counter);
+    ContextProvider provider2 = new SetEntityProvider(counter) {
+    };
+
+    Entity<ByteArrayInputStream> entity = createEntity(
+        new ByteArrayInputStream("test".getBytes()));
+
+    WebTarget target = buildTarget(provider, provider2);
+    Invocation invocation = target.request().buildPost(entity);
+    Response response = invoke(invocation);
+
+    assertStatus(response, Status.OK);
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  /**
+   * Call given provider CheckContextFilter method
+   */
+  protected static Response invoke(Invocation i) throws Fault {
+    Response r = null;
+    try {
+      r = i.invoke();
+    } catch (Exception e) {
+      Object cause = e.getCause();
+      if (cause instanceof Fault)
+        throw (Fault) cause;
+      else
+        throw new Fault(e);
+    }
+    return r;
+  }
+
+  protected static Invocation buildInvocation(ContextProvider... provider) {
+    WebTarget target = buildTarget(provider);
+    Invocation i = target.request().buildGet();
+    return i;
+  }
+
+  protected static WebTarget buildTarget(ContextProvider... providers) {
+    Client client = ClientBuilder.newClient();
+    for (ContextProvider provider : providers)
+      client.register(provider);
+    WebTarget target = client.target(getUrl());
+    return target;
+  }
+
+  protected static Invocation.Builder buildBuilder(
+      ContextProvider... provider) {
+    Invocation.Builder builder = buildTarget(provider).request();
+    return builder;
+  }
+
+  protected static void assertStatus(Response r, Status status) throws Fault {
+    assertTrue(r.getStatus() == status.getStatusCode(), "Expected"+
+        status.getStatusCode()+ "got"+ r.getStatus());
+    TestUtil.logMsg("Found expected status: " + status.getStatusCode());
+  }
+
+  protected static void assertContains(String string, String substring)
+      throws Fault {
+    assertTrue(string.contains(substring), string+ "does NOT contain"+
+        substring+ ", it is:"+ string);
+    TestUtil.logMsg("Found expected substring: " + substring);
+  }
+
+  /**
+   * @return any possible url
+   */
+  protected static String getUrl() {
+    return "http://localhost:8080/404URL/";
+  }
+
+  protected <T> Entity<T> createEntity(T entity) {
+    return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java
new file mode 100644
index 0000000..be186e3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/RemovePropertyProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.Response;
+
+public class RemovePropertyProvider extends ContextProvider {
+  private AtomicInteger counter;
+
+  public RemovePropertyProvider(AtomicInteger counter) {
+    super();
+    this.counter = counter;
+  }
+
+  @Override
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    String propName = "PROPERTY";
+    switch (counter.incrementAndGet()) {
+    case 1:
+      Object property = context.getProperty(propName);
+      assertFault(property == null, "property already exist");
+      context.setProperty(propName, propName);
+      break;
+    case 2:
+      property = context.getProperty(propName);
+      assertFault(property != null, "property not exist");
+      context.removeProperty(propName);
+      break;
+    case 3:
+      property = context.getProperty(propName);
+      assertFault(property == null, "property already exist");
+      Response response = Response.ok("NULL").build();
+      context.abortWith(response);
+      break;
+    }
+  }
+
+  /**
+   * @param conditionTrue
+   * @param message
+   * @throws Fault
+   *           when conditionTrue is not met with message provided
+   */
+  protected static void //
+      assertFault(boolean conditionTrue, Object... message) throws Fault {
+    if (!conditionTrue) {
+      StringBuilder sb = new StringBuilder();
+      for (Object msg : message)
+        sb.append(msg).append(" ");
+      throw new Fault(sb.toString());
+    }
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java
new file mode 100644
index 0000000..376827e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/client/clientrequestcontext/SetEntityProvider.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.client.clientrequestcontext;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+public class SetEntityProvider extends ContextProvider {
+  private AtomicInteger counter;
+
+  protected Annotation anno1 = new GET() {
+    @Override
+    public Class<? extends Annotation> annotationType() {
+      return null;
+    }
+  };
+
+  protected Annotation anno2 = new POST() {
+    @Override
+    public Class<? extends Annotation> annotationType() {
+      return null;
+    }
+  };
+
+  protected Annotation[] annos = new Annotation[] { anno1, anno2 };
+
+  protected MediaType type = MediaType.MULTIPART_FORM_DATA_TYPE;
+
+  protected String entityName = "ENTITY";
+
+  public SetEntityProvider(AtomicInteger counter) {
+    super();
+    this.counter = counter;
+  }
+
+  /**
+   * This method expects the request with entity != String.class has been sent
+   * Also, the mediaType is MediaType.WILDCARD_TYPE
+   */
+  @Override
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    Object entity;
+    MediaType mtype;
+    Annotation[] annotations;
+    Type clz;
+    switch (counter.incrementAndGet()) {
+    case 1:
+      TestUtil.logMsg("Counter is 1");
+      // get
+      entity = context.getEntity();
+      mtype = context.getMediaType();
+      annotations = context.getEntityAnnotations();
+      clz = context.getEntityType();
+      // check
+      assertFault(entity != null, "there is no entity, yet");
+      assertFault(!entity.toString().equals(entityName),
+          "the fake entity was already set");
+      assertFault(annotations == null || annotations.length == 0,
+          "there are already annotations!");
+      assertFault(!mtype.equals(type), "fake MediaType is already set");
+      assertFault(clz != String.class, "String entity is already set");
+      // set
+      context.setEntity(entityName, annos, type);
+      break;
+    case 2:
+      TestUtil.logMsg("Counter is 2");
+      // get
+      entity = context.getEntity();
+      mtype = context.getMediaType();
+      annotations = context.getEntityAnnotations();
+      clz = context.getEntityType();
+      // check
+      assertFault(entity != null, "there is no entity set");
+      assertFault(entity.toString().equals(entityName),
+          "there is no fake entity set, yet");
+      assertFault(annotations.length == 2,
+          "the fake annotations were not set, yet");
+      assertFault(mtype.equals(type), "fake MediaType was not set, yet");
+      assertFault(clz == String.class, "String entity not set, yet");
+      // set
+      context.setEntity(entityName, annos, type);
+      Response response = Response.ok().build();
+      context.abortWith(response);
+      break;
+    }
+  }
+
+  /**
+   * @param conditionTrue
+   * @param message
+   * @throws Fault
+   *           when conditionTrue is not met with message provided
+   */
+  protected static void //
+      assertFault(boolean conditionTrue, Object message) throws Fault {
+    if (!conditionTrue) {
+      throw new Fault(message.toString());
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java
new file mode 100644
index 0000000..66ca227
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Assertable.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.WebTarget;
+
+public abstract class Assertable {
+  final static String[] LOCATION = { "Client", "WebTarget",
+      "Invocation.Builder", "Invocation" };
+
+  private int locationIndex = 0;
+
+  public abstract void check1OnClient(Client client) throws Fault;
+
+  public abstract void check2OnTarget(WebTarget target) throws Fault;
+
+  public void incrementLocation() {
+    locationIndex = (locationIndex + 1 == LOCATION.length) ? 0
+        : locationIndex + 1;
+  }
+
+  public String getLocation() {
+    return new StringBuilder().append("on ").append(LOCATION[locationIndex])
+        .append(" configuration").toString();
+  }
+
+  public static String getLocation(int index) {
+    return LOCATION[index];
+  }
+
+  public int getLocationIndex() {
+    return locationIndex;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java
new file mode 100644
index 0000000..d8d406e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/CallableProvider.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.Callable;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class CallableProvider
+    implements MessageBodyWriter<Callable<?>>, MessageBodyReader<Callable<?>> {
+
+  @Override
+  public long getSize(Callable<?> arg0, Class<?> arg1, Type arg2,
+      Annotation[] arg3, MediaType arg4) {
+    return arg0.toString().length();
+  }
+
+  @Override
+  public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return Callable.class.isAssignableFrom(arg0);
+  }
+
+  @Override
+  public void writeTo(Callable<?> arg0, Class<?> arg1, Type arg2,
+      Annotation[] arg3, MediaType arg4, MultivaluedMap<String, Object> arg5,
+      OutputStream arg6) throws IOException, WebApplicationException {
+    arg6.write(arg0.toString().getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return isWriteable(type, genericType, annotations, mediaType);
+  }
+
+  @Override
+  public Callable<?> readFrom(Class<Callable<?>> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, String> httpHeaders,
+      final InputStream entityStream)
+      throws IOException, WebApplicationException {
+    String content = null;
+    try {
+      content = JaxrsUtil.readFromStream(entityStream);
+      entityStream.close();
+    } catch (Exception e) {
+      content = "Error while reading Callable from InputStream";
+    }
+    return createCallable(content);
+  }
+
+  public static Callable<String> createCallable(final String content) {
+    Callable<String> callable = new Callable<String>() {
+      @Override
+      public String call() throws Exception {
+        return toString();
+      }
+
+      @Override
+      public String toString() {
+        return content;
+      }
+    };
+    return callable;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java
new file mode 100644
index 0000000..27e5b01
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/ConfigurableObject.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Configurable;
+
+/**
+ * Wraps Client, WebTarget and Invocation objects that have configuration()
+ * method
+ */
+public interface ConfigurableObject {
+
+  void config(Configurable<?> config);
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java
new file mode 100644
index 0000000..650cf11
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/FeatureReturningFalse.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+
+public class FeatureReturningFalse implements Feature {
+  @Override
+  public boolean configure(FeatureContext context) {
+    // false returning feature is not to be registered
+    return false;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java
new file mode 100644
index 0000000..d0cda9e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/JAXRSClient.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ *                     ts_home;
+ */
+public class JAXRSClient extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = -6880902064949040518L;
+
+  private int registeredClassesCnt = -1;
+
+  private int registeredInstancesCnt = -1;
+
+  /**
+   * Entry point for different-VM execution. It should delegate to method
+   * run(String[], PrintWriter, PrintWriter), and this method should not contain
+   * any test configuration.
+   */
+  // public static void main(String[] args) {
+  //   new JAXRSClient().run(args);
+  // }
+
+  /* Run test */
+
+  /*
+   * @testName: registerFeatureClassReturningFalseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:754;
+   * 
+   * @test_Strategy: Register a feature meta-provider to be instantiated and
+   * used in the scope of this configurable context.
+   * 
+   * Any subsequent registration attempts for a component type, for which a
+   * class or instance-based registration already exists in the system MUST be
+   * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+   * inform the user about the rejected registration.
+   */
+  public void registerFeatureClassReturningFalseTest() throws Fault {
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int cnt = config.getConfiguration().getClasses().size();
+        assertEqualsInt(cnt, 1 + registeredClassesCnt,
+            "unexpected number of registered classes found:", cnt,
+            getLocation());
+        logMsg("Found", cnt, "features");
+      }
+
+    };
+    Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+        FeatureReturningFalse.class };
+    checkConfig(assertable, classes);
+  }
+
+  /*
+   * @testName: registerFeatureClassReturningFalseWithPriorityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:755;
+   * 
+   * @test_Strategy: Register a feature meta-provider to be instantiated and
+   * used in the scope of this configurable context.
+   * 
+   * Any subsequent registration attempts for a component type, for which a
+   * class or instance-based registration already exists in the system MUST be
+   * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+   * inform the user about the rejected registration.
+   */
+  public void registerFeatureClassReturningFalseWithPriorityTest()
+      throws Fault {
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int cnt = config.getConfiguration().getClasses().size();
+        assertEqualsInt(cnt, 1 + registeredClassesCnt,
+            "unexpected number of registered classes found:", cnt,
+            getLocation());
+        logMsg("Found", cnt, "features");
+      }
+
+    };
+
+    Registrar registrar = new Registrar() {
+      int priority = 0;
+
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        config.register((Class<?>) registerable, ++priority);
+      }
+    };
+
+    Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+        FeatureReturningFalse.class };
+    checkConfig(registrar, assertable, classes);
+  }
+
+  /*
+   * @testName: registerFeatureInstanceReturningFalseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:758;
+   * 
+   * @test_Strategy: Register a feature. In case the registered provider is a
+   * client-side Feature feature, this object instantiates the feature and
+   * invokes the Feature#configure(FeatureContext) method and lets the feature
+   * update it's internal configuration state.
+   */
+  public void registerFeatureInstanceReturningFalseTest() throws Fault {
+    final Feature feature = new FeatureReturningFalse();
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int cnt = config.getConfiguration().getInstances().size();
+        assertEqualsInt(cnt, 1 + registeredInstancesCnt,
+            "unexpected number of registered instances found:", cnt,
+            getLocation());
+        logMsg("Found", cnt, "features");
+      }
+
+    };
+    Object[] features = new Object[] { feature, feature };
+    checkConfig(assertable, features);
+  }
+
+  /*
+   * @testName: registerClassContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: Register a feature meta-provider to be instantiated and
+   * used in the scope of this configurable context.
+   * 
+   * Any subsequent registration attempts for a component type, for which a
+   * class or instance-based registration already exists in the system MUST be
+   * rejected by the JAX-RS implementation and a warning SHOULD be raised to
+   * inform the user about the rejected registration.
+   */
+  public void registerClassContractsTest() throws Fault {
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int cnt = config.getConfiguration().getClasses().size();
+        assertEqualsInt(cnt, 1 + registeredClassesCnt,
+            "unexpected number of registered classes found:", cnt,
+            getLocation());
+        logMsg("Found", cnt, "features");
+      }
+
+    };
+
+    Registrar registrar = new Registrar() {
+      int priority = 0;
+
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        config.register((Class<?>) registerable, ++priority);
+      }
+    };
+
+    Class<?>[] classes = new Class<?>[] { FeatureReturningFalse.class,
+        FeatureReturningFalse.class };
+    checkConfig(registrar, assertable, classes);
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  /**
+   * Check on every possible setting of configuration by a Feature or a
+   * singleton
+   * 
+   */
+  protected void checkConfig(Assertable assertable, Object[] registerables)
+      throws Fault {
+    checkConfig(new Registrar(), assertable, registerables);
+  }
+
+  protected void checkConfig(Registrar registrar, Assertable assertable,
+      Object[] registerables) throws Fault {
+    Client client = ClientBuilder.newClient();
+    Configuration config = client.getConfiguration();
+    registeredClassesCnt = config.getClasses().size();
+    registeredInstancesCnt = config.getInstances().size();
+    logMsg("Already registered", registeredClassesCnt, "classes");
+    logMsg("Already registered", registeredInstancesCnt, "instances");
+
+    register(registrar, client, registerables[0]);
+    assertable.check1OnClient(client);
+    assertable.incrementLocation();
+
+    WebTarget target = client.target("http://tck.cts:888");
+    register(registrar, target, registerables[1]);
+    assertable.check2OnTarget(target);
+    assertable.incrementLocation();
+  }
+
+  protected void register(Registrar registrar, Configurable<?> config,
+      Object registerable) {
+    registrar.register(config, registerable);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java
new file mode 100644
index 0000000..efd796b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/Registrar.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.core.Configurable;
+
+/**
+ * We need the possibility to override the way the registerable is registered
+ * The default behavior is for single argument register method
+ */
+public class Registrar {
+  public void register(Configurable<?> config, Object registerable) {
+    if (registerable instanceof Class) // register(Class)
+      config.register((Class<?>) registerable);
+    else if (registerable instanceof String) // setProperty()
+      config.property((String) registerable, registerable);
+    else
+      // register(Object)
+      config.register(registerable);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java
new file mode 100644
index 0000000..3c4a76a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/core/configurable/SingleCheckAssertable.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.core.configurable;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+
+public abstract class SingleCheckAssertable extends Assertable {
+
+  protected abstract void check(Configurable<?> configurable) throws Fault;
+
+  @Override
+  public void check1OnClient(Client client) throws Fault {
+    check(client);
+  }
+
+  @Override
+  public void check2OnTarget(WebTarget target) throws Fault {
+    check(target);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java
new file mode 100644
index 0000000..d53401b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/ContextOperation.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+/**
+ * These annotations are to get them set in InterceptorBodyOne#setAnnotations()
+ */
+public enum ContextOperation {
+  GETANNOTATIONS, GETGENERICTYPE, GETMEDIATYPE, GETPROPERTY, GETPROPERTYNAMES, GETPROPERTYNAMESISREADONLY, GETTYPE, REMOVEPROPERTY, SETANNOTATIONS, SETANNOTATIONSNULL, SETGENERICTYPE, SETMEDIATYPE, SETPROPERTY, SETPROPERTYNULL, SETTYPE, IOEXCEPTION, WEBAPPLICATIONEXCEPTION
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java
new file mode 100644
index 0000000..18ae459
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InputStreamReaderProvider.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class InputStreamReaderProvider implements
+    MessageBodyReader<InputStreamReader>, MessageBodyWriter<InputStreamReader> {
+
+  @Override
+  public long getSize(InputStreamReader arg0, Class<?> arg1, Type arg2,
+      Annotation[] arg3, MediaType arg4) {
+    return InputStreamReader.class.getName().length();
+  }
+
+  @Override
+  public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return arg0 == InputStreamReader.class;
+  }
+
+  @Override
+  public void writeTo(InputStreamReader arg0, Class<?> arg1, Type arg2,
+      Annotation[] arg3, MediaType arg4, MultivaluedMap<String, Object> arg5,
+      OutputStream arg6) throws IOException, WebApplicationException {
+    String entity = JaxrsUtil.readFromReader(arg0);
+    arg0.close();
+    arg6.write(entity.getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return isWriteable(arg0, arg1, arg2, arg3);
+  }
+
+  @Override
+  public InputStreamReader readFrom(Class<InputStreamReader> arg0, Type arg1,
+      Annotation[] arg2, MediaType arg3, MultivaluedMap<String, String> arg4,
+      InputStream arg5) throws IOException, WebApplicationException {
+    return new InputStreamReader(arg5);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java
new file mode 100644
index 0000000..f7dbce8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyOne.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collection;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.InterceptorContext;
+
+public class InterceptorBodyOne<CONTEXT extends InterceptorContext>
+    extends TemplateInterceptorBody<CONTEXT> {
+
+  public void getAnnotations() {
+    Annotation[] annotations = context.getAnnotations();
+    setSeparatedEntity(";", annotations);
+  }
+
+  public void getGenericType() {
+    Type type = context.getGenericType();
+    String entity = null;
+    if (type instanceof Class)
+      entity = ((Class<?>) type).getName();
+    else
+      entity = type.toString();
+    setEntity(entity);
+  }
+
+  public void getMediaType() {
+    MediaType type = context.getMediaType();
+    setEntity(type);
+  }
+
+  public void getProperty() {
+    Object o = context.getProperty(PROPERTY);
+    setEntity(o == null ? NULL : ENTITY2);
+  }
+
+  public void getPropertyNames() {
+    for (int i = 0; i != 5; i++)
+      context.setProperty(PROPERTY + i, PROPERTY);
+  }
+
+  public void getPropertyNamesIsReadOnly() {
+    Collection<String> names = context.getPropertyNames();
+    int size = names.size();
+    for (int i = 0; i != 5; i++)
+      try {
+        names.add(PROPERTY + i);
+      } catch (Exception e) {
+        // exception is possible
+      }
+    names = context.getPropertyNames();
+    assertTrue(names.size() == size, "Unexpected property names", names);
+    setEntity(NULL);
+  }
+
+  public void getType() {
+    Class<?> type = context.getType();
+    setEntity(type.getName());
+  }
+
+  public void removeProperty() {
+    context.setProperty(PROPERTY, NULL);
+    assertTrue(NULL.equals(context.getProperty(PROPERTY)), PROPERTY,
+        "property not found");
+    context.removeProperty(PROPERTY);
+    Object o = context.getProperty(PROPERTY);
+    setEntity(o == null ? NULL : o.toString());
+  }
+
+  public void setAnnotations() {
+    Annotation[] annotations = ContextOperation.class.getAnnotations();
+    context.setAnnotations(annotations);
+    getAnnotations();
+  }
+
+  public void setAnnotationsNull() {
+    try {
+      context.setAnnotations(null);
+      setEntity(NULL);
+    } catch (NullPointerException e) {
+      setEntity(NPE);
+    }
+  }
+
+  public void setGenericType() {
+    byte[] array = new byte[0];
+    context.setGenericType(array.getClass());
+    getGenericType();
+  }
+
+  public void setMediaType() {
+    MediaType type = MediaType.APPLICATION_FORM_URLENCODED_TYPE;
+    context.setMediaType(type);
+    getMediaType();
+  }
+
+  public void setProperty() {
+    StringBuilder sb = new StringBuilder();
+    sb.append(ENTITY2);
+    context.setProperty(PROPERTY, NULL);
+    context.setProperty(PROPERTY, sb);
+  }
+
+  public void setPropertyNull() {
+    context.setProperty(ENTITY2, ENTITY2);
+    assertTrue(context.getProperty(ENTITY2) != null, "Property", ENTITY2,
+        "set but not found");
+    context.setProperty(ENTITY2, null);
+    String o = (String) context.getProperty(ENTITY2);
+    setEntity(o == null ? NULL : o);
+  }
+
+  public void setType() {
+    context.setType(InputStreamReader.class);
+    getType();
+  }
+
+  public void ioException() throws IOException {
+    throw new IOException(IOE);
+  }
+
+  public void webApplicationException() {
+    throw new WebApplicationException(
+        Response.status(Status.CONFLICT).entity(ENTITY2).build());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java
new file mode 100644
index 0000000..bb6a6eb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorBodyTwo.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.ext.InterceptorContext;
+
+public class InterceptorBodyTwo<CONTEXT extends InterceptorContext>
+    extends TemplateInterceptorBody<CONTEXT> {
+
+  @Override
+  protected Object operationMethodNotFound(String operation)
+      throws IOException {
+    return proceed();
+  }
+
+  public void getPropertyNames() {
+    Collection<String> names = context.getPropertyNames();
+    setEntity(JaxrsUtil.iterableToString(";", names));
+  }
+
+  public void setProperty() {
+    Object property = context.getProperty(PROPERTY);
+    if (property instanceof StringBuilder)
+      setEntity(property.toString());
+    else
+      setEntity(NULL);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java
new file mode 100644
index 0000000..78bf87e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/InterceptorCallbackMethods.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor;
+
+import java.io.IOException;
+
+/**
+ * Every InterceptorContext has different way to get header OPERATION, proceed,
+ * or write an entity to a response. Therefore, TemplateInterceptorBody is given
+ * the implementation of this interface so that it can abstractly call these
+ * methods no matter the given context.
+ * 
+ * It is passed as an argument to the only call-able method
+ * {@link TemplateInterceptorBody#executeMethod()}
+ */
+public interface InterceptorCallbackMethods {
+  void writeEntity(String entity);
+
+  Object proceed() throws IOException;
+
+  String getHeaderString();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java
new file mode 100644
index 0000000..039a772
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/TemplateInterceptorBody.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.ext.InterceptorContext;
+
+/**
+ * Body for both reader and writer interceptor body The body is injected into
+ * Template<Reader/Writer>Interceptor
+ * 
+ * @param <CONTEXT>
+ *          The context the body methods will use.
+ */
+public abstract class TemplateInterceptorBody<CONTEXT extends InterceptorContext> {
+  public static final String OPERATION = "OPERATION";
+
+  public static final String ENTITY = "Entity";
+
+  public static final String ENTITY2 = "Other Entity";
+
+  public static final String PROPERTY = "Property";
+
+  public static final String NULL = "None";
+
+  public static final String NPE = "NullPointerException has been thrown as expected";
+
+  public static final String IOE = "IOException has been thrown as expected";
+
+  public static final String WAE = "WebApplicationException has been thrown as expected";
+
+  protected CONTEXT context;
+
+  protected InterceptorCallbackMethods callback;
+
+  public Object executeMethod(CONTEXT context,
+      InterceptorCallbackMethods callback) throws IOException {
+    this.context = context;
+    this.callback = callback;
+    String operation = getHeaderString();
+    Method[] methods = getClass().getMethods();
+    for (Method method : methods)
+      if (operation.equalsIgnoreCase(method.getName())) {
+        try {
+          Object ret = method.invoke(this);
+          if (ret == null)
+            return proceed();
+          else
+            return ret; // the method ensures the call of proceed();
+        } catch (Exception e) {
+          if (IOException.class.isInstance(e.getCause()))
+            throw (IOException) e.getCause();
+          else if (e.getCause() instanceof RuntimeException)
+            throw (RuntimeException) e.getCause();
+          else
+            throwIOEAndLog(operation, e);
+        }
+      }
+    return operationMethodNotFound(operation);
+  }
+
+  private static void throwIOEAndLog(String operation, Throwable e)
+      throws IOException {
+    System.out.println("Error while invoking method " + operation);
+    e.printStackTrace();
+    throw new IOException(e);
+  }
+
+  protected Object operationMethodNotFound(String operation)
+      throws IOException {
+    throw new IOException("Operation " + operation + " not implemented");
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  protected void assertTrue(boolean conditionTrue, Object... msg) {
+    if (conditionTrue)
+      return;
+    StringBuilder sb = new StringBuilder();
+    if (msg != null)
+      for (Object str : msg)
+        sb.append(str).append(" ");
+    throw new RuntimeException(new IOException(sb.toString()));
+  }
+
+  protected <T> void setEntity(T... entity) {
+    setSeparatedEntity(" ", entity);
+  }
+
+  protected <T> void setSeparatedEntity(String separator, T... entity) {
+    String complete = JaxrsUtil.iterableToString(separator, entity);
+    writeEntity(complete);
+  }
+
+  protected void writeEntity(String entity) {
+    callback.writeEntity(entity);
+  }
+
+  protected Object proceed() throws IOException {
+    return callback.proceed();
+  }
+
+  protected String getHeaderString() {
+    return callback.getHeaderString();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java
new file mode 100644
index 0000000..06e5046
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/ReaderClient.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.Response;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ * 
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class ReaderClient<CONTEXTOPERATION extends Enum<?>>
+    extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 7145627888730121260L;
+
+  /**
+   * Create response to be faked as returned from server
+   */
+  protected Response.ResponseBuilder createResponse(CONTEXTOPERATION op) {
+    Response.ResponseBuilder builder = Response.ok()
+        .header(TemplateInterceptorBody.OPERATION, op.name())
+        .entity(TemplateInterceptorBody.ENTITY);
+    return builder;
+  }
+
+  /**
+   * Create a request filter to be aborted with given fake response simulating
+   * the resource from a request
+   * 
+   * @param response
+   * @return
+   */
+  protected static ClientRequestFilter createRequestFilter(
+      final Response response) {
+    ClientRequestFilter outFilter = new ClientRequestFilter() {
+
+      @Override
+      public void filter(ClientRequestContext context) throws IOException {
+        Response r;
+        if (response == null)
+          r = Response.ok().build();
+        else
+          r = response;
+        context.abortWith(r);
+      }
+    };
+    return outFilter;
+  }
+
+  /**
+   * Invoke and convert IOException to Fault
+   */
+  protected void invoke() throws Fault {
+    try {
+      setProperty(Property.REQUEST, buildRequest(Request.GET, "404URL/"));
+      super.invoke();
+    } catch (Exception cause) {
+      if (cause instanceof IOException)
+        throw new Fault(cause.getMessage());
+      else
+        throw new Fault(cause);
+    }
+  }
+
+  /**
+   * Register providers to client configuration
+   * 
+   * @param response
+   *          ClientRequestFilter#abortWith response
+   */
+  protected void addProviders(Response response) throws Fault {
+    ClientRequestFilter requestFilter = createRequestFilter(response);
+    addProvider(requestFilter);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java
new file mode 100644
index 0000000..a717918
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/TemplateReaderInterceptor.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptor;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+/**
+ * This class is a superclass for any interceptor @Provider. Any such provider
+ * is then given a body, inherited from TemplateInterceptorBody. The body
+ * actually contains methods with name equalIgnoreCase to ContextOperation items
+ * name, the name of the method executed is passed by http header OPERATION
+ * 
+ * @see TemplateInterceptorBody
+ * 
+ *      The injection of the body solves the issue with inheritance from two
+ *      super-classes.
+ */
+public abstract class TemplateReaderInterceptor
+    implements ReaderInterceptor, InterceptorCallbackMethods {
+
+  protected ReaderInterceptorContext readerCtx;
+
+  protected TemplateInterceptorBody<ReaderInterceptorContext> interceptorBody;
+
+  public TemplateReaderInterceptor(
+      TemplateInterceptorBody<ReaderInterceptorContext> interceptorBody) {
+    super();
+    this.interceptorBody = interceptorBody;
+  }
+
+  @Override
+  public Object aroundReadFrom(ReaderInterceptorContext ctx)
+      throws IOException, WebApplicationException {
+    this.readerCtx = ctx;
+    return interceptorBody.executeMethod(readerCtx, this);
+  }
+
+  @Override
+  public void writeEntity(String entity) {
+    readerCtx.setInputStream(new ByteArrayInputStream(entity.getBytes()));
+  }
+
+  @Override
+  public Object proceed() throws IOException {
+    return readerCtx.proceed();
+  }
+
+  @Override
+  public String getHeaderString() {
+    MultivaluedMap<String, String> headers = readerCtx.getHeaders();
+    return headers.getFirst(TemplateInterceptorBody.OPERATION);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java
new file mode 100644
index 0000000..3e6eedd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/JAXRSClient.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+
+import static org.junit.jupiter.api.Assertions.assertTrue;
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ *                     ts_home;
+ */
+public class JAXRSClient extends ReaderClient<ContextOperation> {
+
+  private static final long serialVersionUID = -8828149277776372718L;
+
+  /* Run test */
+  /*
+   * @testName: getAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation. The
+   * annotations are not on client reader.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getAnnotationsTest() throws Fault {
+    Annotation[] annotations = ContextOperation.class.getAnnotations();
+    ResponseBuilder builder = createResponse(ContextOperation.GETANNOTATIONS);
+    Response fake = builder.entity(TemplateInterceptorBody.ENTITY, annotations)
+        .build();
+    addProviders(fake);
+    for (Annotation a : annotations)
+      setProperty(Property.UNEXPECTED_RESPONSE_MATCH,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   * 
+   * If abortWith is invoked, execution is aborted
+   */
+  public void getGenericTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETGENERICTYPE);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get media type of HTTP entity.
+   *
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getMediaTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETMEDIATYPE);
+    Response fake = builder.type(MediaType.APPLICATION_JSON_TYPE).build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Returns null if there is no property by that name.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getPropertyIsNullTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETPROPERTY);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection collection
+   * containing the property names available within the context of the current
+   * request/response exchange context.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getPropertyNamesTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETPROPERTYNAMES);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    for (int i = 0; i != 5; i++)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          TemplateInterceptorBody.PROPERTY + i);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesIsReadOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection containing the
+   * property names available within the context of the current request/response
+   * exchange context.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getPropertyNamesIsReadOnlyTest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.GETPROPERTYNAMESISREADONLY);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get Java type supported by corresponding message body
+   * provider.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETTYPE);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: removePropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Removes a property with the given name from the current
+   * request/response exchange context. After removal, subsequent calls to
+   * getProperty(java.lang.String) to retrieve the property value will return
+   * null.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void removePropertyTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.REMOVEPROPERTY);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Update annotations on the formal declaration of the
+   * artifact that initiated the intercepted entity provider invocation.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setAnnotationsTest() throws Fault {
+    Annotation[] annotations = ReaderInterceptorOne.class.getAnnotations();
+    ResponseBuilder builder = createResponse(ContextOperation.SETANNOTATIONS);
+    Response fake = builder.build();
+    addProviders(fake);
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsNullThrowsNPETest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Throws NullPointerException - in case the input parameter
+   * is null.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setAnnotationsNullThrowsNPETest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.SETANNOTATIONSNULL);
+    Response fake = builder.entity(TemplateInterceptorBody.ENTITY).build();
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+    invoke();
+  }
+
+  /*
+   * @testName: setGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Update type of the object to be produced or written.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setGenericTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETGENERICTYPE);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, "[B");
+    invoke();
+  }
+
+  /*
+   * @testName: setMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Update media type of HTTP entity.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setMediaTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETMEDIATYPE);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Binds an object to a given property name in the current
+   * request/response exchange context. If the name specified is already used
+   * for a property, this method will replace the value of the property with the
+   * new value.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setPropertyTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETPROPERTY);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: If a null value is passed, the effect is the same as
+   * calling the removeProperty(String) method.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setPropertyNullTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETPROPERTYNULL);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Update Java type before calling message body provider.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setTypeTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETTYPE);
+    ByteArrayInputStream bais = new ByteArrayInputStream(
+        TemplateInterceptorBody.ENTITY.getBytes());
+    Reader reader = new InputStreamReader(bais);
+    Response fake = builder.entity(reader).build();
+
+    addProviders(fake);
+    addProvider(InputStreamReaderProvider.class);
+    invoke();
+    InputStreamReader isr = getResponseBody(InputStreamReader.class);
+    try {
+      String entity = JaxrsUtil.readFromReader(isr);
+      assertTrue(entity.contains(InputStreamReader.class.getName()),
+          "Expected"+ InputStreamReader.class.getName()+ "not found");
+      logMsg("#setType set correct type", entity);
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+  }
+
+  /*
+   * @testName: ioExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:921; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Throws IOException - if an IO error arises.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void ioExceptionTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.IOEXCEPTION);
+    Response fake = builder.build();
+    addProviders(fake);
+    invoke();
+    try {
+      getResponseBody();
+    } catch (Exception e) {
+      assertNotNull(e.getMessage(), "Returned unexpected exception", e);
+      IOException io = assertCause(e, IOException.class,
+          "Unexpected exception has been found:", e);
+      assertContains(io.getMessage(), TemplateInterceptorBody.IOE,
+          "Found unexpected message from IOException", e.getMessage());
+      logMsg("found expected IOException", io);
+      return;
+    }
+    fault("Expected IOException not found");
+  }
+
+  /*
+   * @testName: webApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:922; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: throws WebApplicationException thrown by wrapped method.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void webApplicationExceptionTest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.WEBAPPLICATIONEXCEPTION);
+    Response fake = builder.build();
+    addProviders(fake);
+    invoke();
+    try {
+      getResponseBody();
+    } catch (Exception e) {
+      WebApplicationException we = assertCause(e, WebApplicationException.class,
+          "Found unexpected exception", e);
+      assertNotNull(we.getResponse(),
+          "WebApplicationException.getResponse is null");
+      Response response = we.getResponse();
+      String entity = response.getEntity().toString();
+      assertEqualsInt(Status.CONFLICT.getStatusCode(), response.getStatus(),
+          "Unexcpected status returned from WebApplicationException.getResponse",
+          response.getStatus());
+      assertEquals(TemplateInterceptorBody.ENTITY2, entity,
+          "Found unexpected body content from WebApplicationException.getResponse",
+          entity);
+      logMsg("found expected WebApplicationException", we);
+      return;
+    }
+    fault("Expected WebApplicationException not found");
+  }
+
+  // /////////////////////////////////////////////////////////////////////
+  @Override
+  protected void addProviders(Response response) throws Fault {
+    super.addProviders(response);
+    addProvider(ReaderInterceptorTwo.class);
+    addProvider(new ReaderInterceptorOne());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java
new file mode 100644
index 0000000..9d270b6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorOne.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+@Provider
+@Priority(100)
+public class ReaderInterceptorOne extends TemplateReaderInterceptor {
+
+  public ReaderInterceptorOne() {
+    super(new InterceptorBodyOne<ReaderInterceptorContext>());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java
new file mode 100644
index 0000000..bbd968a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/interceptorcontext/ReaderInterceptorTwo.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+@Provider
+@Priority(200)
+public class ReaderInterceptorTwo extends TemplateReaderInterceptor {
+
+  public ReaderInterceptorTwo() {
+    super(new InterceptorBodyTwo<ReaderInterceptorContext>());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java
new file mode 100644
index 0000000..6fb82e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ContextOperation.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.reader.readerinterceptorcontext;
+
+public enum ContextOperation {
+  GETHEADERS, GETHEADERSISMUTABLE, GETINPUTSTREAM, PROCEEDTHROWSIOEXCEPTION, PROCEEDTHROWSWEBAPPEXCEPTION, SETINPUTSTREAM
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java
new file mode 100644
index 0000000..b5d799a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBean.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.WebApplicationException;
+
+public class ExceptionThrowingStringBean extends StringBean {
+
+  public ExceptionThrowingStringBean(String header) {
+    super(header);
+    if (!header.equals(TemplateInterceptorBody.WAE))
+      throw new WebApplicationException(new IOException(header));
+  }
+
+  public ExceptionThrowingStringBean(String header, boolean b) {
+    super(header);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java
new file mode 100644
index 0000000..5ee679c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ExceptionThrowingStringBeanEntityProvider.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ExceptionThrowingStringBeanEntityProvider
+    implements MessageBodyReader<ExceptionThrowingStringBean>,
+    MessageBodyWriter<ExceptionThrowingStringBean> {
+
+  @Override
+  public boolean isWriteable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return type == ExceptionThrowingStringBean.class;
+  }
+
+  @Override
+  public long getSize(ExceptionThrowingStringBean t, Class<?> type,
+      Type genericType, Annotation[] annotations, MediaType mediaType) {
+    return t.get().length();
+  }
+
+  @Override
+  public void writeTo(ExceptionThrowingStringBean t, Class<?> type,
+      Type genericType, Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, Object> httpHeaders, OutputStream entityStream)
+      throws IOException, WebApplicationException {
+    entityStream.write(t.get().getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return isWriteable(type, genericType, annotations, mediaType);
+  }
+
+  @Override
+  public ExceptionThrowingStringBean readFrom(
+      Class<ExceptionThrowingStringBean> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+      throws IOException, WebApplicationException {
+    String entity = JaxrsUtil.readFromStream(entityStream);
+    entityStream.close();
+    return new ExceptionThrowingStringBean(entity);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java
new file mode 100644
index 0000000..8fc8f0d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorOneBody.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+public class InterceptorOneBody
+    extends TemplateInterceptorBody<ReaderInterceptorContext> {
+
+  public void getHeaders() {
+    MultivaluedMap<String, String> headers = context.getHeaders();
+    setEntity(JaxrsUtil.iterableToString(";", headers.keySet()));
+  }
+
+  public void getHeadersIsMutable() {
+    MultivaluedMap<String, String> headers = context.getHeaders();
+    headers.add(PROPERTY, PROPERTY);
+  }
+
+  public void getInputStream() throws IOException {
+    InputStream stream = context.getInputStream();
+    String entity = JaxrsUtil.readFromStream(stream);
+    stream.close();
+    setEntity(entity);
+  }
+
+  public void proceedThrowsIOException() {
+    try {
+      context.proceed();
+      setEntity(NULL);
+    } catch (IOException ioe) {
+      setEntity(IOE);
+    }
+  }
+
+  public Object proceedThrowsWebAppException()
+      throws WebApplicationException, IOException {
+    Object proceedObject = new ExceptionThrowingStringBean(NULL, false);
+    try {
+      proceedObject = context.proceed();
+    } catch (WebApplicationException e) {
+      // Exception has been thrown, message body reader has read nothing
+      // hence we need to set expected value;
+      ((StringBean) proceedObject).set(WAE);
+    }
+    return proceedObject;
+  }
+
+  public void setInputStream() {
+    ByteArrayInputStream stream = new ByteArrayInputStream(NULL.getBytes());
+    context.setInputStream(stream);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java
new file mode 100644
index 0000000..c15be8d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/InterceptorTwoBody.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.ReaderInterceptorContext;
+
+public class InterceptorTwoBody
+    extends TemplateInterceptorBody<ReaderInterceptorContext> {
+  @Override
+  protected Object operationMethodNotFound(String operation)
+      throws IOException {
+    return proceed();
+  }
+
+  public void getHeadersIsMutable() {
+    MultivaluedMap<String, String> headers = context.getHeaders();
+    String first = headers.getFirst(PROPERTY);
+    setEntity(first == null ? NULL : PROPERTY);
+  }
+
+  public void proceedThrowsIOException() throws IOException {
+    throw new IOException("Interceptor#proceed IOException tck test");
+  }
+
+  public Object proceedThrowsWebAppException()
+      throws WebApplicationException, IOException {
+    return context.proceed();
+  }
+
+  public void setInputStream() throws IOException {
+    InputStream stream = context.getInputStream();
+    String entity = JaxrsUtil.readFromStream(stream);
+    setEntity(NULL.equals(entity) ? ENTITY2 : NULL);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java
new file mode 100644
index 0000000..45fa157
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/JAXRSClient.java
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ *                     ts_home;
+ */
+public class JAXRSClient extends ReaderClient<ContextOperation> {
+
+  private static final long serialVersionUID = -6962070973647934636L;
+
+  /* Run test */
+  /*
+   * @testName: getHeadersOperationSetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getHeadersOperationSetTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETHEADERS);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+        TemplateInterceptorBody.OPERATION);
+    invoke();
+  }
+
+  /*
+   * @testName: getHeadersHeadersSetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getHeadersHeadersSetTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.GETHEADERS);
+    for (int i = 0; i != 5; i++) {
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          TemplateInterceptorBody.PROPERTY + i);
+      builder = builder.header(TemplateInterceptorBody.PROPERTY + i, "any");
+    }
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setTextCaser(TextCaser.LOWER);
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        TemplateInterceptorBody.OPERATION);
+    invoke();
+  }
+
+  /* Run test */
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getHeadersIsMutableTest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.GETHEADERSISMUTABLE);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+    invoke();
+  }
+
+  /*
+   * @testName: getInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:924; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Get the input stream of the object to be read.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void getInputStreamTest() throws Fault {
+    String entity = "getInputStreamEntity";
+    ResponseBuilder builder = createResponse(ContextOperation.GETINPUTSTREAM);
+    Response fake = builder.entity(entity).build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, entity);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsIOExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:926; JAXRS:JAVADOC:920;
+   * JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Throws: IOException - if an IO error arises
+   * 
+   * Proceed is tested in any of the interceptor tests.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void proceedThrowsIOExceptionTest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:1008; JAXRS:JAVADOC:920;
+   * JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Throws: WebApplicationException - thrown by the wrapped
+   * {@code MessageBodyReader.readFrom} method.
+   * 
+   * Proceed is tested in any of the intercepter tests.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+    ResponseBuilder builder = createResponse(
+        ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+    Response fake = builder.build();
+    addProviders(fake);
+    addProvider(ExceptionThrowingStringBeanEntityProvider.class);
+    invoke();
+    // Exception thrown, caught in InterceptorBodyOne
+    StringBean bean = getResponseBody(ExceptionThrowingStringBean.class);
+    //
+    assertContains(bean.get(), TemplateInterceptorBody.WAE,
+        "WebApplicationException has not been thrown and the message is",
+        bean.get());
+    logMsg("WebApplicationException has been thrown as expected", bean.get());
+  }
+
+  /*
+   * @testName: setInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:927; JAXRS:JAVADOC:920; JAXRS:SPEC:85;
+   * 
+   * @test_Strategy: Update the input stream of the object to be read.
+   * 
+   * ReaderInterceptor.aroundReadFrom If abortWith is invoked, execution is
+   * aborted
+   */
+  public void setInputStreamTest() throws Fault {
+    ResponseBuilder builder = createResponse(ContextOperation.SETINPUTSTREAM);
+    Response fake = builder.build();
+
+    addProviders(fake);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke();
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  /**
+   * Do not forget to register providers
+   */
+  @Override
+  protected void addProviders(Response response) throws Fault {
+    super.addProviders(response);
+    addProvider(ReaderInterceptorTwo.class);
+    addProvider(ReaderInterceptorOne.class);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java
new file mode 100644
index 0000000..79badd9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorOne.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class ReaderInterceptorOne extends TemplateReaderInterceptor {
+
+  public ReaderInterceptorOne() {
+    super(new InterceptorOneBody());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java
new file mode 100644
index 0000000..82c7104
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/api/rs/ext/interceptor/reader/readerinterceptorcontext/ReaderInterceptorTwo.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class ReaderInterceptorTwo extends TemplateReaderInterceptor {
+
+  public ReaderInterceptorTwo() {
+    super(new InterceptorTwoBody());
+  }
+
+}
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
index f69dd67..e41d223 100644
--- 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
@@ -677,8 +677,6 @@
    * @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)   {
@@ -694,13 +692,11 @@
    * @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);
-  }*/
+  // public static void //
+  //     assertFalse(boolean condition, Object... message)   {
+  //   assertTrue(!condition, message);
+  // }
 
   /**
    * Asserts that two objects are equal. When instances of Comparable, such as
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java
new file mode 100644
index 0000000..8ba1d44
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/common/provider/StringBeanWithAnnotation.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.common.provider;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+
+@Consumes(MediaType.TEXT_PLAIN)
+@Produces(MediaType.TEXT_PLAIN)
+/**
+ * It does not make sense to put any of these annotations. But for test e.g.
+ * getEntityAnnotationsIsNotTakenFromEntityClassTest we need to check that
+ * context.getAnnotations won't have these annotations.
+ */
+public class StringBeanWithAnnotation extends StringBean {
+
+  public StringBeanWithAnnotation(String header) {
+    super(header);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java
new file mode 100644
index 0000000..cc8dfc7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/ContextProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient.Fault;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class ContextProvider implements ClientRequestFilter {
+
+  protected void checkFilterContext(ClientRequestContext context) throws Fault {
+    throw new Fault("this TCK method is not implemented yet");
+  }
+
+  @Override
+  public void filter(ClientRequestContext context) throws IOException {
+    try {
+      checkFilterContext(context);
+    } catch (Fault e) {
+      throw new IOException(e);
+    }
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..de6c77f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/JAXRSClientIT.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.api.client.clientrequestcontext.ContextProvider;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.impl.ReplacingOutputStream;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -3234850442044177095L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_rs_client_clientrequestcontext_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_clientrequestcontext_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class, ContextProvider.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getEntityStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:437; JAXRS:JAVADOC:451; JAXRS:JAVADOC:455;
+   * JAXRS:JAVADOC:456;
+   * 
+   * @test_Strategy: Get the entity output stream. Set a new entity output
+   * stream.
+   */
+  @Test
+  public void getEntityStreamTest() throws Fault {
+    final String entityStreamWorks = "ENTITY_STREAM_WORKS";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        OutputStream stream = context.getEntityStream();
+        ReplacingOutputStream wrapper = new ReplacingOutputStream(stream, 'X',
+            'T');
+        context.setEntityStream(wrapper);
+      }
+    };
+    ByteArrayInputStream entity = new ByteArrayInputStream(
+        entityStreamWorks.replace('T', 'X').getBytes());
+    addProvider(provider);
+    setRequestContentEntity(entity);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "post"));
+    invoke();
+
+    String body = getResponseBody();
+    assertContains(body, entityStreamWorks);
+  }
+
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:439; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * 
+   * @test_Strategy: Get the generic entity type information.
+   */
+  @Test
+  public void getHeadersIsMutableTest() throws Fault {
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        MultivaluedMap<String, Object> headers = context.getHeaders();
+        headers.add("Accept-Language", "en_gb");
+        headers.add("Date", "Tue, 15 Nov 1994 08:12:31 GMT");
+        headers.add("tck", "cts");
+      }
+    };
+    addProvider(provider);
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "headers"));
+    invoke();
+
+    String body = getResponseBody().toLowerCase();
+    assertContains(body, "accept-language");
+    assertContains(body, "date");
+    assertContains(body, "tck");
+  }
+
+  /*
+   * @testName: setMethodTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:452; JAXRS:JAVADOC:455; JAXRS:JAVADOC:456;
+   * 
+   * @test_Strategy: Set the request method.
+   */
+  @Test
+  public void setMethodTest() throws Fault {
+    String entity = "ENTITY";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        context.setMethod("PUT");
+      }
+    };
+    addProvider(provider);
+    setRequestContentEntity(entity);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "put"));
+    invoke();
+
+    String body = getResponseBody();
+    assertContains(body, entity);
+  }
+
+  /*
+   * @testName: setUriTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:454; JAXRS:JAVADOC:447; JAXRS:JAVADOC:455;
+   * JAXRS:JAVADOC:456;
+   * 
+   * @test_Strategy: Set a new request URI. Get the request URI.
+   */
+  @Test
+  public void setUriTest() throws Fault {
+    String entity = "ENTITY";
+    ContextProvider provider = new ContextProvider() {
+      @Override
+      protected void checkFilterContext(ClientRequestContext context)
+          throws Fault {
+        URI uri = context.getUri();
+        try {
+          uri = new URI(uri.toASCIIString().replace("qwerty", "post"));
+        } catch (URISyntaxException e) {
+          throw new Fault(e);
+        }
+        context.setUri(uri);
+      }
+    };
+    addProvider(provider);
+    setRequestContentEntity(entity);
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "qwerty"));
+    invoke();
+
+    String body = getResponseBody();
+    assertContains(body, entity);
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  protected static void assertContains(String string, String substring)
+      throws Fault {
+    assertTrue(string.contains(substring), string+ "does NOT contain"+
+        substring);
+    TestUtil.logMsg("Found expected substring: " + substring);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java
new file mode 100644
index 0000000..7b7c857
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/Resource.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+import java.util.Collection;
+
+import jakarta.ws.rs.GET;
+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.HttpHeaders;
+
+@Path("resource")
+public class Resource {
+
+  @POST
+  @Path("post")
+  public String post(String value) {
+    return value;
+  }
+
+  @PUT
+  @Path("put")
+  public String put(String value) {
+    return value;
+  }
+
+  @GET
+  @Path("headers")
+  public String headers(@Context HttpHeaders headers) {
+    String hdrs = collectionToString(headers.getRequestHeaders().keySet());
+    return hdrs;
+  }
+
+  protected static <T> String collectionToString(Collection<T> collection) {
+    StringBuilder sb = new StringBuilder();
+    for (T t : collection)
+      sb.append(t).append(";");
+    return sb.toString();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java
new file mode 100644
index 0000000..9a302e6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.clientrequestcontext;
+
+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/client/invocationbuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..fe355dd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/JAXRSClientIT.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+import java.util.Locale;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.client.JdkLoggingFilter;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+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.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedHashMap;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -8097693127928445210L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_rs_client_invocationbuilder_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_invocationbuilder_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  static final String[] METHODS = { "delete", "get", "options" };
+
+  static final String[] ENTITY_METHODS = { "put", "post" };
+
+  /* Run test */
+  /*
+   * @testName: acceptLanguageByLocalesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:524;
+   * 
+   * @test_Strategy: Add acceptable languages.
+   */
+  @Test
+  public void acceptLanguageByLocalesTest() throws Fault {
+    Invocation.Builder builder = createBuilderForMethod("languages");
+    builder = builder.acceptLanguage(Locale.GERMAN, Locale.ITALIAN,
+        Locale.FRENCH);
+    String response = builder.buildGet().invoke(String.class);
+    String error = "Expected locale was not found in the response:";
+    assertContainsIgnoreCase(response, Locale.GERMAN, error, response);
+    assertContainsIgnoreCase(response, Locale.ITALIAN, error, response);
+    assertContainsIgnoreCase(response, Locale.FRENCH, error, response);
+  }
+
+  /*
+   * @testName: acceptLanguageByStringsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:525;
+   * 
+   * @test_Strategy: Add acceptable languages.
+   */
+  @Test
+  public void acceptLanguageByStringsTest() throws Fault {
+    Invocation.Builder builder = createBuilderForMethod("languages");
+    builder = builder.acceptLanguage(langToString(Locale.GERMAN),
+        langToString(Locale.ITALIAN), langToString(Locale.FRENCH));
+    String response = builder.buildGet().invoke(String.class);
+    String error = "Expected locale was not found in the response:";
+    assertContainsIgnoreCase(response, Locale.GERMAN, error, response);
+    assertContainsIgnoreCase(response, Locale.ITALIAN, error, response);
+    assertContainsIgnoreCase(response, Locale.FRENCH, error, response);
+  }
+
+  /*
+   * @testName: asyncTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:526;
+   * 
+   * @test_Strategy: Access the asynchronous uniform request invocation
+   * interface to asynchronously invoke the built request.
+   */
+  @Test
+  public void asyncTest() throws Fault {
+    Invocation.Builder builder = createBuilderForMethod("forbid");
+    AsyncInvoker async = builder.async();
+    assertTrue(async != null, "Builder.async() does not work properly");
+  }
+
+  /*
+   * @testName: buildTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:527;
+   * 
+   * @test_Strategy: Build a request invocation using an arbitrary request
+   * method name.
+   */
+  @Test
+  public void buildTest() throws Fault {
+    String error = "Unexpected response returned:";
+    for (String method : METHODS) {
+      Invocation.Builder builder = createBuilderForMethod(method);
+      String response = builder.build(method.toUpperCase())
+          .invoke(String.class);
+      assertContainsIgnoreCase(response, method, error, response);
+    }
+  }
+
+  /*
+   * @testName: buildWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:528;
+   * 
+   * @test_Strategy: Build a request invocation using an arbitrary request
+   * method name and request entity
+   */
+  @Test
+  public void buildWithEntityTest() throws Fault {
+    String error = "Unexpected response returned:";
+    for (String method : ENTITY_METHODS) {
+      Invocation.Builder builder = createBuilderForMethod(method);
+      Entity<String> entity = createEntity(method);
+      String response = builder.build(method.toUpperCase(), entity)
+          .invoke(String.class);
+      assertContainsIgnoreCase(response, method, error, response);
+    }
+  }
+
+  /*
+   * @testName: buildDeleteTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:529;
+   * 
+   * @test_Strategy: Build a DELETE request invocation.
+   */
+  @Test
+  public void buildDeleteTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("delete");
+    String response = builder.buildDelete().invoke(String.class);
+    assertContainsIgnoreCase(response, "delete", error, response);
+  }
+
+  /*
+   * @testName: buildGetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:530;
+   * 
+   * @test_Strategy: Build a GET request invocation.
+   */
+  @Test
+  public void buildGetTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("get");
+    String response = builder.buildGet().invoke(String.class);
+    assertContainsIgnoreCase(response, "get", error, response);
+  }
+
+  /*
+   * @testName: buildPostTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:531;
+   * 
+   * @test_Strategy: Build a POST request invocation.
+   */
+  @Test
+  public void buildPostTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("post");
+    Entity<String> entity = createEntity("post");
+    String response = builder.buildPost(entity).invoke(String.class);
+    assertContainsIgnoreCase(response, "post", error, response);
+  }
+
+  /*
+   * @testName: buildPutTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:532;
+   * 
+   * @test_Strategy: Build a PUT request invocation.
+   */
+  @Test
+  public void buildPutTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("put");
+    Entity<String> entity = createEntity("put");
+    String response = builder.buildPut(entity).invoke(String.class);
+    assertContainsIgnoreCase(response, "put", error, response);
+  }
+
+  /*
+   * @testName: cacheControlTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:533;
+   * 
+   * @test_Strategy: Set the cache control data of the message.
+   */
+  @Test
+  public void cacheControlTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("headerstostring");
+    CacheControl control = new CacheControl();
+    control.setMaxAge(2);
+    String response = builder.cacheControl(control).buildGet()
+        .invoke(String.class).toLowerCase();
+    assertContainsIgnoreCase(response, "max-age", error, response);
+  }
+
+  /*
+   * @testName: cookieCookieTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:535;
+   * 
+   * @test_Strategy: Add a cookie to be set.
+   */
+  @Test
+  public void cookieCookieTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("cookie");
+    Cookie cookie = new Cookie("tck", "cts");
+    String response = builder.cookie(cookie).buildGet().invoke(String.class);
+    assertContainsIgnoreCase(response, "cts", error, response);
+  }
+
+  /*
+   * @testName: cookieStringStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:536;
+   * 
+   * @test_Strategy: Add a cookie to be set.
+   */
+  @Test
+  public void cookieStringStringTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("cookie");
+    String response = builder.cookie("tck", "cts").buildGet()
+        .invoke(String.class);
+    assertContainsIgnoreCase(response, "cts", error, response);
+  }
+
+  /*
+   * @testName: headerObjectTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:537;
+   * 
+   * @test_Strategy: Add an arbitrary header.
+   */
+  @Test
+  public void headerObjectTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("headerstostring");
+    String response = builder.header("tck-header", "cts-header").buildGet()
+        .invoke(String.class);
+    assertContainsIgnoreCase(response, "tck-header", error, response);
+    assertContainsIgnoreCase(response, "cts-header", error, response);
+  }
+
+  /*
+   * @testName: headersMultivaluedMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:538;
+   * 
+   * @test_Strategy: Replaces all existing headers with the newly supplied
+   * headers.
+   */
+  @Test
+  public void headersMultivaluedMapTest() throws Fault {
+    String error = "Unexpected response returned:";
+    Invocation.Builder builder = createBuilderForMethod("headerstostring");
+    MultivaluedMap<String, Object> map = new MultivaluedHashMap<String, Object>();
+    map.add("tck-header", "cts-header");
+    String response = builder.header("unexpected-header", "unexpected-header")
+        .headers(map).buildGet().invoke(String.class);
+    assertTrue(!response.contains("unexpected-header"),
+        "unexpected-header found in the response");
+    assertContainsIgnoreCase(response, "tck-header", error, response);
+    assertContainsIgnoreCase(response, "cts-header", error, response);
+  }
+
+  /*
+   * @testName: headersMultivaluedMapIsNullReplacesAllTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:538;
+   * 
+   * @test_Strategy: headers - new headers to be set, if null all existing
+   * headers will be removed.
+   */
+  @Test
+  public void headersMultivaluedMapIsNullReplacesAllTest() throws Fault {
+    Invocation.Builder builder = createBuilderForMethod("headerstostring");
+    String response = builder.header("unexpected-header", "unexpected-header")
+        .headers((MultivaluedMap<String, Object>) null).buildGet()
+        .invoke(String.class);
+    assertTrue(!response.contains("unexpected-header"),
+        "unexpected-header found in the response");
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+
+  protected String getUrl(String method) {
+    StringBuilder url = new StringBuilder();
+    url.append("http://").append(_hostname).append(":").append(_port);
+    url.append(getContextRoot()).append("/").append(method);
+    return url.toString();
+  }
+
+  /**
+   * Create Invocation.Builder for given resource method and start time
+   */
+  protected Invocation.Builder createBuilderForMethod(String methodName) {
+    Client client = ClientBuilder.newClient();
+    client.register(new JdkLoggingFilter(false));
+    WebTarget target = client.target(getUrl(methodName));
+    Invocation.Builder builder = target.request();
+    return builder;
+  }
+
+  protected <T> Entity<T> createEntity(T entity) {
+    return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+  }
+
+  /**
+   * @return simulates toLanguageTag() for java prior version 7
+   */
+  protected String langToString(Locale language) {
+    return language.toString().replace("_", "-");
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java
new file mode 100644
index 0000000..f04e8de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/Resource.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+import java.util.List;
+import java.util.Map.Entry;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.CookieParam;
+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.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+@Path("resource")
+public class Resource {
+
+  @GET
+  @Path("languages")
+  public String languages(@Context HttpHeaders headers) {
+    return JaxrsUtil.iterableToString(" ", headers.getAcceptableLanguages());
+  }
+
+  @GET
+  @Path("headerstostring")
+  public String headersToString(@Context HttpHeaders headers) {
+    MultivaluedMap<String, String> map = headers.getRequestHeaders();
+    StringBuilder sb = new StringBuilder();
+    for (Entry<String, List<String>> header : map.entrySet())
+      sb.append(header.getKey()).append(":")
+          .append(JaxrsUtil.iterableToString(" ", header.getValue()))
+          .append(";");
+    return sb.toString();
+  }
+
+  @GET
+  @Path("cookie")
+  public String cookie(@CookieParam("tck") String cookie) {
+    return cookie;
+  }
+
+  @GET
+  @Path("allow")
+  public String allow() {
+    return "allow";
+  }
+
+  @DELETE
+  @Path("forbid")
+  public String forbid() {
+    return "forbid";
+  }
+
+  @GET
+  @Path("get")
+  public String get() {
+    return "get";
+  }
+
+  @HEAD
+  @Path("head")
+  public String head() {
+    return "head";
+  }
+
+  @PUT
+  @Path("put")
+  public String put(String value) {
+    return value;
+  }
+
+  @POST
+  @Path("post")
+  public String post(String value) {
+    return value;
+  }
+
+  @DELETE
+  @Path("delete")
+  public String delete() {
+    return "delete";
+  }
+
+  @OPTIONS
+  @Path("options")
+  public String options() {
+    return "options";
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java
new file mode 100644
index 0000000..6cd7cd5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.invocationbuilder;
+
+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/client/syncinvoker/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/JAXRSClientIT.java
new file mode 100644
index 0000000..89297cb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/JAXRSClientIT.java
@@ -0,0 +1,2171 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+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 jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.SyncInvoker;
+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;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 4942772066511819511L;
+
+  protected long millis;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_rs_client_syncinvoker_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_client_syncinvoker_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class, jakarta.ws.rs.tck.common.impl.TRACE.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  static final String[] METHODS = { "DELETE", "GET", "OPTIONS" };
+
+  static final String[] ENTITY_METHODS = { "PUT", "POST" };
+
+  /* Run test */
+  // --------------------------------------------------------------------
+  // ---------------------- DELETE --------------------------------------
+  // --------------------------------------------------------------------
+  /*
+   * @testName: deleteTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:541;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response deleteTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("delete");
+    Response response = sync.delete();
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: deleteThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:541;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void deleteThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.delete();
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: deleteWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:543;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * synchronously.
+   */
+  @Test
+  public String deleteWithStringClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("delete");
+    String response = sync.delete(String.class);
+    assertResponseString(response, "delete");
+    return response;
+  }
+
+  /*
+   * @testName: deleteWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:543;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response deleteWithResponseClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("delete");
+    Response response = sync.delete(Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: deleteWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:543;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void deleteWithStringClassThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.delete(String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: deleteWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:543;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void deleteWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+        sync.delete(String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: deleteWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:543;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void deleteWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+    Response response = sync.delete(Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:546;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * synchronously.
+   */
+  @Test
+  public String deleteWithGenericTypeStringTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("delete");
+    GenericType<String> generic = createGeneric(String.class);
+    String response = sync.delete(generic);
+    assertResponseString(response, "delete");
+    return response;
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:546;
+   * 
+   * @test_Strategy: Invoke HTTP DELETE method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response deleteWithGenericTypeResponseTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("delete");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.delete(generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:546;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void deleteWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        GenericType<String> generic = createGeneric(String.class);
+        sync.delete(generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:546;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void deleteWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.delete(generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: deleteWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:546;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.delete( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void deleteWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("deletenotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.delete(generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------GET------------------------------------
+  // ------------------------------------------------------------------
+  /*
+   * @testName: getTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:549;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response getTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("get");
+    Response response = sync.get();
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: getThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:549;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void getThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.get();
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: getWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:551;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * synchronously.
+   */
+  @Test
+  public String getWithStringClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("get");
+    String response = sync.get(String.class);
+    assertResponseString(response, "get");
+    return response;
+  }
+
+  /*
+   * @testName: getWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:551;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response getWithResponseClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("get");
+    Response response = sync.get(Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: getWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:551;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void getWithStringClassThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.get(String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: getWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:551;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void getWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+        sync.get(String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: getWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:551;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void getWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+    Response response = sync.get(Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: getWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:554;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * synchronously.
+   */
+  @Test
+  public String getWithGenericTypeStringTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("get");
+    GenericType<String> generic = createGeneric(String.class);
+    String response = sync.get(generic);
+    assertResponseString(response, "get");
+    return response;
+  }
+
+  /*
+   * @testName: getWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:554;
+   * 
+   * @test_Strategy: Invoke HTTP GET method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response getWithGenericTypeResponseTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("get");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.get(generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: getWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:554;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void getWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        GenericType<String> generic = createGeneric(String.class);
+        sync.get(generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: getWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:554;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void getWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.get(generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: getWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:554;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.get( GenericType ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void getWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("getnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.get(generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------HEAD-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: headTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:557;
+   * 
+   * @test_Strategy: Invoke HTTP HEAD method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response headTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("head");
+    Response response = sync.head();
+    Status status = Status.fromStatusCode(response.getStatus());
+    assertTrue(status == Status.OK || status == Status.NO_CONTENT,
+        "Incorrect status for head received");
+    return response;
+  }
+
+  /*
+   * @testName: headThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:557;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.head throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void headThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.head();
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------METHOD-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: methodTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:559;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodTest() throws Fault {
+    Response response = null;
+    for (String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      response = sync.method(method);
+      assertResponseOk(response);
+    }
+  }
+
+  /*
+   * @testName: methodThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:559;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodThrowsProcessingExceptionTest() throws Fault {
+    for (final String method : METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          sync.method(method);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:561;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithStringClassTest() throws Fault {
+    String response = null;
+    for (String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      response = sync.method(method, String.class);
+      assertResponseString(response, method.toLowerCase());
+    }
+  }
+
+  /*
+   * @testName: methodWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:561;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithResponseClassTest() throws Fault {
+    Response response = null;
+    for (String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      response = sync.method(method, Response.class);
+      assertResponseOk(response);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:561;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void methodWithStringClassThrowsProcessingExceptionTest()
+      throws Fault {
+    for (final String method : METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          sync.method(method, String.class);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:561;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void methodWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerForMethod(
+              method.toLowerCase() + "notok");
+          sync.method(method, String.class);
+        }
+      };
+      assertWebApplicationException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:561;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Response response = sync.method(method, Response.class);
+      assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:564;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithGenericTypeStringTest() throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    String response = null;
+    for (String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      response = sync.method(method, generic);
+      assertResponseString(response, method.toLowerCase());
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:564;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithGenericTypeResponseTest() throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = null;
+    for (String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      response = sync.method(method, generic);
+      assertResponseOk(response);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:564;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    final GenericType<String> generic = createGeneric(String.class);
+    for (final String method : METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          sync.method(method, generic);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:564;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(GenericType<String>)
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    final GenericType<String> generic = createGeneric(String.class);
+    for (final String method : METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerForMethod(
+              method.toLowerCase() + "notok");
+          sync.method(method, generic);
+        }
+      };
+      assertWebApplicationException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:564;
+   * 
+   * @test_Strategy:
+   * jakarta.ws.rs.client.SyncInvoker.method(GenericType<Response>) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void methodWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = null;
+    for (final String method : METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      response = sync.method(method, generic);
+      assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:567;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response methodWithEntityTest() throws Fault {
+    Response response = null;
+    for (String method : ENTITY_METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = createEntity(method.toLowerCase());
+      response = sync.method(method, entity);
+      assertResponseOk(response);
+    }
+    return response;
+  }
+
+  /*
+   * @testName: methodWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:567;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity)
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodWithEntityThrowsProcessingExceptionTest() throws Fault {
+    final Entity<String> entity = createEntity("entity");
+    for (final String method : ENTITY_METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          sync.method(method, entity);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:569;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public String methodWithStringClassWithEntityTest() throws Fault {
+    String response = null;
+    for (String method : ENTITY_METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = createEntity(method.toLowerCase());
+      response = sync.method(method, entity, String.class);
+      assertResponseString(response, method.toLowerCase());
+    }
+    return response;
+  }
+
+  /*
+   * @testName: methodWithResponseClassWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:569;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public String methodWithResponseClassWithEntityTest() throws Fault {
+    String response = null;
+    for (String method : ENTITY_METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = createEntity(method.toLowerCase());
+      response = sync.method(method, entity, String.class);
+      assertResponseString(response, method.toLowerCase());
+    }
+    return response;
+  }
+
+  /*
+   * @testName: methodWithStringClassWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:569;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * Class) throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodWithStringClassWithEntityThrowsProcessingExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          Entity<String> entity = createEntity(method.toLowerCase());
+          sync.method(method, entity, String.class);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName: methodWithStringClassWithEntityThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:569;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * Class) throws WebApplicationException - in case the response status code of
+   * the response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void methodWithStringClassWithEntityThrowsWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          SyncInvoker sync = createSyncInvokerForMethod(
+              method.toLowerCase() + "notok");
+          Entity<String> entity = createEntity(method.toLowerCase());
+          sync.method(method, entity, String.class);
+        }
+      };
+      assertWebApplicationException(run);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithResponseClassWithEntityThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:569;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * Class) throws WebApplicationException - in case the response status code of
+   * the response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void methodWithResponseClassWithEntityThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      SyncInvoker sync = createSyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = createEntity(method.toLowerCase());
+      Response response = sync.method(method, entity, Response.class);
+      assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeStringWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:572;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithGenericTypeStringWithEntityTest() throws Fault {
+    String response = null;
+    for (String method : ENTITY_METHODS) {
+      GenericType<String> generic = createGeneric(String.class);
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = createEntity(method.toLowerCase());
+      response = sync.method(method, entity, generic);
+      assertResponseString(response, method.toLowerCase());
+    }
+  }
+
+  /*
+   * @testName: methodWithGenericTypeResponseWithEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:572;
+   * 
+   * @test_Strategy: Invoke an arbitrary method for the current request
+   * synchronously.
+   */
+  @Test
+  public void methodWithGenericTypeResponseWithEntityTest() throws Fault {
+    Response response = null;
+    for (String method : ENTITY_METHODS) {
+      GenericType<Response> generic = createGeneric(Response.class);
+      SyncInvoker sync = createSyncInvokerForMethod(method.toLowerCase());
+      Entity<String> entity = createEntity(method.toLowerCase());
+      response = sync.method(method, entity, generic);
+      assertResponseOk(response);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithGenericTypeStringWithEntityThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:572;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * GenericType) throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void methodWithGenericTypeStringWithEntityThrowsProcessingExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          GenericType<String> generic = createGeneric(String.class);
+          SyncInvoker sync = createSyncInvokerWrongUrl();
+          Entity<String> entity = createEntity(method);
+          sync.method(method, entity, generic);
+        }
+      };
+      assertProcessingException(run);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithGenericTypeStringWithEntityThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:572;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * GenericType) throws WebApplicationException - in case the response status
+   * code of the response returned by the server is not successful and the
+   * specified response type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeStringWithEntityThrowsWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      Runnable run = new Runnable() {
+        @Override
+        public void run() {
+          GenericType<String> generic = createGeneric(String.class);
+          SyncInvoker sync = createSyncInvokerForMethod(
+              method.toLowerCase() + "notok");
+          Entity<String> entity = createEntity(method);
+          sync.method(method, entity, generic);
+        }
+      };
+      assertWebApplicationException(run);
+    }
+  }
+
+  /*
+   * @testName:
+   * methodWithGenericTypeResponseWithEntityThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:572;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.method(String, Entity,
+   * GenericType) throws WebApplicationException - in case the response status
+   * code of the response returned by the server is not successful and the
+   * specified response type is not Response.
+   */
+  @Test
+  public void methodWithGenericTypeResponseWithEntityThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    for (final String method : ENTITY_METHODS) {
+      GenericType<Response> generic = createGeneric(Response.class);
+      SyncInvoker sync = createSyncInvokerForMethod(
+          method.toLowerCase() + "notok");
+      Entity<String> entity = createEntity(method);
+      Response response = sync.method(method, entity, generic);
+      assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+    }
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------OPTIONS--------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: optionsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:575;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response optionsTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("options");
+    Response response = sync.options();
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: optionsThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:575;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void optionsThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.options();
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: optionsWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:577;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * synchronously.
+   */
+  @Test
+  public String optionsWithStringClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("options");
+    String response = sync.options(String.class);
+    assertResponseString(response, "options");
+    return response;
+  }
+
+  /*
+   * @testName: optionsWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:577;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response optionsWithResponseClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("options");
+    Response response = sync.options(Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: optionsWithStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:577;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void optionsWithStringThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.options(String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: optionsWithStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:577;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void optionsWithStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+        sync.options(String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: optionsWithResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:577;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void optionsWithResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+    Response response = sync.options(Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:580;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * synchronously.
+   */
+  @Test
+  public String optionsWithGenericTypeStringTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("options");
+    GenericType<String> generic = createGeneric(String.class);
+    String response = sync.options(generic);
+    assertResponseString(response, "options");
+    return response;
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:580;
+   * 
+   * @test_Strategy: Invoke HTTP options method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response optionsWithGenericTypeResponseTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("options");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.options(generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:580;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void optionsWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        GenericType<String> generic = createGeneric(String.class);
+        sync.options(generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: optionsWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:580;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void optionsWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.options(generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName:
+   * optionsWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:580;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.options( GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void optionsWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("optionsnotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.options(generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------POST-----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: postTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:583;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response postTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("post");
+    Entity<String> entity = createEntity("post");
+    Response response = sync.post(entity);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: postThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:583;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post(Entity) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void postThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("post");
+        sync.post(entity);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: postWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:585;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * synchronously.
+   */
+  @Test
+  public String postWithStringClassTest() throws Fault {
+    Entity<String> entity = createEntity("post");
+    SyncInvoker sync = createSyncInvokerForMethod("post");
+    String response = sync.post(entity, String.class);
+    assertResponseString(response, "post");
+    return response;
+  }
+
+  /*
+   * @testName: postWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:585;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response postWithResponseClassTest() throws Fault {
+    Entity<String> entity = createEntity("post");
+    SyncInvoker sync = createSyncInvokerForMethod("post");
+    Response response = sync.post(entity, Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: postWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:585;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void postWithStringClassThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("post");
+        sync.post(entity, String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: postWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:585;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void postWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+        Entity<String> entity = createEntity("post");
+        sync.post(entity, String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: postWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:585;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void postWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+    Entity<String> entity = createEntity("post");
+    Response response = sync.post(entity, Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: postWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:588;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * synchronously.
+   */
+  @Test
+  public String postWithGenericTypeStringTest() throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = createEntity("post");
+    SyncInvoker sync = createSyncInvokerForMethod("post");
+    String response = sync.post(entity, generic);
+    assertResponseString(response, "post");
+    return response;
+  }
+
+  /*
+   * @testName: postWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:588;
+   * 
+   * @test_Strategy: Invoke HTTP post method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response postWithGenericTypeResponseTest() throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Entity<String> entity = createEntity("post");
+    SyncInvoker sync = createSyncInvokerForMethod("post");
+    Response response = sync.post(entity, generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: postWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:588;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void postWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("post");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.post(entity, generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: postWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:588;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void postWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+        Entity<String> entity = createEntity("post");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.post(entity, generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: postWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:588;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.post( Entity, GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void postWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("postnotok");
+    Entity<String> entity = createEntity("post");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.post(entity, generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------PUT -----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: putTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:591;
+   * 
+   * @test_Strategy: Invoke HTTP PUT method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response putTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("put");
+    Entity<String> entity = createEntity("put");
+    Response response = sync.put(entity);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: putThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:591;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put(Entity) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void putThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("put");
+        sync.put(entity);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: putWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:593;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * synchronously.
+   */
+  @Test
+  public String putWithStringClassTest() throws Fault {
+    Entity<String> entity = createEntity("put");
+    SyncInvoker sync = createSyncInvokerForMethod("put");
+    String response = sync.put(entity, String.class);
+    assertResponseString(response, "put");
+    return response;
+  }
+
+  /*
+   * @testName: putWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:593;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response putWithResponseClassTest() throws Fault {
+    Entity<String> entity = createEntity("put");
+    SyncInvoker sync = createSyncInvokerForMethod("put");
+    Response response = sync.put(entity, Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: putWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:593;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void putWithStringClassThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("put");
+        sync.put(entity, String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: putWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:593;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void putWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+        Entity<String> entity = createEntity("put");
+        sync.put(entity, String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: putWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:593;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, Class ) throws
+   * WebApplicationException - in case the response status code of the response
+   * returned by the server is not successful and the specified response type is
+   * not Response.
+   */
+  @Test
+  public void putWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+    Entity<String> entity = createEntity("put");
+    Response response = sync.put(entity, Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: putWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:596;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * synchronously.
+   */
+  @Test
+  public String putWithGenericTypeStringTest() throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    Entity<String> entity = createEntity("put");
+    SyncInvoker sync = createSyncInvokerForMethod("put");
+    String response = sync.put(entity, generic);
+    assertResponseString(response, "put");
+    return response;
+  }
+
+  /*
+   * @testName: putWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:596;
+   * 
+   * @test_Strategy: Invoke HTTP put method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response putWithGenericTypeResponseTest() throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    Entity<String> entity = createEntity("put");
+    SyncInvoker sync = createSyncInvokerForMethod("put");
+    Response response = sync.put(entity, generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: putWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:596;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, GenericType )
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void putWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        Entity<String> entity = createEntity("put");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.put(entity, generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: putWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:596;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.put( Entity, GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void putWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+        Entity<String> entity = createEntity("put");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.put(entity, generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: putWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:596;
+   * 
+   * @test_Strategy: throws WebApplicationException - in case the response
+   * status code of the response returned by the server is not successful and
+   * the specified response type is not Response.
+   */
+  @Test
+  public void putWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("putnotok");
+    Entity<String> entity = createEntity("put");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.put(entity, generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ------------------------------------------------------------------
+  // ---------------------------TRACE -----------------------------------
+  // ------------------------------------------------------------------
+
+  /*
+   * @testName: traceTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:599;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response traceTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("trace");
+    Response response = sync.trace();
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: traceThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:599;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace(Entity) throws
+   * ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void traceThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.trace();
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: traceWithStringClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:601;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * synchronously.
+   */
+  @Test
+  public String traceWithStringClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("trace");
+    String response = sync.trace(String.class);
+    assertResponseString(response, "trace");
+    return response;
+  }
+
+  /*
+   * @testName: traceWithResponseClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:601;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response traceWithResponseClassTest() throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("trace");
+    Response response = sync.trace(Response.class);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: traceWithStringClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:601;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void traceWithStringClassThrowsProcessingExceptionTest() throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        sync.trace(String.class);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: traceWithStringClassThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:601;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void traceWithStringClassThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+        sync.trace(String.class);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: traceWithResponseClassThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:601;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, Class )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  //@Test
+  public void traceWithResponseClassThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+    Response response = sync.trace(Response.class);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  /*
+   * @testName: traceWithGenericTypeStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:604;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * synchronously.
+   */
+  @Test
+  public String traceWithGenericTypeStringTest() throws Fault {
+    GenericType<String> generic = createGeneric(String.class);
+    SyncInvoker sync = createSyncInvokerForMethod("trace");
+    String response = sync.trace(generic);
+    assertResponseString(response, "trace");
+    return response;
+  }
+
+  /*
+   * @testName: traceWithGenericTypeResponseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:604;
+   * 
+   * @test_Strategy: Invoke HTTP trace method for the current request
+   * synchronously.
+   */
+  @Test
+  public Response traceWithGenericTypeResponseTest() throws Fault {
+    GenericType<Response> generic = createGeneric(Response.class);
+    SyncInvoker sync = createSyncInvokerForMethod("trace");
+    Response response = sync.trace(generic);
+    assertResponseOk(response);
+    return response;
+  }
+
+  /*
+   * @testName: traceWithGenericTypeStringThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:604;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+   * throws ProcessingException in case the invocation failed.
+   */
+  @Test
+  public void traceWithGenericTypeStringThrowsProcessingExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerWrongUrl();
+        GenericType<String> generic = createGeneric(String.class);
+        sync.trace(generic);
+      }
+    };
+    assertProcessingException(run);
+  }
+
+  /*
+   * @testName: traceWithGenericTypeStringThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:604;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  @Test
+  public void traceWithGenericTypeStringThrowsWebApplicationExceptionTest()
+      throws Fault {
+    Runnable run = new Runnable() {
+      @Override
+      public void run() {
+        SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+        GenericType<String> generic = createGeneric(String.class);
+        sync.trace(generic);
+      }
+    };
+    assertWebApplicationException(run);
+  }
+
+  /*
+   * @testName: traceWithGenericTypeResponseThrowsNoWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:604;
+   * 
+   * @test_Strategy: jakarta.ws.rs.client.SyncInvoker.trace( Entity, GenericType )
+   * throws WebApplicationException - in case the response status code of the
+   * response returned by the server is not successful and the specified
+   * response type is not Response.
+   */
+  //@Test
+  public void traceWithGenericTypeResponseThrowsNoWebApplicationExceptionTest()
+      throws Fault {
+    SyncInvoker sync = createSyncInvokerForMethod("tracenotok");
+    GenericType<Response> generic = createGeneric(Response.class);
+    Response response = sync.trace(generic);
+    assertStatusAndLog(response, Status.NOT_ACCEPTABLE);
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  // utility methods
+
+  protected String getUrl(String method) {
+    StringBuilder url = new StringBuilder();
+    url.append("http://").append(_hostname).append(":").append(_port);
+    url.append(getContextRoot()).append("/").append(method);
+    return url.toString();
+  }
+
+  /**
+   * Create SyncInvoker for given resource method and start time
+   */
+  protected SyncInvoker createSyncInvokerForMethod(String methodName) {
+    Client client = ClientBuilder.newClient();
+    client.register(new JdkLoggingFilter(false));
+    WebTarget target = client.target(getUrl(methodName));
+    SyncInvoker sync = target.request();
+    return sync;
+  }
+
+  protected SyncInvoker createSyncInvokerWrongUrl() {
+    _hostname = "tck.cts";
+    _port = 888;
+    return createSyncInvokerForMethod("wrongurl");
+  }
+
+  protected static void assertStatusAndLog(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 static void assertResponseOk(Response response) throws Fault {
+    assertStatusAndLog(response, Status.OK);
+  }
+
+  protected static void assertResponseString(String response,
+      String expectedValue) throws Fault {
+    assertTrue(expectedValue.equals(response), "expected value"+ expectedValue+
+        "differes from acquired value"+ response);
+  }
+
+  protected static <T> Entity<T> createEntity(T entity) {
+    return Entity.entity(entity, MediaType.WILDCARD_TYPE);
+  }
+
+  protected static <T> GenericType<T> createGeneric(Class<T> clazz) {
+    return new GenericType<T>(clazz);
+  }
+
+  protected static void assertProcessingException(Runnable runnable)
+      throws Fault {
+    assertException(runnable, ProcessingException.class);
+  }
+
+  protected static//
+  void assertWebApplicationException(Runnable runnable) throws Fault {
+    assertException(runnable, WebApplicationException.class);
+  }
+
+  protected static <T extends Exception> void assertException(Runnable runnable,
+      Class<T> exception) throws Fault {
+    try {
+      runnable.run();
+    } catch (Exception e) {
+      if (exception != null && exception.isInstance(e)) {
+        return;
+      }
+      throw new Fault("unexpected exception", e);
+    }
+    fault("ProcessingException has not been thrown");
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java
new file mode 100644
index 0000000..c2e456a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/Resource.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+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 {
+
+  @GET
+  @Path("get")
+  public String get() {
+    return "get";
+  }
+
+  @GET
+  @Path("getnotok")
+  public Response getNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @HEAD
+  @Path("head")
+  public String head() {
+    return "head";
+  }
+
+  @HEAD
+  @Path("headnotok")
+  public Response headNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @PUT
+  @Path("put")
+  public String put(String value) {
+    return value;
+  }
+
+  @PUT
+  @Path("putnotok")
+  public Response putNotOk(String value) {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @POST
+  @Path("post")
+  public String post(String value) {
+    return value;
+  }
+
+  @POST
+  @Path("postnotok")
+  public Response postNotOk(String value) {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @DELETE
+  @Path("delete")
+  public String delete() {
+    return "delete";
+  }
+
+  @DELETE
+  @Path("deletenotok")
+  public Response deleteNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @OPTIONS
+  @Path("options")
+  public String options() {
+    return "options";
+  }
+
+  @OPTIONS
+  @Path("optionsnotok")
+  public Response optionsNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+  @TRACE
+  @Path("trace")
+  public String trace() {
+    return "trace";
+  }
+
+  @TRACE
+  @Path("tracenotok")
+  public Response traceNotOk() {
+    return Response.status(Status.NOT_ACCEPTABLE).build();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java
new file mode 100644
index 0000000..1b657bf
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.client.syncinvoker;
+
+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/application/ApplicationHolderSingleton.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationHolderSingleton.java
new file mode 100644
index 0000000..2c1fd89
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationHolderSingleton.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+/**
+ * ApplicationHolderSingleton is a Singleton that is a dummy provider, too, to
+ * conform requirement on Provider
+ */
+public class ApplicationHolderSingleton
+    implements MessageBodyReader<Application> {
+  private Application application;
+
+  public ApplicationHolderSingleton(Application application) {
+    super();
+    this.application = application;
+  }
+
+  public Application getApplication() {
+    return application;
+  }
+
+  @Override
+  public boolean isReadable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    return true;
+  }
+
+  @Override
+  public Application readFrom(Class<Application> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+      throws IOException, WebApplicationException {
+    return null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java
new file mode 100644
index 0000000..8e83069
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/ApplicationServlet.java
@@ -0,0 +1,90 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.util.Map;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Response;
+
+@Path("ApplicationTest")
+public class ApplicationServlet {
+
+  @GET
+  @Path("/GetSingletons")
+  public Response testGetSingletons(@Context Application application) {
+    // Derived from the default, thus return empty implementation
+    if (application.getSingletons() == null)
+      return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+    // Passed
+    return Response.ok(String.valueOf(application.getSingletons().size()))
+        .build();
+  }
+
+  @GET
+  @Path("/GetClasses")
+  public Response testGetClasses(@Context Application application) {
+    // Context Issue
+    application = getDeproxiedApplication(application);
+    if (!application.getClasses().contains(ApplicationServlet.class))
+      return Response.status(Response.Status.NOT_ACCEPTABLE).build();
+    // Passed
+    return Response.ok(String.valueOf(application.getClasses().size())).build();
+  }
+
+  @Path("properties")
+  @GET
+  public Response getProperties(@Context Application application) {
+    Response response = null;
+    application = getDeproxiedApplication(application);
+    Map<String, Object> properties = application.getProperties();
+    if (properties == null || properties.size() == 0) {
+      response = Response.noContent().build();
+    } else {
+      Object val0 = properties.get(TSAppConfig.KEYS[0]);
+      Object val1 = properties.get(TSAppConfig.KEYS[1]);
+      if (TSAppConfig.VALUES[0].equals(val0)
+          && TSAppConfig.VALUES[1].equals(val1))
+        response = Response.ok(JaxrsUtil.mapToString(properties)).build();
+      else
+        response = Response.status(Response.Status.NOT_ACCEPTABLE).build();
+    }
+    return response;
+  }
+
+  // ////////////////////////////////////////////////////////////////////////
+
+  /**
+   * Deproxy
+   */
+  protected static Application getDeproxiedApplication(
+      Application application) {
+    Set<Object> singletons = application.getSingletons();
+    for (Object s : singletons)
+      if (s.getClass() == ApplicationHolderSingleton.class)
+        return ((ApplicationHolderSingleton) s).getApplication();
+    throw new IllegalStateException(
+        "ApplicationHolderSingleton has not been found in a list of singletons");
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java
new file mode 100644
index 0000000..6340618
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/JAXRSClientIT.java
@@ -0,0 +1,169 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.io.IOException;
+import java.util.Map;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response.Status;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+  
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_application_web/ApplicationTest");
+  }
+
+  private static final long serialVersionUID = 1L;
+
+  protected int expectedSingletons = 1;
+
+  protected int expectedClasses = 1;
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_application_web.war");
+    archive.addClasses(TSAppConfig.class, ApplicationServlet.class, ApplicationHolderSingleton.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /*
+   * @testName: getSingletonsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:23
+   * 
+   * @test_Strategy: Check that vi does not modify the getSingletons()
+   */
+  @Test
+  public void getSingletonsTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "GetSingletons"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+    assertTrue(getReturnedNumber() == expectedSingletons,
+        "Application.getSingletons() return incorrect value:"+
+        getReturnedNumber());
+  }
+
+  /*
+   * @testName: getClassesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:22; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check the implementation injects TSAppConfig
+   */
+  @Test
+  public void getClassesTest() throws Fault {
+    setProperty(REQUEST, buildRequest(GET, "GetClasses"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+    assertTrue(getReturnedNumber() == expectedClasses,
+        "Application.getClasses() return incorrect value:"+
+        getReturnedNumber());
+  }
+
+  /*
+   * @testName: getPropertiesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1035; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: The returned properties are reflected in the application
+   * configuration passed to the server-side features or injected into
+   * server-side JAX-RS components.
+   */
+  @Test
+  public void getPropertiesTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "properties"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    setProperty(Property.SEARCH_STRING, TSAppConfig.KEYS[0]);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultGetPropertiesIsEmptyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1035;
+   * 
+   * @test_Strategy: The default implementation returns an empty set.
+   */
+  @Test
+  public void defaultGetPropertiesIsEmptyTest() throws Fault {
+    Application application = new Application();
+    Map<String, Object> properties = application.getProperties();
+    assertNotNull(properties,
+        "Default implementation is not empty map, but null");
+    assertTrue(properties.isEmpty(), "Default implementation is not empty, but"+
+        JaxrsUtil.mapToString(properties));
+    logMsg("Default implementation gets empty map as expected");
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+
+  protected int getReturnedNumber() throws Fault {
+    HttpResponse response = _testCase.getResponse();
+    String body;
+    try {
+      body = response.getResponseBodyAsString();
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+    return Integer.parseInt(body);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java
new file mode 100644
index 0000000..91ecf49
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/application/TSAppConfig.java
@@ -0,0 +1,56 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.application;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+  static final String[] KEYS = { "key1", "key2" };
+
+  static final String[] VALUES = { "value1", "value2" };
+
+  private Map<String, Object> properties = new TreeMap<String, Object>();
+
+  public TSAppConfig() {
+    properties.put(KEYS[0], VALUES[0]);
+    properties.put(KEYS[1], VALUES[1]);
+  }
+
+  @Override
+  public Set<Object> getSingletons() {
+    Set<Object> set = new HashSet<Object>();
+    set.add(new ApplicationHolderSingleton(this));
+    return set;
+  }
+
+  @Override
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(ApplicationServlet.class);
+    return resources;
+  }
+
+  @Override
+  public Map<String, Object> getProperties() {
+    return properties;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java
new file mode 100644
index 0000000..51acda4
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/FirstFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.io.IOException;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class FirstFilter implements ClientRequestFilter {
+
+  @Override
+  public void filter(ClientRequestContext requestContext) throws IOException {
+    requestContext.setEntity(getClass().getName(), null,
+        MediaType.WILDCARD_TYPE);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java
new file mode 100644
index 0000000..7235422
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/JAXRSClientIT.java
@@ -0,0 +1,1280 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.core.configurable.Assertable;
+import jakarta.ws.rs.tck.api.rs.core.configurable.CallableProvider;
+import jakarta.ws.rs.tck.api.rs.core.configurable.Registrar;
+import jakarta.ws.rs.tck.api.rs.core.configurable.SingleCheckAssertable;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -8051302528257391040L;
+
+  private static final int configurableCnt = 2;
+
+  private int registeredClassesCnt = -1;
+
+  private int registeredInstancesCnt = -1;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_configurable_web/resource");
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_configurable_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class, Assertable.class, CallableProvider.class, Registrar.class, SingleCheckAssertable.class, jakarta.ws.rs.tck.api.rs.core.configurable.ConfigurableObject.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: registerClassWriterContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Class) except the JAX-RS component class is only registered as a
+   * provider of the listed extension provider or meta-provider contracts.
+   */
+  @Test
+  public void registerClassWriterContractsTest() throws Fault {
+    final String content = "registerClassWriterContractsTest";
+
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = getCallableEntity(content);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register((Class<?>) registerable, MessageBodyWriter.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 1);
+
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      Response response = i.invoke();
+      response.bufferEntity();
+      String responseString = response.readEntity(String.class);
+      assertEquals(content, responseString, "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully wrote Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+      // check message body reader contract
+      try {
+        Callable<?> callable = response.readEntity(Callable.class);
+        fault("MessageBodyReader contract has been unexpectedly registered",
+            callable);
+      } catch (Exception e) {
+        logMsg("MessageBodyReader contract has not been registered as expected",
+            e);
+      }
+    }
+  }
+
+  /*
+   * @testName: registerClassReaderContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Class) except the JAX-RS component class is only registered as a
+   * provider of the listed extension provider or meta-provider contracts.
+   */
+  @Test
+  public void registerClassReaderContractsTest() throws Fault {
+    final String content = "registerClassReaderContractsTest";
+
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register((Class<?>) registerable, MessageBodyReader.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 1);
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      Response response = i.invoke();
+      Callable<?> callable = response.readEntity(Callable.class);
+      assertEquals(content, callable.toString(), "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully read Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+    }
+  }
+
+  /*
+   * @testName: registerClassEmptyContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: Implementations MUST ignore attempts to register a
+   * component class for an empty collection of contracts via this method and
+   * SHOULD raise a warning about such event.
+   */
+  @Test
+  public void registerClassEmptyContractsTest() throws Fault {
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register((Class<?>) registerable, new Class<?>[] {});
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProvider();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, classes, entity);
+      logMsg("The provider of with contracts has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassNotAssignableContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: Contracts that are not assignable from the registered
+   * component class MUST be ignored
+   */
+  @Test
+  public void registerClassNotAssignableContractsTest() throws Fault {
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register((Class<?>) registerable, ClientRequestFilter.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProvider();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, classes, entity);
+      logMsg(
+          "The provider with unassignable contract has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassNullContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:756;
+   * 
+   * @test_Strategy: Implementations MUST ignore attempts to register a
+   * component class for a null collection of contracts via this method and
+   * SHOULD raise a warning about such event.
+   */
+  @Test
+  public void registerClassNullContractsTest() throws Fault {
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register((Class<?>) registerable, (Class<?>[]) null);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProvider();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, classes, entity);
+      logMsg("The provider with null contract has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassBindingPriorityFirstIsSecondTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:755;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Class) except that any binding priority specified on the
+   * registered JAX-RS component class via
+   * 
+   * @Priority annotation is overridden with the supplied bindingPriority value.
+   */
+  @Test
+  public void registerClassBindingPriorityFirstIsSecondTest() throws Fault {
+    final String content = "registerClassBindingPriorityFirstIsSecondTest";
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          config.register(FirstFilter.class, 400);
+          config.register(SecondFilter.class, 399);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 2);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      String response = i.invoke(String.class);
+      assertEquals(FirstFilter.class.getName(), response,
+          "Unexpected filter ordering, the last was", response);
+      logMsg(response, "has been executed as second, as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassBindingPriorityFirstIsFirstTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:755;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Class) except that any binding priority specified on the
+   * registered JAX-RS component class via
+   * 
+   * @Priority annotation is overridden with the supplied bindingPriority value.
+   */
+  @Test
+  public void registerClassBindingPriorityFirstIsFirstTest() throws Fault {
+    final String content = "registerClassBindingPriorityFirstIsFirstTest";
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          config.register(FirstFilter.class, 300);
+          config.register(SecondFilter.class, 399);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 2);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      String response = i.invoke(String.class);
+      assertEquals(SecondFilter.class.getName(), response,
+          "Unexpected filter ordering, the last was", response);
+      logMsg(response, "has been executed as second, as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectBindingPriorityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:759;
+   * 
+   * @test_Strategy: Any binding priority specified on the registered JAX-RS
+   * component class via
+   * 
+   * @Priority annotation is overridden with the supplied bindingPriority value.
+   */
+  @Test
+  public void registerObjectBindingPriorityTest() throws Fault {
+    final String content = "registerObjectBindingPriorityTest";
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          config.register(new FirstFilter(), 400);
+          config.register(new SecondFilter(), 399);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 2);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      String response = i.invoke(String.class);
+      assertEquals(FirstFilter.class.getName(), response,
+          "Unexpected filter ordering, the last was", response);
+      logMsg(response, "has been executed as second, as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectWriterContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:760;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Object) except the JAX-RS component class is only registered as a
+   * provider of the listed extension provider or meta-provider contracts.
+   */
+  @Test
+  public void registerObjectWriterContractsTest() throws Fault {
+    final String content = "registerObjectWriterContractsTest";
+
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = getCallableEntity(content);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register(registerable, MessageBodyWriter.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 1);
+
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, instances, entity);
+      Response response = i.invoke();
+      response.bufferEntity();
+      String responseString = response.readEntity(String.class);
+      assertEquals(content, responseString, "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully wrote Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+      // check message body reader contract
+      try {
+        Callable<?> callable = response.readEntity(Callable.class);
+        fault("MessageBodyReader contract has been unexpectedly registered",
+            callable);
+      } catch (Exception e) {
+        logMsg("MessageBodyReader contract has not been registered as expected",
+            e);
+      }
+    }
+  }
+
+  /*
+   * @testName: registerObjectReaderContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:760;
+   * 
+   * @test_Strategy: This registration method provides the same functionality as
+   * register(Object) except the JAX-RS component class is only registered as a
+   * provider of the listed extension provider or meta-provider contracts.
+   */
+  @Test
+  public void registerObjectReaderContractsTest() throws Fault {
+    final String content = "registerClassReaderContractsTest";
+
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register(registerable, MessageBodyReader.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 1);
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, instances, entity);
+      Response response = i.invoke();
+      Callable<?> callable = response.readEntity(Callable.class);
+      assertEquals(content, callable.toString(), "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully read Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+    }
+  }
+
+  /*
+   * @testName: registerObjectEmptyContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:760;
+   * 
+   * @test_Strategy: Implementations MUST ignore attempts to register a
+   * component class for an empty collection of contracts via this method and
+   * SHOULD raise a warning about such event.
+   */
+  @Test
+  public void registerObjectEmptyContractsTest() throws Fault {
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register(registerable, new Class<?>[] {});
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, instances, entity);
+      logMsg("The provider with empty contracts has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectNotAssignableContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:760;
+   * 
+   * @test_Strategy: Contracts that are not assignable from the registered
+   * component class MUST be ignored
+   */
+  @Test
+  public void registerObjectNotAssignableContractsTest() throws Fault {
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register(registerable, ClientRequestFilter.class);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, instances, entity);
+      logMsg(
+          "The provider withO unassignable contract has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectNullContractsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:760;
+   * 
+   * @test_Strategy: Implementations MUST ignore attempts to register a
+   * component class for a null collection of contracts via this method and
+   * SHOULD raise a warning about such event.
+   */
+  @Test
+  public void registerObjectNullContractsTest() throws Fault {
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue)
+          config.register(registerable, (Class<?>[]) null);
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProvider();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, instances, entity);
+      logMsg("The provider with null contract has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassWriterContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:989;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Class, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerClassWriterContractsInMapTest() throws Fault {
+    final String content = "registerClassWriterContractsInMapTest";
+
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = getCallableEntity(content);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(MessageBodyWriter.class, 100);
+          config.register((Class<?>) registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 1);
+
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      Response response = i.invoke();
+      response.bufferEntity();
+      String responseString = response.readEntity(String.class);
+      assertEquals(content, responseString, "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully wrote Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+      // check message body reader contract
+      try {
+        Callable<?> callable = response.readEntity(Callable.class);
+        fault("MessageBodyReader contract has been unexpectedly registered",
+            callable);
+      } catch (Exception e) {
+        logMsg("MessageBodyReader contract has not been registered as expected",
+            e);
+      }
+    }
+  }
+
+  /*
+   * @testName: registerClassReaderContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:989;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Class, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerClassReaderContractsInMapTest() throws Fault {
+    final String content = "registerClassReaderContractsInMapTest";
+
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(MessageBodyReader.class, 100);
+          config.register((Class<?>) registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 1);
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      Response response = i.invoke();
+      Callable<?> callable = response.readEntity(Callable.class);
+      assertEquals(content, callable.toString(), "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully read Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+    }
+  }
+
+  /*
+   * @testName: registerClassBindingPriorityInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:989;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Class, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerClassBindingPriorityInMapTest() throws Fault {
+    final String content = "registerClassBindingPriorityInMapTest";
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(ClientRequestFilter.class, 400);
+          config.register(FirstFilter.class, contracts);
+          contracts.clear();
+          contracts.put(ClientRequestFilter.class, 300);
+          config.register(SecondFilter.class, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Assertable assertable = getAssertableWithRegisteredProviderClassesOnConfigurable(
+          cnt, 2);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      String response = i.invoke(String.class);
+      assertEquals(FirstFilter.class.getName(), response,
+          "Unexpected filter ordering, the last was", response);
+      logMsg(response, "has been executed as second, as expected");
+    }
+  }
+
+  /*
+   * @testName: registerClassNotAssignableContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:989;
+   * 
+   * @test_Strategy: Contracts that are not assignable from the registered
+   * component class MUST be ignored
+   */
+  @Test
+  public void registerClassNotAssignableContractsInMapTest() throws Fault {
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(ClientRequestFilter.class, 400);
+          config.register((Class<?>) registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, classes, entity);
+      logMsg(
+          "The provider with unassignable contract has ben ignored as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectWriterContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:990;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Object, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerObjectWriterContractsInMapTest() throws Fault {
+    final String content = "registerObjectWriterContractsInMapTest";
+
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = getCallableEntity(content);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(MessageBodyWriter.class, 100);
+          config.register(registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 1);
+
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, instances, entity);
+      Response response = i.invoke();
+      response.bufferEntity();
+      String responseString = response.readEntity(String.class);
+      assertEquals(content, responseString, "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully wrote Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+      // check message body reader contract
+      try {
+        Callable<?> callable = response.readEntity(Callable.class);
+        fault("MessageBodyReader contract has been unexpectedly registered",
+            callable);
+      } catch (Exception e) {
+        logMsg("MessageBodyReader contract has not been registered as expected",
+            e);
+      }
+    }
+  }
+
+  /*
+   * @testName: registerObjectReaderContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:990;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Object, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerObjectReaderContractsInMapTest() throws Fault {
+    final String content = "registerObjectReaderContractsInMapTest";
+
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(MessageBodyReader.class, 100);
+          config.register(registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 1);
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Invocation i = checkConfig(registrar, assertable, instances, entity);
+      Response response = i.invoke();
+      Callable<?> callable = response.readEntity(Callable.class);
+      assertEquals(content, callable.toString(), "Expected", content,
+          "differs from given", response);
+      logMsg(
+          "sucessufully read Callable by provider registered on Configurable",
+          Assertable.getLocation(cnt));
+    }
+  }
+
+  /*
+   * @testName: registerObjectBindingPriorityInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:990;
+   * 
+   * @test_Strategy: This registration method provides same functionality as
+   * register(Object, Class[]) except that any binding priority specified on the
+   * registered JAX-RS component class using @Priority annotation is overridden
+   * for each extension provider contract type separately with an integer
+   * binding priority value specified as a value in the supplied map.
+   */
+  @Test
+  public void registerObjectBindingPriorityInMapTest() throws Fault {
+    final String content = "registerObjectBindingPriorityInMapTest";
+    Class<?>[] classes = createProviderClasses();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity(content, MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(ClientRequestFilter.class, 400);
+          config.register(new FirstFilter(), contracts);
+          contracts.clear();
+          contracts.put(ClientRequestFilter.class, 300);
+          config.register(new SecondFilter(), contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      Assertable assertable = getAssertableWithRegisteredProviderInstancesOnConfigurable(
+          cnt, 2);
+      Invocation i = checkConfig(registrar, assertable, classes, entity);
+      String response = i.invoke(String.class);
+      assertEquals(FirstFilter.class.getName(), response,
+          "Unexpected filter ordering, the last was", response);
+      logMsg(response, "has been executed as second, as expected");
+    }
+  }
+
+  /*
+   * @testName: registerObjectNotAssignableContractsInMapTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:990;
+   * 
+   * @test_Strategy: Contracts that are not assignable from the registered
+   * component class MUST be ignored
+   */
+  @Test
+  public void registerObjectNotAssignableContractsInMapTest() throws Fault {
+    Object[] instances = createProviderInstances();
+    // entity to send to a server
+    Entity<?> entity = Entity.entity("", MediaType.WILDCARD);
+
+    // register only once per client build
+    IncrementableRegistrar registrar = new IncrementableRegistrar(0, 1) {
+      @Override
+      public void register(Configurable<?> config, Object registerable) {
+        if (currentValue++ == finalValue) {
+          Map<Class<?>, Integer> contracts = new HashMap<Class<?>, Integer>();
+          contracts.put(ClientRequestFilter.class, 400);
+          config.register(registerable, contracts);
+        }
+      }
+    };
+
+    setResourceMethod("echo");
+    // build client configurableCnt times to register provider using a
+    // different
+    // configurable each time
+    Assertable assertable = getAssertableWithNoRegisteredProviderInstance();
+    for (int cnt = 0; cnt != configurableCnt; cnt++) {
+      // Check the provider is registered
+      logMsg("Check on Configurable", Assertable.getLocation(cnt));
+      // set we want to register the provider on Configurable
+      // Assertable::LOCATION[cnt]
+      registrar.setCurrentValue(0).setFinalValue(cnt);
+      checkConfig(registrar, assertable, instances, entity);
+      logMsg(
+          "The provider with unassignable contract has ben ignored as expected");
+    }
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+  private Assertable getAssertableWithRegisteredProviderClassesOnConfigurable(
+      final int configurableIndex, final int numberOfRegisteredClasses) {
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int size = config.getConfiguration().getClasses().size();
+        int shouldBe = getLocationIndex() >= configurableIndex
+            ? numberOfRegisteredClasses
+            : 0;
+        shouldBe += registeredClassesCnt;
+        assertEqualsInt(size, shouldBe,
+            "unexpected number of registered classes found:", size,
+            getLocation());
+        logMsg("Found", size, "provider(s) as expected");
+      }
+    };
+    return assertable;
+  }
+
+  private Assertable getAssertableWithRegisteredProviderInstancesOnConfigurable(
+      final int configurableIndex, final int numberOfRegisteredInstances) {
+    Assertable assertable = new SingleCheckAssertable() {
+      @Override
+      protected void check(Configurable<?> configurable) throws Fault {
+        assertSizeAndLog(configurable);
+      }
+
+      void assertSizeAndLog(Configurable<?> config) throws Fault {
+        int size = config.getConfiguration().getInstances().size();
+        int shouldBe = getLocationIndex() >= configurableIndex
+            ? numberOfRegisteredInstances
+            : 0;
+        shouldBe += registeredInstancesCnt;
+        assertEqualsInt(size, shouldBe,
+            "unexpected number of registered classes found:", size,
+            getLocation());
+        logMsg("Found", size, "provider(s) as expected");
+      }
+    };
+    return assertable;
+  }
+
+  private Assertable getAssertableWithNoRegisteredProvider() {
+    return getAssertableWithRegisteredProviderClassesOnConfigurable(0, 0);
+  }
+
+  private Assertable getAssertableWithNoRegisteredProviderInstance() {
+    return getAssertableWithRegisteredProviderInstancesOnConfigurable(0, 0);
+  }
+
+  /**
+   * Provider has to not be anonymous class, because we need @Provider
+   * annotation there
+   */
+  protected Object[] createProviderInstances() {
+    Object[] instances = new CallableProvider[] { new CallableProvider() {
+    }, new CallableProvider() {
+    } };
+    return instances;
+  }
+
+  protected static Class<?>[] createProviderClasses() {
+    Class<?>[] classes = new Class<?>[] { CallableProvider.class,
+        CallableProvider.class };
+    return classes;
+  }
+
+  protected Invocation checkConfig(Registrar registrar, Assertable assertable,
+      Object[] registerables, Entity<?> entity) throws Fault {
+    Client client = ClientBuilder.newClient();
+    Configuration config = client.getConfiguration();
+    registeredClassesCnt = config.getClasses().size();
+    registeredInstancesCnt = config.getInstances().size();
+    logMsg("Already registered", registeredClassesCnt, "classes");
+    logMsg("Already registered", registeredInstancesCnt, "instances");
+
+    register(registrar, client, registerables[0]);
+    assertable.check1OnClient(client);
+    assertable.incrementLocation();
+
+    WebTarget target = client.target(getAbsoluteUrl());
+    register(registrar, target, registerables[1]);
+    assertable.check2OnTarget(target);
+    assertable.incrementLocation();
+
+    Invocation.Builder builder = target.request();
+    Invocation invocation = builder.buildPost(entity);
+    return invocation;
+  }
+
+  protected void register(Registrar registrar, Configurable<?> config,
+      Object registerable) {
+    registrar.register(config, registerable);
+  }
+
+  protected class IncrementableRegistrar extends Registrar {
+    int currentValue;
+
+    int finalValue;
+
+    int getFinalValue() {
+      return finalValue;
+    }
+
+    IncrementableRegistrar setFinalValue(int finalValue) {
+      this.finalValue = finalValue;
+      return this;
+    }
+
+    IncrementableRegistrar(int initValue, int finalValue) {
+      currentValue = initValue;
+      this.finalValue = finalValue;
+    }
+
+    int getCurrentValue() {
+      return currentValue;
+    }
+
+    IncrementableRegistrar setCurrentValue(int set) {
+      currentValue = set;
+      return this;
+    }
+  }
+
+  private void setResourceMethod(String method) {
+    setContextRoot(getContextRoot() + "/" + method);
+  }
+
+  private static Entity<?> getCallableEntity(final String content) {
+    Entity<?> entity = Entity.entity(CallableProvider.createCallable(content),
+        MediaType.WILDCARD_TYPE);
+    return entity;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java
new file mode 100644
index 0000000..b8f2c16
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/Resource.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+  @POST
+  @Path("echo")
+  public String echo(String value) {
+    return value;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java
new file mode 100644
index 0000000..52d78ab
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/SecondFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+import java.io.IOException;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class SecondFilter implements ClientRequestFilter {
+
+  @Override
+  public void filter(ClientRequestContext requestContext) throws IOException {
+    requestContext.setEntity(getClass().getName(), null,
+        MediaType.WILDCARD_TYPE);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java
new file mode 100644
index 0000000..c2f52f2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configurable/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configurable;
+
+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/configuration/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configuration/JAXRSClientIT.java
new file mode 100644
index 0000000..459ab7f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/configuration/JAXRSClientIT.java
@@ -0,0 +1,550 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.configuration;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.io.InputStream;
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.core.configurable.Assertable;
+import jakarta.ws.rs.tck.api.rs.core.configurable.Registrar;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+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.WebTarget;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.Feature;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.MediaType;
+
+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.assertFalse;
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+
+/**
+ * <p>
+ * These tests follow the intended JAXRS rule to enable Features in the order of
+ * them being registered. By this rule, it is possible to check the previous
+ * Feature has been / has not been enabled.
+ * </p>
+ * 
+ * <p>
+ * The isEnabled works only in runtime which has its own version of
+ * configuration, i.e. it does not work on Configurable.getConfiguration()
+ * </p>
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 7215781408688132392L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_configuration_web/resource/echo");
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_configuration_web.war");
+    archive.addClasses(jakarta.ws.rs.tck.ee.rs.core.configurable.Resource.class,
+      jakarta.ws.rs.tck.ee.rs.core.configurable.TSAppConfig.class,
+      jakarta.ws.rs.tck.api.rs.core.configurable.Assertable.class, 
+      jakarta.ws.rs.tck.api.rs.core.configurable.Registrar.class, 
+      jakarta.ws.rs.tck.api.rs.core.configurable.CallableProvider.class, 
+      jakarta.ws.rs.tck.api.rs.core.configurable.SingleCheckAssertable.class, 
+      jakarta.ws.rs.tck.api.rs.core.configurable.ConfigurableObject.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: isEnabledFeatureReturningFalseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:999; JAXRS:JAVADOC:1003;
+   * 
+   * @test_Strategy: Check if a feature instance of featureClass class has been
+   * previously enabled in the runtime configuration context.
+   * 
+   * Returns true if the feature was successfully enabled, false otherwise
+   */
+  @Test
+  public void isEnabledFeatureReturningFalseTest() throws Fault {
+    final CheckingFeature feature1 = new FeatureReturningFalse1();
+    final CheckingFeature feature2 = new FeatureReturningFalse2();
+    final CheckingFeature feature3 = new FeatureReturningFalse3();
+    final CheckingFeature feature4 = new FeatureReturningFalse4();
+
+    feature1.addDisabledFeatures(feature2, feature3, feature4)
+        .setName("feature1");
+    feature2.addDisabledFeatures(feature1, feature3, feature4)
+        .setName("feature2");
+    feature3.addDisabledFeatures(feature1, feature2, feature4)
+        .setName("feature3");
+    feature4.addDisabledFeatures(feature1, feature2, feature3)
+        .setName("feature4");
+
+    Assertable assertable = new Assertable() {
+      @Override
+      public void check1OnClient(Client client) throws Fault {
+        assertIsDisabled(client, feature1);
+        assertIsDisabled(client, feature2);
+        assertIsDisabled(client, feature3);
+        assertIsDisabled(client, feature4);
+      }
+
+      @Override
+      public void check2OnTarget(WebTarget target) throws Fault {
+        assertIsDisabled(target, feature1);
+        assertIsDisabled(target, feature2);
+        assertIsDisabled(target, feature3);
+        assertIsDisabled(target, feature4);
+      }
+
+      void assertIsDisabled(Configurable<?> config, CheckingFeature feature)
+          throws Fault {
+        boolean isEnabled = config.getConfiguration().isEnabled(feature);
+        assertFalse(isEnabled, "Feature"+ feature.getName()+
+            "is unexpectedly enabled"+ getLocation());
+        logMsg("No feature enabled as expected", getLocation());
+      }
+    };
+    Object[] instances = { feature1, feature2, feature3, feature4 };
+    checkConfig(assertable, instances);
+    logMsg(
+        "The provider with unassignable contract has ben ignored as expected");
+  }
+
+  /*
+   * @testName: isEnabledFeatureReturningTrueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:999; JAXRS:JAVADOC:1003;
+   * 
+   * @test_Strategy: Check if a feature instance of featureClass class has been
+   * previously enabled in the runtime configuration context.
+   * 
+   * Returns true if the feature was successfully enabled, false otherwise
+   */
+  @Test
+  public void isEnabledFeatureReturningTrueTest() throws Fault {
+    final CheckingFeature feature1 = new FeatureReturningTrue1();
+    final CheckingFeature feature2 = new FeatureReturningTrue2();
+    final CheckingFeature feature3 = new FeatureReturningTrue3();
+    final CheckingFeature feature4 = new FeatureReturningTrue4();
+
+    feature1.addDisabledFeatures(feature2, feature3, feature4)
+        .setName("feature1");
+    feature2.addDisabledFeatures(feature3, feature4)
+        .addEnabledFeatures(feature1).setName("feature2");
+    feature3.addDisabledFeatures(feature4)
+        .addEnabledFeatures(feature1, feature2).setName("feature3");
+    feature4.addEnabledFeatures(feature1, feature2, feature3)
+        .setName("feature4");
+
+    Assertable assertable = new Assertable() {
+      @Override
+      public void check1OnClient(Client client) throws Fault {
+        assertIsRegistered(client, feature1);
+        assertIsNotRegistered(client, feature2);
+        assertIsNotRegistered(client, feature3);
+        assertIsNotRegistered(client, feature4);
+      }
+
+      @Override
+      public void check2OnTarget(WebTarget target) throws Fault {
+        assertIsRegistered(target, feature1);
+        assertIsRegistered(target, feature2);
+        assertIsNotRegistered(target, feature3);
+        assertIsNotRegistered(target, feature4);
+      }
+
+      void assertIsRegistered(Configurable<?> config, CheckingFeature feature)
+          throws Fault {
+        Configuration configuration = config.getConfiguration();
+        assertTrue(configuration.isRegistered(feature), "Feature"+
+            feature.getName()+ "is NOT registered"+ getLocation());
+        logMsg("Feature", feature.getName(), "registered as expected",
+            getLocation());
+      }
+
+      void assertIsNotRegistered(Configurable<?> config,
+          CheckingFeature feature) throws Fault {
+        Configuration configuration = config.getConfiguration();
+        assertFalse(configuration.isRegistered(feature), "Feature"+
+            feature.getName()+ "is unexpectedly registered"+ getLocation());
+        logMsg("Feature", feature.getName(), "NOT registered as expected",
+            getLocation());
+      }
+
+    };
+    Object[] instances = { feature1, feature2, feature3, feature4 };
+    checkConfig(assertable, instances);
+    logMsg(
+        "The provider with unassignable contract has ben ignored as expected");
+  }
+
+  /*
+   * @testName: isEnabledClassReturningFalseTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1000; JAXRS:JAVADOC:1003;
+   * 
+   * @test_Strategy: Check if a feature instance of featureClass class has been
+   * previously enabled in the runtime configuration context.
+   * 
+   * Returns true if the feature was successfully enabled, false otherwise
+   */
+  @SuppressWarnings("unchecked")
+  @Test
+  public void isEnabledClassReturningFalseTest() throws Fault {
+    final CheckingFeature feature1 = new FeatureReturningFalse1();
+    final CheckingFeature feature2 = new FeatureReturningFalse2();
+    final CheckingFeature feature3 = new FeatureReturningFalse3();
+    final CheckingFeature feature4 = new FeatureReturningFalse4();
+
+    feature1
+        .addDisabledClasses(FeatureReturningFalse2.class,
+            FeatureReturningFalse3.class, FeatureReturningFalse4.class)
+        .setName("feature1");
+    feature2
+        .addDisabledClasses(FeatureReturningFalse1.class,
+            FeatureReturningFalse3.class, FeatureReturningFalse4.class)
+        .setName("feature2");
+    feature3
+        .addDisabledClasses(FeatureReturningFalse1.class,
+            FeatureReturningFalse2.class, FeatureReturningFalse4.class)
+        .setName("feature3");
+    feature4
+        .addDisabledClasses(FeatureReturningFalse1.class,
+            FeatureReturningFalse2.class, FeatureReturningFalse3.class)
+        .setName("feature4");
+
+    Assertable assertable = new Assertable() {
+      @Override
+      public void check1OnClient(Client client) throws Fault {
+        assertIsDisabled(client, feature1);
+        assertIsDisabled(client, feature2);
+        assertIsDisabled(client, feature3);
+        assertIsDisabled(client, feature4);
+      }
+
+      @Override
+      public void check2OnTarget(WebTarget target) throws Fault {
+        assertIsDisabled(target, feature1);
+        assertIsDisabled(target, feature2);
+        assertIsDisabled(target, feature3);
+        assertIsDisabled(target, feature4);
+      }
+
+      void assertIsDisabled(Configurable<?> config, CheckingFeature feature)
+          throws Fault {
+        boolean isEnabled = config.getConfiguration().isEnabled(feature);
+        assertFalse(isEnabled, "Feature"+ feature.getName()+
+            "is unexpectedly enabled"+ getLocation());
+        logMsg("No feature enabled as expected", getLocation());
+      }
+    };
+    Object[] instances = { feature1, feature2, feature3, feature4 };
+    checkConfig(assertable, instances);
+    logMsg(
+        "The provider with unassignable contract has ben ignored as expected");
+  }
+
+  /*
+   * @testName: isEnabledFeatureClassReturningTrueTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1000; JAXRS:JAVADOC:1003;
+   * 
+   * @test_Strategy: Check if a feature instance of featureClass class has been
+   * previously enabled in the runtime configuration context.
+   * 
+   * Returns true if the feature was successfully enabled, false otherwise
+   */
+  @SuppressWarnings("unchecked")
+  @Test
+  public void isEnabledFeatureClassReturningTrueTest() throws Fault {
+    final CheckingFeature feature1 = new FeatureReturningTrue1();
+    final CheckingFeature feature2 = new FeatureReturningTrue2();
+    final CheckingFeature feature3 = new FeatureReturningTrue3();
+    final CheckingFeature feature4 = new FeatureReturningTrue4();
+
+    feature1
+        .addDisabledClasses(FeatureReturningTrue2.class,
+            FeatureReturningTrue3.class, FeatureReturningTrue4.class)
+        .setName("feature1");
+    feature2
+        .addDisabledClasses(FeatureReturningTrue3.class,
+            FeatureReturningTrue4.class)
+        .addEnabledClasses(FeatureReturningTrue1.class).setName("feature2");
+    feature3.addDisabledClasses(FeatureReturningTrue4.class)
+        .addEnabledClasses(FeatureReturningTrue1.class,
+            FeatureReturningTrue2.class)
+        .setName("feature3");
+    feature4
+        .addEnabledClasses(FeatureReturningTrue1.class,
+            FeatureReturningTrue2.class, FeatureReturningTrue3.class)
+        .setName("feature4");
+
+    Assertable assertable = new Assertable() {
+      @Override
+      public void check1OnClient(Client client) throws Fault {
+        assertIsRegistered(client, feature1);
+        assertIsNotRegistered(client, feature2);
+        assertIsNotRegistered(client, feature3);
+        assertIsNotRegistered(client, feature4);
+      }
+
+      @Override
+      public void check2OnTarget(WebTarget target) throws Fault {
+        assertIsRegistered(target, feature1);
+        assertIsRegistered(target, feature2);
+        assertIsNotRegistered(target, feature3);
+        assertIsNotRegistered(target, feature4);
+      }
+
+      void assertIsRegistered(Configurable<?> config, CheckingFeature feature)
+          throws Fault {
+        Configuration configuration = config.getConfiguration();
+        assertTrue(configuration.isRegistered(feature), "Feature"+
+            feature.getName()+ "is NOT registered"+ getLocation());
+        logMsg("Feature", feature.getName(), "registered as expected",
+            getLocation());
+      }
+
+      void assertIsNotRegistered(Configurable<?> config,
+          CheckingFeature feature) throws Fault {
+        Configuration configuration = config.getConfiguration();
+        assertFalse(configuration.isRegistered(feature), "Feature"+
+            feature.getName()+ "is unexpectedly registered"+ getLocation());
+        logMsg("Feature", feature.getName(), "NOT registered as expected",
+            getLocation());
+      }
+
+    };
+    Object[] instances = { feature1, feature2, feature3, feature4 };
+    checkConfig(assertable, instances);
+    logMsg(
+        "The provider with unassignable contract has ben ignored as expected");
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+
+  /**
+   * Check on every possible setting of configuration by a Feature or a
+   * singleton
+   * 
+   */
+  protected void checkConfig(Assertable assertable, Object[] registerables)
+      throws Fault {
+    checkConfig(new Registrar(), assertable, registerables);
+  }
+
+  protected void checkConfig(Registrar registrar, Assertable assertable,
+      Object[] registerables) throws Fault {
+    Entity<String> entity = Entity.entity("echo", MediaType.WILDCARD_TYPE);
+
+    Client client = ClientBuilder.newClient();
+    logMsg("Registering on Client");
+    register(registrar, client, registerables[0]);
+
+    WebTarget target = client.target(getAbsoluteUrl());
+    logMsg("Registering on WebTarget");
+    register(registrar, target, registerables[1]);
+
+    Invocation.Builder builder = target.request();
+    Invocation invocation = builder.buildPost(entity);
+
+    String response = invocation.invoke(String.class);
+    assertEquals(entity.getEntity(), response, "Unexpected response received",
+        response);
+
+    assertable.check1OnClient(client);
+    assertable.incrementLocation();
+    assertable.check2OnTarget(target);
+  }
+
+  protected void register(Registrar registrar, Configurable<?> config,
+      Object registerable) {
+    registrar.register(config, registerable);
+  }
+
+  // //////////////////////////////////////////////////////////////////////
+  private abstract class NamedFeature implements Feature {
+    String name;
+
+    public String getName() {
+      return name;
+    }
+
+    public NamedFeature setName(String name) {
+      this.name = name;
+      return this;
+    }
+  }
+
+  class CheckingFeature extends NamedFeature {
+    List<NamedFeature> enabledFeatures = new LinkedList<NamedFeature>();
+
+    List<NamedFeature> disabledFeatures = new LinkedList<NamedFeature>();
+
+    List<Class<? extends NamedFeature>> enabledFeatureClasses = new LinkedList<Class<? extends NamedFeature>>();
+
+    List<Class<? extends NamedFeature>> disabledFeatureClasses = new LinkedList<Class<? extends NamedFeature>>();
+
+    @Override
+    public boolean configure(FeatureContext context) {
+      for (NamedFeature feature : enabledFeatures) {
+        if (!context.getConfiguration().isEnabled(feature))
+          throw new RuntimeException(
+              "Feature " + feature.getName() + " has NOT been enabled");
+        logMsg("Feature", feature.getName(), "has been enabled as expected");
+      }
+      for (NamedFeature feature : disabledFeatures) {
+        if (context.getConfiguration().isEnabled(feature))
+          throw new RuntimeException("Feature " + feature.getName()
+              + " has been unexpectedly enabled");
+        logMsg("Feature", feature.getName(),
+            "has NOT been enabled as expected");
+      }
+      for (Class<? extends NamedFeature> feature : enabledFeatureClasses) {
+        if (!context.getConfiguration().isEnabled(feature))
+          throw new RuntimeException(
+              "Feature " + feature.getName() + " has NOT been enabled");
+        logMsg("Feature", feature.getName(), "has been enabled as expected");
+      }
+      for (Class<? extends NamedFeature> feature : disabledFeatureClasses) {
+        if (context.getConfiguration().isEnabled(feature))
+          throw new RuntimeException("Feature " + feature.getName()
+              + " has been unexpectedly enabled");
+        logMsg("Feature", feature.getName(),
+            "has NOT been enabled as expected");
+      }
+      return true;
+    }
+
+    public CheckingFeature addEnabledFeatures(NamedFeature... features) {
+      if (features != null)
+        for (NamedFeature feature : features)
+          enabledFeatures.add(feature);
+      return this;
+    }
+
+    public CheckingFeature addDisabledFeatures(NamedFeature... features) {
+      if (features != null)
+        for (NamedFeature feature : features)
+          disabledFeatures.add(feature);
+      return this;
+    }
+
+    public CheckingFeature addEnabledClasses(
+        Class<? extends NamedFeature>... features) {
+      if (features != null)
+        for (Class<? extends NamedFeature> feature : features)
+          enabledFeatureClasses.add(feature);
+      return this;
+    }
+
+    public CheckingFeature addDisabledClasses(
+        Class<? extends NamedFeature>... features) {
+      if (features != null)
+        for (Class<? extends NamedFeature> feature : features)
+          disabledFeatureClasses.add(feature);
+      return this;
+    }
+  }
+
+  private class FeatureReturningFalse extends CheckingFeature {
+    @Override
+    public boolean configure(FeatureContext context) {
+      super.configure(context);
+      // false returning feature is not to be registered
+      return false;
+    }
+  }
+
+  private class FeatureReturningTrue extends CheckingFeature {
+    @Override
+    public boolean configure(FeatureContext context) {
+      return super.configure(context);
+    }
+  }
+
+  private class FeatureReturningFalse1 extends FeatureReturningFalse {
+  };
+
+  private class FeatureReturningFalse2 extends FeatureReturningFalse {
+  };
+
+  private class FeatureReturningFalse3 extends FeatureReturningFalse {
+  };
+
+  private class FeatureReturningFalse4 extends FeatureReturningFalse {
+  };
+
+  private class FeatureReturningTrue1 extends FeatureReturningTrue {
+  };
+
+  private class FeatureReturningTrue2 extends FeatureReturningTrue {
+  };
+
+  private class FeatureReturningTrue3 extends FeatureReturningTrue {
+  };
+
+  private class FeatureReturningTrue4 extends FeatureReturningTrue {
+  };
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java
new file mode 100644
index 0000000..f37116e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/HttpHeadersTest.java
@@ -0,0 +1,208 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.Iterator;
+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.GET;
+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.Cookie;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+
+@Path(value = "/HeadersTest")
+public class HttpHeadersTest {
+
+  @Context
+  HttpHeaders hs;
+
+  StringBuffer sb;
+
+  @GET
+  @Path("/headers")
+  public String headersGet() {
+    sb = new StringBuffer();
+    List<String> myHeaders = Arrays.asList("Accept", "Content-Type");
+
+    try {
+      MultivaluedMap<String, String> rqhdrs = hs.getRequestHeaders();
+      Set<String> keys = rqhdrs.keySet();
+      sb.append("getRequestHeaders= ");
+      for (String header : myHeaders) {
+        if (keys.contains(header)) {
+          sb.append(
+              "Found " + header + ": " + hs.getRequestHeader(header) + "; ");
+        }
+      }
+    } catch (Throwable ex) {
+      sb.append("Unexpected exception thrown in getRequestHeaders: "
+          + ex.getMessage());
+      ex.printStackTrace();
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/acl")
+  public String aclGet() {
+    sb = new StringBuffer();
+    try {
+      sb.append("Accept-Language");
+
+      List<Locale> acl = hs.getAcceptableLanguages();
+      sb.append("getLanguage= ");
+      for (Locale tmp : acl) {
+        sb.append(langToString(tmp)).append("; ");
+      }
+    } catch (Throwable ex) {
+      sb.append("Unexpected exception thrown in getAcceptableLanguages: "
+          + ex.getMessage());
+      ex.printStackTrace();
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/amt")
+  public String amtGet() {
+    sb = new StringBuffer();
+    try {
+      sb.append("getAcceptableMediaTypes");
+      List<MediaType> acmts = hs.getAcceptableMediaTypes();
+
+      for (MediaType mt : acmts) {
+        sb.append(mt.getType());
+        sb.append("/");
+        sb.append(mt.getSubtype());
+      }
+    } catch (Throwable ex) {
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+      ex.printStackTrace();
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/mt")
+  public String mtGet() {
+    sb = new StringBuffer();
+
+    try {
+      sb.append("getMediaType");
+      MediaType mt = hs.getMediaType();
+      if (mt != null) {
+        sb.append(mt.getType());
+        sb.append("/");
+        sb.append(mt.getSubtype());
+        sb.append(" ");
+
+        java.util.Map<java.lang.String, java.lang.String> pmap = mt
+            .getParameters();
+
+        sb.append("MediaType size=" + pmap.size());
+
+        Iterator<Entry<String, String>> k = pmap.entrySet().iterator();
+        while (k.hasNext()) {
+          Entry<String, String> next = k.next();
+          String key = next.getKey();
+          sb.append("Key " + key + "; Value " + next.getValue());
+        }
+
+        sb.append(mt.toString());
+
+        sb.append("MediaType= " + mt.toString() + "; ");
+      } else {
+        sb.append("MediaType= null; ");
+      }
+    } catch (Throwable ex) {
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+      ex.printStackTrace();
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/cookie")
+  public String cookieGet() {
+    sb = new StringBuffer();
+
+    try {
+      sb.append("getCookies= ");
+      Map<String, Cookie> cookies = hs.getCookies();
+      sb.append("Cookie Size=" + cookies.size());
+
+      for (Entry<String, Cookie> entry : cookies.entrySet()) {
+        sb.append("key=" + entry.getKey() + "; value=" + entry.getValue());
+        Cookie c = entry.getValue();
+        sb.append("Cookie Name=" + c.getName());
+        sb.append("Cookie Value=" + c.getValue());
+        sb.append("Cookie Path=" + c.getPath());
+        sb.append("Cookie Domain=" + c.getDomain());
+        sb.append("Cookie Version=" + c.getVersion());
+
+      }
+    } catch (Throwable ex) {
+      sb.append("Unexpected exception thrown: " + ex.getMessage());
+      ex.printStackTrace();
+    }
+    return sb.toString();
+  }
+
+  @PUT
+  public String headersPlainPut(String nil) {
+    sb = new StringBuffer();
+    sb.append("Content-Language");
+    sb.append(langToString(hs.getLanguage()));
+    return sb.toString();
+  }
+
+  @POST
+  @Path("date")
+  public String date(@Context HttpHeaders headers, String nil) {
+    Date date = headers.getDate();
+    long time = date.getTime();
+    return String.valueOf(time);
+  }
+
+  @POST
+  @Path("headerstring")
+  public String headerString(@Context HttpHeaders headers, String headerName) {
+    String header = headers.getHeaderString(headerName);
+    return header;
+  }
+
+  @GET
+  @Path("length")
+  public String headerLength(@Context HttpHeaders headers) {
+    return String.valueOf(headers.getLength());
+  }
+
+  private static String langToString(Locale locale) {
+    return locale.toString().replace("_", "-");
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java
new file mode 100644
index 0000000..1d50c1d
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/JAXRSClientIT.java
@@ -0,0 +1,302 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.io.IOException;
+import java.text.DateFormat;
+import java.util.TimeZone;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Variant;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -5727774504018187299L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_headers_web/HeadersTest");
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_headers_web.war");
+    archive.addClasses(TSAppConfig.class, HttpHeadersTest.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: cookieTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:77;
+   * 
+   * @test_Strategy: Client invokes GET request on root resource at
+   * /HeadersTest/cookie with Cookie set; Verify that all Cookies properties are
+   * set by the request
+   */
+  @Test
+  public void cookieTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        "Cookie: $Version=1; name1=value1; $Domain=" + _hostname
+            + "; $Path=/jaxrs_ee_core_headers_web");
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "cookie"));
+    setProperty(Property.SEARCH_STRING,
+        "getCookie|Cookie Name=name1|Cookie Value=value1"
+            + "|Cookie Path=/jaxrs_ee_core_headers_web" + "|Cookie Domain="
+            + "|Cookie Version=1");
+    invoke();
+  }
+
+  /*
+   * @testName: acceptLanguageTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:75;
+   * 
+   * @test_Strategy: Client invokes GET request on root resource at
+   * /HeadersTes/acl with Language Header set; Verify that HttpHeaders got the
+   * property set by the request
+   */
+  @Test
+  public void acceptLanguageTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        buildAccept(MediaType.TEXT_PLAIN_TYPE));
+    setProperty(Property.REQUEST_HEADERS, "Accept-Language:en-US");
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "acl"));
+    setProperty(Property.SEARCH_STRING, "Accept-Language|en-US");
+    invoke();
+  }
+
+  /*
+   * @testName: contentLanguageTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:78;
+   * 
+   * @test_Strategy: Client invokes PUT request on root resource at /HeadersTest
+   * with Language Header set; Verify that HttpHeaders got the property set by
+   * the request
+   */
+  @Test
+  public void contentLanguageTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        buildAccept(MediaType.TEXT_PLAIN_TYPE));
+    Variant variant = new Variant(MediaType.WILDCARD_TYPE, "en-US", null);
+    Entity<String> entity = Entity.entity("anything", variant);
+    setRequestContentEntity(entity);
+    setProperty(Property.REQUEST, buildRequest(Request.PUT, ""));
+    setProperty(Property.SEARCH_STRING_IGNORE_CASE, "Content-Language|en-US");
+    invoke();
+  }
+
+  /*
+   * @testName: mediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8; JAXRS:JAVADOC:79;
+   * 
+   * @test_Strategy: Client invokes GET request on a sub resource at
+   * /HeadersTest/mt with Content-Type Header set; Verify that HttpHeaders got
+   * the property set by the request
+   */
+  @Test
+  public void mediaTypeTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type:application/xml;charset=utf8");
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "mt"));
+    setProperty(Property.SEARCH_STRING, "getMediaType|application/xml"
+        + "|MediaType size=1|Key charset|Value utf8");
+    invoke();
+  }
+
+  /*
+   * @testName: mediaTypeAcceptableTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:JAVADOC:76;
+   * 
+   * @test_Strategy: Client invokes GET request on a sub resource at
+   * /HeadersTest/amt with Accept MediaType Header set; Verify that HttpHeaders
+   * got the property set by the request
+   */
+  @Test
+  public void mediaTypeAcceptableTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        "Accept:text/*, text/html, text/html;level=1, */*");
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "amt"));
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        "getAcceptableMediaTypes|text/*|text/html|text/html|*/*");
+    invoke();
+  }
+
+  /*
+   * @testName: requestHeadersTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:3.6; JAXRS:SPEC:33.8; JAXRS:SPEC:40;
+   * JAXRS:JAVADOC:80; JAXRS:JAVADOC:81;
+   * 
+   * @test_Strategy: Client invokes GET request on a sub resource at
+   * /HeadersTest/sub2 with Accept MediaType and Content-Type Headers set;
+   * Verify that HttpHeaders got the property set by the request
+   */
+  @Test
+  public void requestHeadersTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        "Accept:text/*, text/html, text/html;level=1, */*");
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type:application/xml;charset=utf8");
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "headers"));
+    setProperty(Property.SEARCH_STRING, "getRequestHeaders=|Accept:|text/*");
+    setProperty(Property.SEARCH_STRING, "text/html|text/html|*/*");
+    setProperty(Property.SEARCH_STRING, "Content-Type:|application/xml");
+    setProperty(Property.SEARCH_STRING, "charset=utf8");
+    invoke();
+  }
+
+  /*
+   * @testName: getDateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:779;
+   * 
+   * @test_Strategy: Get message date
+   */
+  @Test
+  public void getDateTest() throws Fault {
+    long currentTime = System.currentTimeMillis();
+    DateFormat format = JaxrsUtil.createDateFormat(TimeZone.getTimeZone("GMT"));
+    String gmt = format.format(currentTime);
+
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "date"));
+    setProperty(Property.CONTENT, "getDate");
+    setProperty(Property.REQUEST_HEADERS, "Date:" + gmt);
+    invoke();
+    long responseTime = Long.parseLong(getResponseBody());
+    boolean check = Math.abs(currentTime - responseTime) < 1001L;
+    assertTrue(check, "HttpHeaders.getDate()="+ responseTime+
+        "differs from expected"+ currentTime+ "by more than 1000 ms.");
+    logMsg("#getDate() returned expected Date instance");
+  }
+
+  /*
+   * @testName: getHeaderStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:780;
+   * 
+   * @test_Strategy: Get a HTTP header as a single string value.
+   */
+  @Test
+  public void getHeaderStringTest() throws Fault {
+    String[] headers = { "askdjb", "ksadbva", "klwiaslkfn", "klwvasbk" };
+    for (String header : headers) {
+      setProperty(Property.REQUEST, buildRequest(Request.POST, "headerstring"));
+      setProperty(Property.CONTENT, header);
+      setProperty(Property.REQUEST_HEADERS, header + ":" + header + header);
+      setProperty(Property.SEARCH_STRING, header + header);
+      invoke();
+    }
+    logMsg("#getHeaderString() returned expected header values");
+  }
+
+  /*
+   * @testName: getHeaderStringUsesToStringTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:780;
+   * 
+   * @test_Strategy: Get a HTTP header as a single string value. Each single
+   * header value is converted to String using its toString method if a header
+   * delegate is not available.
+   */
+  @Test
+  public void getHeaderStringUsesToStringTest() throws Fault {
+    final StringBean bean = new StringBean("bean");
+    ClientRequestFilter filter = new ClientRequestFilter() {
+      @Override
+      public void filter(ClientRequestContext ctx) throws IOException {
+        ctx.getHeaders().add(bean.get(), bean);
+      }
+    };
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "headerstring"));
+    setProperty(Property.CONTENT, bean.get());
+    addProvider(filter);
+    setProperty(Property.SEARCH_STRING, bean.toString());
+    invoke();
+    logMsg(
+        "#getHeaderString() returned expected header converted by toString() method");
+  }
+
+  /*
+   * @testName: getLengthTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:781;
+   * 
+   * @test_Strategy: Get Content-Length value
+   */
+  @Test
+  public void getLengthTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(Request.GET, "length"));
+    invoke();
+    String body = getResponseBody();
+    assertTrue(body != null && body.length() > 0, "Nothing returned");
+    long length = Long.parseLong(body);
+    assertTrue(length != 0, "Nothing returned");
+    logMsg("#getLength() returned expected length", body);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java
new file mode 100644
index 0000000..0c5538c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/headers/TSAppConfig.java
@@ -0,0 +1,35 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.headers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.core.Application;
+
+/**
+ *
+ * @author diannejiao
+ */
+public class TSAppConfig extends Application {
+
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(HttpHeadersTest.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java
new file mode 100644
index 0000000..0da365b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/AnnotatedClass.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+/**
+ * This is the dummy class to get annotations from it
+ */
+public abstract class AnnotatedClass {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java
new file mode 100644
index 0000000..91979eb
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/CorruptedInputStream.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 2018 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.response;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class CorruptedInputStream extends ByteArrayInputStream {
+
+  AtomicInteger atomic;
+
+  private boolean corrupted = false;
+
+  public static final int CLOSEVALUE = 999;
+
+  public static final String IOETEXT = "CorruptedInputStream tck test IOException";
+
+  public CorruptedInputStream(byte[] buf, AtomicInteger atomic) {
+    super(buf);
+    this.atomic = atomic;
+  }
+
+  @Override
+  public void close() throws IOException {
+    if (corrupted) {
+      atomic.set(CLOSEVALUE);
+      throw new IOException(IOETEXT);
+    }
+    super.close();
+  }
+
+  public boolean isCorrupted() {
+    return corrupted;
+  }
+
+  public void setCorrupted(boolean corrupted) {
+    this.corrupted = corrupted;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java
new file mode 100644
index 0000000..0d83139
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/DateReaderWriter.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateReaderWriter
+    implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+
+  public static final int ANNOTATION_NONE = 0;
+
+  public static final int ANNOTATION_CONSUMES = 1 << 2;
+
+  public static final int ANNOTATION_PROVIDER = 1 << 3;
+
+  public static final int ANNOTATION_UNKNOWN = 1 << 7;
+
+  private AtomicInteger atom;
+
+  public DateReaderWriter(AtomicInteger atom) {
+    super();
+    this.atom = atom;
+  }
+
+  @Override
+  public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4) {
+    return String.valueOf(Long.MAX_VALUE).length();
+  }
+
+  @Override
+  public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return arg0 == Date.class;
+  }
+
+  @Override
+  public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+      throws IOException, WebApplicationException {
+    parseAnnotations(arg3);
+    stream.write(String.valueOf(date.getTime()).getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return isWriteable(arg0, arg1, arg2, arg3);
+  }
+
+  @Override
+  public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+      throws IOException, WebApplicationException {
+    parseAnnotations(arg2);
+
+    InputStreamReader reader = new InputStreamReader(arg5);
+    BufferedReader br = new BufferedReader(reader);
+    long date = Long.parseLong(br.readLine());
+    return new Date(date);
+  }
+
+  protected void parseAnnotations(Annotation[] annotations) {
+    int value = ANNOTATION_NONE;
+    if (annotations != null)
+      for (Annotation annotation : annotations)
+        if (annotation.annotationType() == Consumes.class)
+          value |= ANNOTATION_CONSUMES;
+        else if (annotation.annotationType() == Provider.class)
+          value |= ANNOTATION_PROVIDER;
+        else
+          value |= ANNOTATION_UNKNOWN;
+    atom.set(value);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java
new file mode 100644
index 0000000..dd54287
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/JAXRSClientIT.java
@@ -0,0 +1,1825 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.net.URI;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.GenericType;
+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 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.assertFalse;
+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;
+
+/**
+ * Some tests are the same as the tests in api.rs.core package except how the
+ * Response is created. This is because implementation of inbound and outbound
+ * Response differ.
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 4182256439207983256L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_response_web/resource");
+    setPrintEntity(true);
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_response_web.war");
+    archive.addClasses(TSAppConfig.class, jakarta.ws.rs.tck.common.util.JaxrsUtil.class, ResponseTest.class, CorruptedInputStream.class, jakarta.ws.rs.tck.common.provider.StringBean.class, jakarta.ws.rs.tck.common.provider.StringBeanHeaderDelegate.class, jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider.class, jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate.class, jakarta.ws.rs.tck.common.provider.PrintingErrorHandler.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /*
+   * @class.setup_props: webServerHost; webServerPort; ts_home;
+   */
+  /* Run test */
+
+  /*
+   * @testName: statusTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:14.2; JAXRS:JAVADOC:131; JAXRS:JAVADOC:139;
+   * 
+   * @test_Strategy: Client send request to a resource, verify that correct
+   * status code returned
+   *
+   */
+  @Test
+  public void statusTest() throws Fault {
+    for (Response.Status status : Response.Status.values()) {
+      if (status == Status.RESET_CONTENT)
+        continue; // it takes some time
+      setProperty(Property.STATUS_CODE, getStatusCode(status));
+      invokeGet("status?status=" + getStatusCode(status));
+    }
+  }
+
+  /*
+   * @testName: bufferEntityBuffersDataTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:838;
+   * 
+   * @test_Strategy: Buffer the message entity. In case the message entity is
+   * backed by an unconsumed entity input stream, all the bytes of the original
+   * entity input stream are read and stored locally.
+   * 
+   * This operation is idempotent, i.e. it can be invoked multiple times with
+   * the same effect which also means that calling the bufferEntity() method on
+   * an already buffered (and thus closed) message instance is legal and has no
+   * further effect.
+   */
+  @Test
+  public void bufferEntityBuffersDataTest() throws Fault {
+    Response response = invokeGet("entity");
+    boolean buffer = response.bufferEntity();
+    assertTrue(buffer, "#bufferEntity() did not buffer opened stream");
+    buffer = response.bufferEntity();
+    assertTrue(buffer, "#bufferEntity() is not idempotent");
+
+    String read = response.readEntity(String.class);
+    assertTrue(read.equals(ResponseTest.ENTITY), "Read entity"+ read+
+        "instead of"+ ResponseTest.ENTITY);
+    read = response.readEntity(String.class);
+    assertTrue(read.equals(ResponseTest.ENTITY), "Read entity"+ read+
+        "instead of"+ ResponseTest.ENTITY);
+    logMsg("#bufferEntity did buffer opened stream as expected");
+  }
+
+  /*
+   * @testName: bufferEntityThrowsExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:838;
+   * 
+   * @test_Strategy: Throws: ProcessingException - if there was an error while
+   * buffering the entity input stream.
+   */
+  @Test
+  public void bufferEntityThrowsExceptionTest() throws Fault {
+    setCorruptedStream(); // the error is on buffering, which calls close()
+    Response response = invokeGet("corrupted");
+    catchCorruptedStreamExceptionOnBufferEntity(response);
+    logMsg("ProcessingException has been thrown 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 = invokeGet("entity");
+    response.close();
+    try {
+      response.bufferEntity();
+      fault("buffer entity did not throw IllegalStateException when closed");
+    } catch (IllegalStateException e) {
+      logMsg("#bufferEntity throws IllegalStateException as expected");
+    }
+  }
+
+  /*
+   * @testName: closeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:841;
+   * 
+   * @test_Strategy: Close the message entity input stream (if available and
+   * open). This operation is idempotent, i.e. it can be invoked multiple times
+   * with the same effect which also means that calling the method on an already
+   * closed message instance is legal and has no further effect
+   */
+  @Test
+  public void closeTest() throws Fault {
+    // make new Client, the one from super class calls bufferEntity()
+    Client client = ClientBuilder.newClient();
+    WebTarget target = client
+        .target("http://" + _hostname + ":" + _port + getContextRoot())
+        .path("entity");
+    Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+        .invoke();
+    response.close(); // calling the method on an already closed message
+    response.close(); // instance is legal
+
+    // Any attempts to manipulate (read, get, buffer) a message entity on a
+    // closed response will result in an IllegalStateException being thrown
+    try {
+      String entity = response.readEntity(String.class);
+      assertTrue(false, "IllegalStateException has not been thrown when"+
+          "#close() and #readEntity() but entity"+ entity+ "has been read");
+    } catch (IllegalStateException e) {
+      logMsg(
+          "#close() closed the stream, and consecutive reading threw IllegalStateException as expected");
+    }
+  }
+
+  /*
+   * @testName: closeThrowsExceptionWhenErrorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:841;
+   * 
+   * @test_Strategy: throws ProcessingException - if there is an error closing
+   * the response.
+   */
+  @Test
+  public void closeThrowsExceptionWhenErrorTest() throws Fault {
+    setCorruptedStream();
+    Response response = invokeGet("corrupted");
+    try {
+      response.close(); // response.close should call stream.close()
+      assertTrue(false, "ProcessingException has not been thrown when"+
+          "CorruptedInputStream#close()");
+    } catch (ProcessingException e) {
+      // it is corrupted, #close throws IOException
+      assertNotNull(e.getCause(), "unknown exception thrown", e);
+      assertEquals(e.getCause().getMessage(), CorruptedInputStream.IOETEXT,
+          "unknown exception thrown", e);
+      logMsg("#close() threw ProcessingException 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 {
+    String allowed = Request.POST.name() + " " + Request.TRACE.name();
+    Response response = invokePost("allowedmethods", allowed);
+    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 {
+    Response response = invokeGet("cookies");
+    // getCookies test
+    Map<String, NewCookie> map = response.getCookies();
+    for (Entry<String, NewCookie> entry : map.entrySet()) {
+      String key = entry.getKey();
+      String value = entry.getValue().getValue();
+      if (key.equals("c1"))
+        assertEquals(value, "v1", value, "does not match expected v1");
+      else if (key.equals("c2"))
+        assertEquals(value, "v2", value, "does not match expected v2");
+      else
+        fault("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 cookie3 = new NewCookie("c3", "v3");
+    Response response = invokeGet("cookies");
+    // getCookies test
+    Map<String, NewCookie> map;
+    try {
+      map = response.getCookies();
+      map.put("c3", cookie3);
+    } catch (Exception e) {
+      // can throw an exception or nothing or return a copy map
+    }
+    map = response.getCookies();
+    assertFalse(map.containsKey("c3"), "getCookies is not read-only returned"+
+        map.get("c3"));
+    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 {
+    long date = getCurrentTimeMillis();
+    Response response = invokePost("date", String.valueOf(date));
+    long responseDate = response.getDate().getTime();
+    // assertEqualsLong(date, responseDate, "Original date", date,
+    // "and response#getDate()", responseDate, "differs");
+    // int TC, the Date settings is overriden by underlaying containers
+    // But getDate is to be tested, not setDate, hence
+    assertTrue(Math.abs(responseDate - date) < (10 * 60 * 1000),
+        "#getDate() returned time that differes by more than 10 minutes");
+    logMsg("#getDate matches the Date HTTP header");
+  }
+
+  /*
+   * @testName: getEntityThrowsIllegalStateExceptionTestWhenClosed
+   * 
+   * @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 getEntityThrowsIllegalStateExceptionTestWhenClosed()
+      throws Fault {
+    Response response = invokeGet("entity");
+    response.close();
+    try {
+      Object entity = response.getEntity();
+      fault("No exception has been thrown, entity=", entity);
+    } catch (IllegalStateException e) {
+      logMsg("#getEntity throws IllegalStateException as expected", e);
+    }
+  }
+
+  /*
+   * @testName: getEntityThrowsIllegalStateExceptionWhenConsumedTest
+   * 
+   * @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 getEntityThrowsIllegalStateExceptionWhenConsumedTest()
+      throws Fault {
+    Response response = invokeGet("entity");
+    response.readEntity(String.class);
+    try {
+      Object entity = response.getEntity();
+      fault("No exception has been thrown entity=", entity);
+    } 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 {
+    String tag = "ABCDEF0123456789";
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.NOT_MODIFIED));
+    Response response = invokePost("entitytag", tag);
+    EntityTag responseTag = response.getEntityTag();
+    assertEquals(tag, responseTag.getValue(), "response#getEntityTag()",
+        responseTag.getValue(), "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 {
+    ResponseHeaderValue<EntityTag> value = new ResponseHeaderValue<>();
+    addProvider(new HeaderNotPresent<EntityTag>(value) {
+      @Override
+      protected void setHeader(ClientResponseContext responseContext,
+          ResponseHeaderValue<EntityTag> header) {
+        header.value = responseContext.getEntityTag();
+      }
+    });
+
+    Response response = invokePost("entitytag", null);
+    EntityTag responseTag = response.getEntityTag();
+    assertHeaderNull(responseTag, value, "getEntityTag");
+  }
+
+  /*
+   * @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 {
+    Response response = invokePost("headers", "notnull");
+    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: getHeadersUsingHeaderDelegateTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:848;
+   * 
+   * @test_Strategy: Get view of the response headers and their object values.
+   */
+  @Test
+  public void getHeadersUsingHeaderDelegateTest() throws Fault {
+    invokeGet("setstringbeanruntime");
+
+    Response response = invokePost("headerstring", "notnull");
+    String[] metadata = JaxrsCommonClient.getMetadata(response.getHeaders());
+    logMsg("Received:");
+    logMsg((Object[]) metadata);
+    String headers = JaxrsUtil.iterableToString(";", (Object[]) metadata);
+    for (int i = 1; i != 4; i++) {
+      String header = "s" + i + ":s" + i;
+      assertContainsIgnoreCase(headers, header, "Expected header", header,
+          "was not found in received headers", headers);
+    }
+    logMsg("Received expected headers", headers);
+
+    invokeGet("setoriginalruntime");
+  }
+
+  /*
+   * @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 = invokePost("headers", null);
+    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 {
+    Response response = invokePost("headers", "headerstring");
+    logMsg("Found following objects:");
+    logMsg((Object[]) JaxrsCommonClient.getMetadata(response.getHeaders()));
+    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 {
+    invokeGet("setstringbeanruntime");
+
+    Response response = invokePost("headerstring", "delegate");
+    String header = response.getHeaderString("s3");
+    assertContainsIgnoreCase(header, "s3", "Header", "s3",
+        "has unexpected value", header);
+    logMsg("HeaderDelegate is used for header as expected");
+
+    invokeGet("setoriginalruntime");
+  }
+
+  /*
+   * @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 {
+    Response response = invokePost("headerstring", "toString");
+    String header = response.getHeaderString("s1");
+    assertContainsIgnoreCase(header, "s1", "Header s1 has unexpected value",
+        header);
+
+    header = response.getHeaderString("s2");
+    assertContainsIgnoreCase(header, "s2", "Header s2 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 = invokePost("language",
+        Locale.CANADA_FRENCH.getCountry());
+    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 {
+    ResponseHeaderValue<Locale> value = new ResponseHeaderValue<>();
+    addProvider(new HeaderNotPresent<Locale>(value) {
+      @Override
+      protected void setHeader(ClientResponseContext responseContext,
+          ResponseHeaderValue<Locale> header) {
+        header.value = responseContext.getLanguage();
+      }
+    });
+
+    Response response = invokePost("language", null);
+    Locale locale = response.getLanguage();
+    assertHeaderNull(locale, value, "getLanguage");
+  }
+
+  /*
+   * @testName: getLastModifiedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:851;
+   * 
+   * @test_Strategy: Get the last modified date.
+   */
+  @Test
+  public void getLastModifiedTest() throws Fault {
+    long time = getCurrentTimeMillis();
+    Response response = invokePost("lastmodified", String.valueOf(time));
+    long responseDate = response.getLastModified().getTime();
+    assertEqualsLong(time, responseDate, "Last Modified date", time,
+        "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 {
+    ResponseHeaderValue<Date> containerValue = new ResponseHeaderValue<>();
+    addProvider(new HeaderNotPresent<Date>(containerValue) {
+      @Override
+      protected void setHeader(ClientResponseContext responseContext,
+          ResponseHeaderValue<Date> header) {
+        header.value = responseContext.getLastModified();
+      }
+    });
+
+    Response response = invokePost("lastmodified", null);
+    Date responseDate = response.getLastModified();
+    assertHeaderNull(responseDate, containerValue, "getLastModified");
+  }
+
+  /*
+   * @testName: getLengthTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:852;
+   * 
+   * @test_Strategy: Get Content-Length value.
+   */
+  @Test
+  public void getLengthTest() throws Fault {
+    Response response = invokePost("length", "1234567890");
+    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 = invokePost("length", null);
+    int len = response.getLength();
+    String headerLen = response.getHeaderString(HttpHeaders.CONTENT_LENGTH);
+    if (headerLen == null)
+      assertEqualsInt(len, -1, "Expected Content-Length = -1",
+          "does NOT match response#getLength()", len);
+    else
+      assertEqualsInt(len, Integer.parseInt(headerLen),
+          "Expected Content-Length =", headerLen,
+          "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 {
+    String rel = "getLinkTest";
+    Response response = invokePost("link", rel);
+    Link responseLink = response.getLink(rel);
+    assertNotNull(responseLink, "#getLink is null");
+    assertContains(rel, responseLink.getRel(),
+        "#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 {
+    ResponseHeaderValue<Link> containerValue = new ResponseHeaderValue<>();
+    addProvider(new HeaderNotPresent<Link>(containerValue) {
+      @Override
+      protected void setHeader(ClientResponseContext responseContext,
+          ResponseHeaderValue<Link> header) {
+        header.value = responseContext.getLink("getLinkTest");
+      }
+    });
+
+    Response response = invokePost("link", null);
+    Link responseLink = response.getLink("getLinkTest");
+    assertHeaderNull(responseLink, containerValue, "getLink");
+  }
+
+  /*
+   * @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 = invokePost("linkbuilder", rel);
+    Link responseLink = response.getLink(rel);
+    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 = invokeGet("entity");
+    Builder builder = response.getLinkBuilder("anyrelation");
+    assertNull(builder,
+        "#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 {
+    Response response = invokeGet("links");
+    Set<Link> responseLinks = response.getLinks();
+    assertEqualsInt(responseLinks.size(), 2,
+        "#getLinks() returned set of unexpected size", responseLinks.size());
+    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 = invokeGet("entity");
+    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 {
+    String path = "path";
+    URI serverUri = ResponseTest.createUri(path);
+    Response response = invokePost("location", path);
+    URI responseLocation = response.getLocation();
+    assertEquals(responseLocation, serverUri, "#getLocation()",
+        responseLocation, "differs from expected", serverUri);
+    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 {
+    ResponseHeaderValue<URI> containerValue = new ResponseHeaderValue<>();
+    addProvider(new HeaderNotPresent<URI>(containerValue) {
+      @Override
+      protected void setHeader(ClientResponseContext responseContext,
+          ResponseHeaderValue<URI> header) {
+        header.value = responseContext.getLocation();
+      }
+    });
+
+    Response response = invokeGet("entity");
+    URI responseLocation = response.getLocation();
+    assertHeaderNull(responseLocation, containerValue, "getLocation");
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:857;
+   * 
+   * @test_Strategy: Get the media type of the message entity.
+   */
+  @Test
+  public void getMediaTypeTest() throws Fault {
+    MediaType mediaType = MediaType.APPLICATION_ATOM_XML_TYPE;
+    Response response = invokePost("mediatype", mediaType.toString());
+    MediaType responseMedia = response.getMediaType();
+    assertEquals(mediaType, responseMedia, "#getMediaType()", responseMedia,
+        "differs from expected", MediaType.APPLICATION_ATOM_XML);
+    logMsg("#getMediaType returned expected MediaType");
+  }
+
+  /*
+   * @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()) {
+      setProperty(Property.STATUS_CODE, getStatusCode(status));
+      Response response = invokePost("statusinfo", status.name());
+      StatusType info = response.getStatusInfo();
+      assertEqualsInt(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 {
+    Response response = invokePost("headerstring", "stringheaders");
+    MultivaluedMap<String, String> headers = response.getStringHeaders();
+    String header = headers.getFirst("s1");
+    assertContainsIgnoreCase(header, "s1", "Header", "s1",
+        "has unexpected value", header);
+
+    header = headers.getFirst("s2");
+    assertContainsIgnoreCase(header, "s2", "Header", "s2",
+        "has unexpected value", header);
+
+    logMsg("#getStringHeaders contains expected values",
+        JaxrsUtil.iterableToString(",", headers.entrySet()));
+  }
+
+  /*
+   * @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 {
+    invokeGet("setstringbeanruntime");
+
+    Response response = invokePost("headerstring", "stringheaders");
+    MultivaluedMap<String, String> headers = response.getStringHeaders();
+    String header = headers.getFirst("s3");
+    assertContainsIgnoreCase("s3", header, "Header", "s3",
+        "has unexpected value", header);
+
+    logMsg("#getStringHeaders contains expected values",
+        JaxrsUtil.iterableToString(",", headers.entrySet()));
+
+    invokeGet("setoriginalruntime");
+  }
+
+  /*
+   * @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 = invokeGet("entity");
+    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 = invokePost("headerstring", null);
+    assertFalse(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 = invokeGet("entity");
+    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 {
+    Response response = invokePost("link", "path");
+    assertTrue(response.hasLink("path"), "#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 = invokeGet("entity");
+    assertFalse(response.hasLink("rel"), "#has Link did found some Link");
+    logMsg("#hasLink has not found any Link as expected");
+  }
+
+  /*
+   * @testName: readEntityClassTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: Read the message entity input stream as an instance of
+   * specified Java type using a MessageBodyReader that supports mapping the
+   * message entity stream onto the requested type
+   */
+  @Test
+  public void readEntityClassTest() throws Fault {
+    Response response = invokeGet("entity");
+    response.bufferEntity();
+    String line;
+
+    Reader reader = response.readEntity(Reader.class);
+    line = readLine(reader);
+    assertTrue(ResponseTest.ENTITY.equals(line), "#readEntity(Reader)={"+ line+
+        "} differs from expected"+ ResponseTest.ENTITY);
+
+    byte[] buffer = new byte[0];
+    buffer = response.readEntity(buffer.getClass());
+    line = new String(buffer);
+    assertTrue(ResponseTest.ENTITY.equals(line), "#readEntity(byte[].class)={"+
+        line+ "} differs from expected"+ ResponseTest.ENTITY);
+
+    logMsg("Got expected", line);
+  }
+
+  /*
+   * @testName: readEntityClassIsNullWhenNoEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: If the message does not contain an entity body null is
+   * returned.
+   */
+  @Test
+  public void readEntityClassIsNullWhenNoEntityTest() throws Fault {
+    Response response = invokeGet("status?status=200");
+    String entity = response.readEntity(String.class);
+    assertTrue(entity == null || "".equals(entity),
+        "entity is not null or zero length"+ entity);
+    logMsg("Null or zero length entity returned when no entity as expected");
+  }
+
+  /*
+   * @testName: readEntityClassCloseIsCalledTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityClassCloseIsCalledTest() throws Fault {
+    AtomicInteger ai = setCorruptedStream();
+    final Response response = invokeGet("corrupted");
+    catchCorruptedStreamException(new Runnable() {
+      @Override
+      public void run() {
+        response.readEntity(String.class);
+      }
+    });
+    assertEquals(ai.get(), CorruptedInputStream.CLOSEVALUE,
+        "Close has not been called");
+    logMsg("Close() has been called on an entity stream as expected");
+  }
+
+  /*
+   * @testName: readEntityClassCloseIsNotCalledOnInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityClassCloseIsNotCalledOnInputStreamTest() throws Fault {
+    AtomicInteger ai = setCorruptedStream();
+    Response response = invokeGet("corrupted");
+    try {
+      response.readEntity(InputStream.class);
+      logMsg("Close() has not been called on entity stream as expected");
+    } catch (Exception e) {
+      throw new Fault("Close was called", e);
+    }
+    assertTrue(ai.get() == 0, "Close was called");
+  }
+
+  /*
+   * @testName: readEntityClassThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: Method throws an ProcessingException if the content of the
+   * message cannot be mapped to an entity of the requested type
+   */
+  @Test
+  public void readEntityClassThrowsProcessingExceptionTest() throws Fault {
+    Response response = invokeGet("entity");
+    try {
+      response.readEntity(Void.class);
+      throw new Fault(
+          "No exception has been thrown when reader for entity class is not known");
+    } catch (ProcessingException e) {
+      logMsg("ProcessingException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityClassThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:863;
+   * 
+   * @test_Strategy: if the entity is not backed by an input stream, or if the
+   * entity input stream has been fully consumed already and has not been
+   * buffered prior consuming.
+   */
+  @Test
+  public void readEntityClassThrowsIllegalStateExceptionTest() throws Fault {
+    Client client = ClientBuilder.newClient(); // create a new client
+    WebTarget target = client.target( // with no bufferEntity called
+        "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+    Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+        .invoke();
+    String entity = response.readEntity(String.class);
+    assertTrue(ResponseTest.ENTITY.equals(entity),
+        "#readEntity(String.class)={"+ entity+ "} differs from expected"+
+        ResponseTest.ENTITY);
+    try {
+      response.readEntity(Reader.class);
+      throw new Fault(
+          "No exception has been thrown when reader for entity is not buffered");
+    } catch (IllegalStateException e) {
+      logMsg("IllegalStateException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: Read the message entity input stream as an instance of
+   * specified Java type using a MessageBodyReader that supports mapping the
+   * message entity stream onto the requested type
+   */
+  @Test
+  public void readEntityGenericTypeTest() throws Fault {
+    Response response = invokeGet("entity");
+    response.bufferEntity();
+    String line;
+
+    Reader reader = response.readEntity(generic(Reader.class));
+    line = readLine(reader);
+    assertTrue(ResponseTest.ENTITY.equals(line),
+        "#readEntity(GenericType<Reader>)={"+ line+ "} differs from expected"+
+        ResponseTest.ENTITY);
+
+    byte[] buffer = new byte[0];
+    buffer = response.readEntity(generic(buffer.getClass()));
+    assertTrue(buffer != null,
+        "response.readEntity(GenericType<byte[]>) is null");
+    line = new String(buffer);
+    assertTrue(ResponseTest.ENTITY.equals(line),
+        "#readEntity(GenericType<byte[]>)={"+ line+ "} differs from expected"+
+        ResponseTest.ENTITY);
+
+    logMsg("Got expected", line);
+  }
+
+  /*
+   * @testName: readEntityGenericIsNullWhenNoEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: If the message does not contain an entity body null is
+   * returned.
+   */
+  @Test
+  public void readEntityGenericIsNullWhenNoEntityTest() throws Fault {
+    String request = buildRequest(Request.GET, "status?status=200");
+    setProperty(Property.REQUEST, request);
+    invoke();
+    Response response = getResponse();
+    String entity = response.readEntity(generic(String.class));
+    assertTrue(entity == null || "".equals(entity),
+        "entity is not null or zero length"+ entity);
+    logMsg("Null or zero length entity returned when no entity as expected");
+  }
+
+  /*
+   * @testName: readEntityGenericCloseIsCalledTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityGenericCloseIsCalledTest() throws Fault {
+    AtomicInteger ai = setCorruptedStream();
+    final Response response = invokeGet("corrupted");
+    catchCorruptedStreamException(new Runnable() {
+      @Override
+      public void run() {
+        response.readEntity(generic(String.class));
+      }
+    });
+    assertTrue(ai.get() == CorruptedInputStream.CLOSEVALUE,
+        "Close has not been called");
+    logMsg("Close() has been called on an entity stream as expected");
+  }
+
+  /*
+   * @testName: readEntityGenericTypeCloseIsNotCalledOnInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityGenericTypeCloseIsNotCalledOnInputStreamTest()
+      throws Fault {
+    AtomicInteger ai = setCorruptedStream();
+    Response response = invokeGet("corrupted");
+    try {
+      response.readEntity(generic(InputStream.class));
+      logMsg("Close() has not been called on entity stream as expected");
+    } catch (Exception e) {
+      throw new Fault("Close was called", e);
+    }
+    assertTrue(ai.get() == 0, "Close was called");
+  }
+
+  /*
+   * @testName: readEntityGenericTypeThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: Method throws an ProcessingException if the content of the
+   * message cannot be mapped to an entity of the requested type
+   */
+  @Test
+  public void readEntityGenericTypeThrowsProcessingExceptionTest()
+      throws Fault {
+    Response response = invokeGet("entity");
+    try {
+      response.readEntity(generic(Void.class));
+      throw new Fault(
+          "No exception has been thrown when reader for entity class is not known");
+    } catch (ProcessingException e) {
+      logMsg("ProcessingException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityGenericTypeThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:866;
+   * 
+   * @test_Strategy: if the entity is not backed by an input stream, or if the
+   * entity input stream has been fully consumed already and has not been
+   * buffered prior consuming.
+   */
+  @Test
+  public void readEntityGenericTypeThrowsIllegalStateExceptionTest()
+      throws Fault {
+    Client client = ClientBuilder.newClient(); // create a new client
+    WebTarget target = client.target( // with no bufferEntity called
+        "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+    Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+        .invoke();
+    String entity = response.readEntity(generic(String.class));
+    assertTrue(ResponseTest.ENTITY.equals(entity),
+        "#readEntity(GenericType<byte[]>)={"+ entity+ "} differs from expected"+
+        ResponseTest.ENTITY);
+    try {
+      response.readEntity(generic(Reader.class));
+      throw new Fault(
+          "No exception has been thrown when reader for entity is not buffered");
+    } catch (IllegalStateException e) {
+      logMsg("IllegalStateException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: Read the message entity input stream as an instance of
+   * specified Java type using a MessageBodyReader that supports mapping the
+   * message entity stream onto the requested type. annotations - annotations
+   * that will be passed to the MessageBodyReader.
+   */
+  @Test
+  public void readEntityClassAnnotationTest() throws Fault {
+    Date date = Calendar.getInstance().getTime();
+    String sDate = String.valueOf(date.getTime());
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    int expected = DateReaderWriter.ANNOTATION_CONSUMES
+        | DateReaderWriter.ANNOTATION_PROVIDER;
+
+    AtomicInteger ai = new AtomicInteger();
+    DateReaderWriter drw = new DateReaderWriter(ai);
+    addProvider(drw);
+
+    Response response = invokeGet("date?date=" + sDate);
+    response.bufferEntity();
+
+    Date entity = response.readEntity(Date.class, annotations);
+    assertTrue(date.equals(entity), "#readEntity(Date, annotations)={"+ entity+
+        "} differs from expected"+ date);
+
+    assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+        expected+ "which suggest a problem with annotation passing");
+
+    String responseDate = response.readEntity(String.class, annotations);
+    assertTrue(sDate.equals(responseDate),
+        "#readEntity(String.class, annotations)={"+ responseDate+
+        "} differs from expected"+ sDate);
+
+    assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+        expected+ "which suggest a problem with annotation passing");
+
+    logMsg("Got expected date", date);
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationIsNullWhenNoEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: If the message does not contain an entity body null is
+   * returned.
+   */
+  @Test
+  public void readEntityClassAnnotationIsNullWhenNoEntityTest() throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Response response = invokeGet("status?status=200");
+    String entity = response.readEntity(String.class, annotations);
+    assertTrue(entity == null || "".equals(entity),
+        "entity is not null or zero length"+ entity);
+    logMsg("Null or zero length entity returned when no entity as expected");
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationCloseIsCalledTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityClassAnnotationCloseIsCalledTest() throws Fault {
+    final Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    AtomicInteger ai = setCorruptedStream();
+    final Response response = invokeGet("corrupted");
+    catchCorruptedStreamException(new Runnable() {
+      @Override
+      public void run() {
+        response.readEntity(String.class, annotations);
+      }
+    });
+    assertEqualsInt(ai.get(), CorruptedInputStream.CLOSEVALUE,
+        "Close has not been called");
+    logMsg("Close() has been called on an entity stream as expected");
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationCloseIsNotCalledOnInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityClassAnnotationCloseIsNotCalledOnInputStreamTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    AtomicInteger ai = setCorruptedStream();
+    Response response = invokeGet("corrupted");
+    try {
+      response.readEntity(InputStream.class, annotations);
+      logMsg("Close() has not been called on entity stream as expected");
+    } catch (ProcessingException e) {
+      throw new Fault("Close was called", e);
+    }
+    assertTrue(ai.get() == 0, "Close was called");
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: Method throws an ProcessingException if the content of the
+   * message cannot be mapped to an entity of the requested type
+   */
+  @Test
+  public void readEntityClassAnnotationThrowsProcessingExceptionTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Response response = invokeGet("entity");
+    try {
+      response.readEntity(Void.class, annotations);
+      throw new Fault(
+          "No exception has been thrown when reader for entity class is not known");
+    } catch (ProcessingException e) {
+      logMsg("ProcessingException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityClassAnnotationThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:869;
+   * 
+   * @test_Strategy: if the entity is not backed by an input stream, or if the
+   * entity input stream has been fully consumed already and has not been
+   * buffered prior consuming.
+   */
+  @Test
+  public void readEntityClassAnnotationThrowsIllegalStateExceptionTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Client client = ClientBuilder.newClient(); // create a new client
+    WebTarget target = client.target( // with no bufferEntity called
+        "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+    Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+        .invoke();
+    String entity = response.readEntity(String.class, annotations);
+    assertTrue(ResponseTest.ENTITY.equals(entity),
+        "#readEntity(String.class, annotations)={"+ entity+
+        "} differs from expected"+ ResponseTest.ENTITY);
+    try {
+      response.readEntity(Reader.class, annotations);
+      throw new Fault(
+          "No exception has been thrown when reader for entity is not buffered");
+    } catch (IllegalStateException e) {
+      logMsg("IllegalStateException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: Read the message entity input stream as an instance of
+   * specified Java type using a MessageBodyReader that supports mapping the
+   * message entity stream onto the requested type. annotations - annotations
+   * that will be passed to the MessageBodyReader.
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationTest() throws Fault {
+    Date date = Calendar.getInstance().getTime();
+    String sDate = String.valueOf(date.getTime());
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    int expected = DateReaderWriter.ANNOTATION_CONSUMES
+        | DateReaderWriter.ANNOTATION_PROVIDER;
+
+    AtomicInteger ai = new AtomicInteger();
+    DateReaderWriter drw = new DateReaderWriter(ai);
+    addProvider(drw);
+
+    Response response = invokeGet("date?date=" + sDate);
+    response.bufferEntity();
+
+    Date entity = response.readEntity(generic(Date.class), annotations);
+    assertTrue(date.equals(entity), "#readEntity(Date, annotations)={"+ entity+
+        "} differs from expected"+ date);
+
+    assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+        expected+ "which suggest a problem with annotation passing");
+
+    String responseDate = response.readEntity(generic(String.class),
+        annotations);
+    assertTrue(sDate.equals(responseDate),
+        "#readEntity(String.class, annotations)={"+ responseDate+
+        "} differs from expected"+ sDate);
+
+    assertTrue(ai.get() == expected, ai.get()+ "differes from expected"+
+        expected+ "which suggest a problem with annotation passing");
+
+    logMsg("Got expected date", date);
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationIsNullWhenNoEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: If the message does not contain an entity body null is
+   * returned.
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationIsNullWhenNoEntityTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Response response = invokeGet("status?status=200");
+    String entity = response.readEntity(generic(String.class), annotations);
+    assertTrue(entity == null || "".equals(entity),
+        "entity is not null or zero length"+ entity);
+    logMsg("Null or zero length entity returned when no entity as expected");
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationCloseIsCalledTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationCloseIsCalledTest() throws Fault {
+    final Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    AtomicInteger ai = setCorruptedStream();
+    final Response response = invokeGet("corrupted");
+    catchCorruptedStreamException(new Runnable() {
+      @Override
+      public void run() {
+        response.readEntity(generic(String.class), annotations);
+      }
+    });
+    assertEqualsInt(ai.get(), CorruptedInputStream.CLOSEVALUE,
+        "Close has not been called");
+    logMsg("Close() has been called on an entity stream as expected");
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationCloseIsNotCalledOnInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: Unless the supplied entity type is an input stream, this
+   * method automatically closes the consumed response entity stream if it is
+   * not buffered.
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationCloseIsNotCalledOnInputStreamTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    AtomicInteger ai = setCorruptedStream();
+    Response response = invokeGet("corrupted");
+    try {
+      response.readEntity(generic(InputStream.class), annotations);
+    } catch (ProcessingException e) {
+      fault("Close was called", e);
+    }
+    assertEqualsInt(ai.get(), 0, "Close was called");
+    logMsg("Close() has not been called on entity stream as expected");
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationThrowsProcessingExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: Method throws an ProcessingException if the content of the
+   * message cannot be mapped to an entity of the requested type
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationThrowsProcessingExceptionTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Response response = invokeGet("entity");
+    try {
+      response.readEntity(generic(Void.class), annotations);
+      throw new Fault(
+          "No exception has been thrown when reader for entity class is not known");
+    } catch (ProcessingException e) {
+      logMsg("ProcessingException has been thrown as expected");
+    }
+  }
+
+  /*
+   * @testName: readEntityGenericTypeAnnotationThrowsIllegalStateExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:872;
+   * 
+   * @test_Strategy: if the entity is not backed by an input stream, or if the
+   * entity input stream has been fully consumed already and has not been
+   * buffered prior consuming.
+   */
+  @Test
+  public void readEntityGenericTypeAnnotationThrowsIllegalStateExceptionTest()
+      throws Fault {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Client client = ClientBuilder.newClient(); // create a new client
+    WebTarget target = client.target( // with no bufferEntity called
+        "http://" + _hostname + ":" + _port + getContextRoot()).path("entity");
+    Response response = target.request(MediaType.TEXT_PLAIN_TYPE).buildGet()
+        .invoke();
+    String entity = response.readEntity(generic(String.class), annotations);
+    assertTrue(ResponseTest.ENTITY.equals(entity),
+        "#readEntity(GenericType<String>, annotations)={"+ entity+
+        "} differs from expected"+ ResponseTest.ENTITY);
+    try {
+      response.readEntity(generic(Reader.class), annotations);
+      throw new Fault(
+          "No exception has been thrown when reader for entity is not buffered");
+    } catch (IllegalStateException e) {
+      logMsg("IllegalStateException has been thrown as expected");
+    }
+  }
+
+    /*
+   * @testName: responseCreatedRelativeURITest
+   *
+   * @assertion_ids: JAXRS:JAVADOC:121;
+   *
+   * @test_Strategy: The resource calls Response.created() to set the Location header with a
+   * relative URI. The relative URI should be converted into an absolute URI by resolving it
+   * relative to the base URI.
+   */
+  @Test
+  public void responseCreatedRelativeURITest()
+      throws Fault {
+    String resourceUrl = getAbsoluteUrl();
+    String expected = resourceUrl.substring(0, resourceUrl.length() - "resource".length()) + "created";
+    Response response = invokeGet("created");
+    try {
+      assertTrue(expected.equals(response.getHeaderString("location")),
+        "#response.getHeaderString(\"location\") [" +
+        response.getHeaderString("location") + "] differs from "+ expected);
+    } finally {
+      response.close();
+    }
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  protected <T> GenericType<T> generic(Class<T> clazz) {
+    return new GenericType<T>(clazz);
+  }
+
+  protected Response invokeGet(String method) throws Fault {
+    String request = buildRequest(Request.GET, method);
+    setProperty(Property.REQUEST_HEADERS,
+        buildAccept(MediaType.TEXT_PLAIN_TYPE));
+    setProperty(Property.REQUEST, request);
+    invoke();
+    return getResponse();
+  }
+
+  protected Response invokePost(String method, Object entity) throws Fault {
+    String request = buildRequest(Request.POST, method);
+    setProperty(Property.REQUEST, request);
+    setRequestContentEntity(entity);
+    invoke();
+    return getResponse();
+  }
+
+  protected String readLine(Reader reader) throws Fault {
+    String line = null;
+    BufferedReader buffered = new BufferedReader(reader);
+    try {
+      line = buffered.readLine();
+    } catch (IOException e) {
+      try {
+        buffered.close();
+      } catch (IOException ie) {
+      }
+      throw new Fault(e);
+    }
+    return line;
+  }
+
+  protected AtomicInteger setCorruptedStream() {
+    final AtomicInteger ai = new AtomicInteger(0);
+    ClientResponseFilter filter = new ClientResponseFilter() {
+      @Override
+      public void filter(ClientRequestContext arg0,
+          ClientResponseContext response) throws IOException {
+        CorruptedInputStream cis = new CorruptedInputStream(
+            ResponseTest.ENTITY.getBytes(), ai);
+        cis.setCorrupted(true);
+        response.setEntityStream(cis);
+      }
+    };
+    addProvider(filter);
+
+    // do not use new entity stream in logging filter for the case of priority
+    // disfunction, the CorruptedInputStream would be then replaced, wrongly
+    // informing about not closing the stream
+    super.setPrintEntity(false);
+
+    return ai;
+  }
+
+  protected long getCurrentTimeMillis() {
+    long millis = System.currentTimeMillis() / 1000;
+    millis *= 1000;
+    return millis;
+  }
+
+  protected 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 void catchCorruptedStreamException(Runnable runnable) throws Fault {
+    try {
+      runnable.run();
+    } catch (ProcessingException e) {
+      // it is corrupted, #close throws IOException
+      assertNotNull(e.getCause(), "unknown exception thrown", e);
+      assertEquals(e.getCause().getMessage(), CorruptedInputStream.IOETEXT,
+          "unknown exception thrown", e);
+    }
+  }
+
+  protected void catchCorruptedStreamExceptionOnBufferEntity(
+      final Response response) throws Fault {
+    catchCorruptedStreamException(new Runnable() {
+      @Override
+      public void run() {
+        // The original entity input stream is
+        // consumed and automatically closed
+        response.bufferEntity();
+      }
+    });
+  }
+
+  //////////////////////////////////////////////////////////////////////////////////////////////
+  // Even though the test itself do not set the headers, possibly the vendor's
+  ////////////////////////////////////////////////////////////////////////////////////////////// container
+  ////////////////////////////////////////////////////////////////////////////////////////////// does.
+  // In that case, the ResponseFilter checks the value; if it is not expected
+  ////////////////////////////////////////////////////////////////////////////////////////////// null,
+  ////////////////////////////////////////////////////////////////////////////////////////////// the
+  ////////////////////////////////////////////////////////////////////////////////////////////// response
+  // should return the same value the response context does.
+
+  private <T> void assertHeaderNull(T actualHeader,
+      ResponseHeaderValue<T> filterValue, String method) throws Fault {
+    if (filterValue.value == null) {
+      assertNull(actualHeader, "response#" + method + "() should be null, was ",
+          actualHeader);
+      logMsg("response#" + method + "() was null as expected");
+    } else {
+      assertEquals(filterValue.value, actualHeader,
+          "response#" + method + "() was set to " + filterValue.value,
+          "by container but was ", actualHeader);
+      logMsg("response#" + method + "() was set to " + actualHeader
+          + " as preset by container");
+    }
+  }
+
+  class ResponseHeaderValue<T> {
+    private T value;
+  }
+
+  abstract class HeaderNotPresent<T> implements ClientResponseFilter {
+    private ResponseHeaderValue<T> headerValue;
+
+    public HeaderNotPresent(ResponseHeaderValue<T> headerValue) {
+      this.headerValue = headerValue;
+    }
+
+    @Override
+    public void filter(ClientRequestContext requestContext,
+        ClientResponseContext responseContext) throws IOException {
+      setHeader(responseContext, headerValue);
+    }
+
+    protected abstract void setHeader(ClientResponseContext responseContext,
+        ResponseHeaderValue<T> header);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java
new file mode 100644
index 0000000..7874bab
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/ResponseTest.java
@@ -0,0 +1,306 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Calendar;
+import java.util.Date;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.StringTokenizer;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+import jakarta.ws.rs.tck.common.provider.StringBeanRuntimeDelegate;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.CacheControl;
+import jakarta.ws.rs.core.EntityTag;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Link;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.RuntimeDelegate;
+
+@Path("resource")
+public class ResponseTest {
+  public static final String ENTITY = "ENtiTy";
+
+  @GET
+  @Path("status")
+  @Produces(value = "text/plain")
+  public Response statusTest(@QueryParam("status") int status) {
+    StringBuffer sb = new StringBuffer();
+    sb.append("status code in request = " + status);
+    ResponseBuilder builder = Response.status(status);
+    Response res = builder.header("TESTHEADER", sb.toString()).build();
+    return res;
+  }
+
+  @GET
+  @Path("entity")
+  @Produces(MediaType.TEXT_PLAIN)
+  public String entity() {
+    return ENTITY;
+  }
+
+  @GET
+  @Path("corrupted")
+  public CorruptedInputStream corrupted() {
+    return new CorruptedInputStream(ENTITY.getBytes(), null);
+  }
+
+  @GET
+  @Path("date")
+  public String date(@QueryParam("date") String date) {
+    return date;
+  }
+
+  @POST
+  @Path("allowedmethods")
+  public Response getAllowedMethods(String methods) {
+    ResponseBuilder builder = Response.ok();
+    StringTokenizer tokenizer = new StringTokenizer(methods);
+    List<String> allowed = new LinkedList<String>();
+    while (tokenizer.hasMoreTokens())
+      allowed.add(tokenizer.nextToken());
+    builder.allow(allowed.toArray(new String[0]));
+    return builder.build();
+  }
+
+  @GET
+  @Path("cookies")
+  public Response getCookies() {
+    NewCookie cookie1 = new NewCookie("c1", "v1");
+    NewCookie cookie2 = new NewCookie("c2", "v2");
+    Response response = Response.ok().cookie(cookie1).cookie(cookie2).build();
+    return response;
+  }
+
+  @POST
+  @Path("date")
+  public Response getDate(String date) throws InterruptedException {
+    ResponseBuilder builder = Response.ok();
+    Thread.sleep(1500L);
+    if (date != null && date.length() != 0) {
+      long millis = Long.parseLong(date);
+      Date dateFromMillis = new Date(millis);
+      builder = builder.header(HttpHeaders.DATE, dateFromMillis);
+    }
+    Response response = builder.build();
+    return response;
+  }
+
+  @POST
+  @Path("entitytag")
+  public Response getEntityTag(String tag) {
+    ResponseBuilder builder;
+    if (tag != null && tag.length() != 0) {
+      EntityTag entityTag = new EntityTag(tag);
+      builder = Response.notModified(entityTag);
+    } else
+      builder = Response.ok();
+    Response response = builder.build();
+    return response;
+  }
+
+  @POST
+  @Path("headers")
+  public Response getHeaders(String headers) {
+    CacheControl ccl = new CacheControl();
+    NewCookie cookie = new NewCookie("cookie", "eikooc");
+    String encoding = "gzip";
+    Date date = Calendar.getInstance().getTime();
+    ResponseBuilder builder = Response.ok();
+    if (headers != null && headers.length() != 0) {
+      builder = builder.cacheControl(ccl).cookie(cookie).encoding(encoding)
+          .expires(date).language(Locale.CANADA_FRENCH);
+    }
+    return builder.build();
+  }
+
+  @POST
+  @Path("headerstring")
+  public Response getHeaderString(String headers) {
+    StringBuilder builder = new StringBuilder("s1");
+    StringBuffer buffer = new StringBuffer("s2");
+    StringBean bean = new StringBean("s3");
+    ResponseBuilder response = Response.ok();
+    if (headers != null && headers.length() != 0)
+      response = response.header(builder.toString(), builder)
+          .header(buffer.toString(), buffer).header(bean.get(), bean);
+    return response.build();
+  }
+
+  @POST
+  @Path("language")
+  public Response getLanguage(String lang) {
+    ResponseBuilder builder = Response.ok();
+    Locale locale = null;
+    if (Locale.CANADA_FRENCH.getCountry().equals(lang))
+      locale = Locale.CANADA_FRENCH;
+    if (locale != null)
+      builder = builder.language(locale);
+    return builder.build();
+  }
+
+  @POST
+  @Path("lastmodified")
+  public Response lastModified(String date) {
+    ResponseBuilder builder = Response.ok();
+    if (date != null && date.length() != 0) {
+      long millis = Long.parseLong(date);
+      Date dateFromMillis = new Date(millis);
+      builder = builder.lastModified(dateFromMillis);
+    }
+    Response response = builder.build();
+    return response;
+  }
+
+  @POST
+  @Path("length")
+  public Response getLength(String entity) {
+    Response response = null;
+    if (entity == null || entity.length() == 0)
+      response = Response.ok().build();
+    else
+      response = Response.ok(entity)
+          .header(HttpHeaders.CONTENT_LENGTH, entity.length()).build();
+    return response;
+  }
+
+  @POST
+  @Path("link")
+  public Response getLink(String rel) {
+    ResponseBuilder builder = Response.ok();
+    if (rel != null && rel.length() != 0)
+      builder.links(createLink("path", rel));
+    return builder.build();
+  }
+
+  @POST
+  @Path("linkbuilder")
+  public Response getLinkBuilder(String rel) {
+    Link link1 = createLink("path1", rel);
+    Response response = Response.ok().links(link1).build();
+    Link builderLink = response.getLinkBuilder(rel).build();
+    response = Response.ok().links(builderLink).build();
+    return response;
+  }
+
+  @GET
+  @Path("links")
+  public Response getLinks() {
+    Link link1 = createLink("path1", "rel1");
+    Link link2 = createLink("path2", "rel2");
+    Response response = Response.ok().links(link1, link2).build();
+    return response;
+  }
+
+  @POST
+  @Path("location")
+  public Response getLocation(String path) {
+    URI location = createUri(path);
+    Response response = Response.ok().location(location).build();
+    return response;
+  }
+
+  @POST
+  @Path("mediatype")
+  public Response getMediaType(String mediaType) {
+    MediaType media = MediaType.WILDCARD_TYPE;
+    if (mediaType.equals(MediaType.APPLICATION_ATOM_XML))
+      media = MediaType.APPLICATION_ATOM_XML_TYPE;
+    Response response = Response.ok().type(media).build();
+    return response;
+  }
+
+  @POST
+  @Path("statusinfo")
+  public Response getStatusInfo(String status) {
+    Status stat = Status.valueOf(status);
+    Response response = Response.status(stat).build();
+    return response;
+  }
+
+  // For the methods that checks for the header delegate this is the way
+  // to add header delegate by switching runtimedelegate
+  // As long as the runtime delegate is one only for whole classloader
+  @Path("setstringbeanruntime")
+  @GET
+  public Response setStringBeanRuntime() {
+    RuntimeDelegate original = RuntimeDelegate.getInstance();
+    if (!(original instanceof StringBeanRuntimeDelegate)) {
+      StringBeanRuntimeDelegate sbrd = new StringBeanRuntimeDelegate(original);
+      RuntimeDelegate.setInstance(sbrd);
+    }
+    return Response.ok().build();
+  }
+
+  // We need to switch back to the original runtime delegate since
+  // we cannot be sure what happen when the war with our runtimedelegate gets
+  // undeployed
+  @Path("setoriginalruntime")
+  @GET
+  public Response setOriginalRuntime() {
+    Response response = null;
+    RuntimeDelegate stringBeanDelegate = RuntimeDelegate.getInstance();
+    if (stringBeanDelegate instanceof StringBeanRuntimeDelegate) {
+      RuntimeDelegate original = ((StringBeanRuntimeDelegate) stringBeanDelegate)
+          .getOriginal();
+      RuntimeDelegate.setInstance(original);
+      response = Response.ok().build();
+    } else
+      response = Response.status(Status.NO_CONTENT).build();
+    return response;
+  }
+
+  @Path("created")
+  @GET
+  public Response setLocationHeader() {
+    try {
+      Response response = Response.created(new URI("created")).status(200).build();
+      return response;
+    } catch (URISyntaxException e) {
+       throw new RuntimeException(e);
+    }
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  protected static Link createLink(String path, String rel) {
+    return Link.fromUri(createUri(path)).rel(rel).build();
+  }
+
+  protected static URI createUri(String path) {
+    URI uri;
+    try {
+      uri = new URI("http://localhost.tck:888/url404/" + path);
+    } catch (URISyntaxException e) {
+      throw new RuntimeException(e);
+    }
+    return uri;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java
new file mode 100644
index 0000000..16b355c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/response/TSAppConfig.java
@@ -0,0 +1,40 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.response;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.provider.PrintingErrorHandler;
+import jakarta.ws.rs.tck.common.provider.StringBeanHeaderDelegate;
+
+import jakarta.ws.rs.core.Application;
+
+/**
+ *
+ * @author diannejiao
+ */
+public class TSAppConfig extends Application {
+
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(ResponseTest.class);
+    resources.add(StringBeanHeaderDelegate.class);
+    resources.add(PrintingErrorHandler.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java
new file mode 100644
index 0000000..5e495b1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/AnnotatedClass.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Consumes
+/**
+ * This is the dummy class to get annotations from it
+ */
+public abstract class AnnotatedClass {
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java
new file mode 100644
index 0000000..6c0db80
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateClientReaderWriter.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateClientReaderWriter
+    implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+  private StringBuilder atom;
+
+  public DateClientReaderWriter(StringBuilder atom) {
+    super();
+    this.atom = atom;
+  }
+
+  @Override
+  public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4) {
+    return String.valueOf(Long.MAX_VALUE).length()
+        + DateContainerReaderWriter.SPLITTER.length();
+  }
+
+  @Override
+  public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return arg0 == Date.class;
+  }
+
+  @Override
+  public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+      throws IOException, WebApplicationException {
+    stream.write(dateToString(date).getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return isWriteable(arg0, arg1, arg2, arg3);
+  }
+
+  @Override
+  public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+      throws IOException, WebApplicationException {
+    InputStreamReader reader = new InputStreamReader(arg5);
+    BufferedReader br = new BufferedReader(reader);
+    String data = br.readLine();
+    String[] split = data == null ? new String[] { "0" }
+        : data.split(DateContainerReaderWriter.SPLITTER);
+    long date = Long.parseLong(split[0]);
+    atom.append(split[1]);
+    return new Date(date);
+  }
+
+  public static final String dateToString(Date date) {
+    return String.valueOf(date.getTime());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java
new file mode 100644
index 0000000..02f6865
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/DateContainerReaderWriter.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Date;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DateContainerReaderWriter
+    implements MessageBodyReader<Date>, MessageBodyWriter<Date> {
+
+  public static final int ANNOTATION_NONE = 0;
+
+  public static final int ANNOTATION_CONSUMES = 1 << 2;
+
+  public static final int ANNOTATION_PROVIDER = 1 << 3;
+
+  public static final int ANNOTATION_UNKNOWN = 1 << 7;
+
+  public static final String SPLITTER = " ANNOTATION_VALUE ";
+
+  @Override
+  public long getSize(Date arg0, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4) {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    return String.valueOf(Long.MAX_VALUE).length() + SPLITTER.length()
+        + annotations[0].annotationType().getName().length()
+        + annotations[1].annotationType().getName().length();
+  }
+
+  @Override
+  public boolean isWriteable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return arg0 == Date.class;
+  }
+
+  @Override
+  public void writeTo(Date date, Class<?> arg1, Type arg2, Annotation[] arg3,
+      MediaType arg4, MultivaluedMap<String, Object> arg5, OutputStream stream)
+      throws IOException, WebApplicationException {
+    String annotation = parseAnnotations(arg3);
+    stream.write(dateToString(date).getBytes());
+    stream.write(SPLITTER.getBytes());
+    stream.write(annotation.getBytes());
+  }
+
+  @Override
+  public boolean isReadable(Class<?> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3) {
+    return isWriteable(arg0, arg1, arg2, arg3);
+  }
+
+  @Override
+  public Date readFrom(Class<Date> arg0, Type arg1, Annotation[] arg2,
+      MediaType arg3, MultivaluedMap<String, String> arg4, InputStream arg5)
+      throws IOException, WebApplicationException {
+    InputStreamReader reader = new InputStreamReader(arg5);
+    BufferedReader br = new BufferedReader(reader);
+    long date = Long.parseLong(br.readLine());
+    return new Date(date);
+  }
+
+  protected String parseAnnotations(Annotation[] annotations) {
+    StringBuilder value = new StringBuilder();
+    if (annotations != null)
+      for (Annotation annotation : annotations)
+        value.append(annotation.annotationType().getName()).append(", ");
+    return value.toString();
+  }
+
+  public static final String dateToString(Date date) {
+    return String.valueOf(date.getTime());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java
new file mode 100644
index 0000000..3e28970
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/JAXRSClientIT.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.util.Calendar;
+import java.util.Date;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.GenericType;
+import jakarta.ws.rs.core.Response;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 1L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_responsebuilder_web/resource");
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_responsebuilder_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class, AnnotatedClass.class, DateContainerReaderWriter.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: entityObjectTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:879;
+   * 
+   * @test_Strategy: Set the message entity content encoding.
+   */
+  @Test
+  public void entityObjectTest() throws Fault {
+    Date date = Calendar.getInstance().getTime();
+    String entity = DateContainerReaderWriter.dateToString(date);
+    StringBuilder sb = new StringBuilder();
+    DateClientReaderWriter rw = new DateClientReaderWriter(sb);
+    addProvider(rw);
+
+    setProperty(Property.REQUEST, buildRequest(Request.POST, "entity"));
+    setProperty(Property.CONTENT, entity);
+    invoke();
+
+    Response response = getResponse();
+    Date responseDate = response.readEntity(Date.class);
+    assertTrue(date.equals(responseDate), "entity date"+ date+
+        "differs from acquired"+ responseDate);
+
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    for (Annotation annotation : annotations) {
+      String name = annotation.annotationType().getName();
+      assertTrue(sb.toString().contains(name), sb+ "does not contain"+ name+
+          ", annotations not passed to MessageBodyWriter?");
+    }
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  protected <T> GenericType<T> generic(Class<T> clazz) {
+    return new GenericType<T>(clazz);
+  }
+
+  protected String readLine(Reader reader) throws Fault {
+    String line = null;
+    BufferedReader buffered = new BufferedReader(reader);
+    try {
+      line = buffered.readLine();
+    } catch (IOException e) {
+      try {
+        buffered.close();
+      } catch (IOException ie) {
+      }
+      throw new Fault(e);
+    }
+    return line;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java
new file mode 100644
index 0000000..8bb17fd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/Resource.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+import java.lang.annotation.Annotation;
+import java.util.Date;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Response;
+
+@Path("resource")
+public class Resource {
+  @POST
+  @Path("entity")
+  public Response entity(Date date) {
+    Annotation[] annotations = AnnotatedClass.class.getAnnotations();
+    Response response = Response.ok().entity(date, annotations).build();
+    return response;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java
new file mode 100644
index 0000000..527a686
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/TSAppConfig.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.responsebuilder;
+
+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);
+    resources.add(DateContainerReaderWriter.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java
new file mode 100644
index 0000000..32aba1c
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/JAXRSClient.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+import java.util.Properties;
+
+import org.apache.commons.httpclient.Header;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import jakarta.ws.rs.core.Response;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+public abstract class JAXRSClient extends JAXRSCommonClient {
+  private static final long serialVersionUID = 1L;
+
+  protected static final String URL = "Context";
+
+  protected HttpResponse response;
+
+  protected String wwwAuthenticate;
+
+  protected String user;
+
+  protected String password;
+
+  protected String authuser;
+
+  protected String authpassword;
+
+  public void setup() {
+    user = System.getProperty("user");
+    password = System.getProperty("password");
+    authuser = System.getProperty("authuser");
+    authpassword = System.getProperty("authpassword");
+    assertTrue(!isNullOrEmpty(user), "user was not set");
+    assertTrue(!isNullOrEmpty(password),
+        "password was not set");
+    assertTrue(!isNullOrEmpty(authuser),
+        "authuser was not set");
+    assertTrue(!isNullOrEmpty(authpassword),
+        "authpassword was not set");
+    super.setup();
+  }
+
+  public void noAuthorizationTest() throws Fault {
+    setProperty(STATUS_CODE, getStatusCode(Response.Status.UNAUTHORIZED));
+    invokeRequest();
+    assertTrue(wwwAuthenticate != null,
+        "Expected authentication request missing!");
+  }
+
+  protected void invokeRequest() throws Fault {
+    setProperty(REQUEST, buildRequest("GET", URL));
+    invoke();
+    response = _testCase.getResponse();
+    Header header = response.getResponseHeader("WWW-Authenticate");
+    wwwAuthenticate = header == null ? null : header.getValue();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java
new file mode 100644
index 0000000..f7ef354
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+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(TestServlet.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java
new file mode 100644
index 0000000..c3b05ba
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/TestServlet.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.SecurityContext;
+
+@Path("/Servlet")
+public class TestServlet {
+  public static enum Security {
+    SECURED, UNSECURED
+  };
+
+  public static enum Scheme {
+    BASIC, DIGEST, NOSCHEME
+  }
+
+  public static enum Role {
+    DIRECTOR, OTHERROLE, NOROLE
+  }
+
+  private static void addSecuredInfo(SecurityContext context,
+      StringBuilder sb) {
+    Security security;
+    security = context.isSecure() ? Security.SECURED : Security.UNSECURED;
+    sb.append(security).append("|");
+  }
+
+  private static void addSchemaInfo(SecurityContext context, StringBuilder sb) {
+    Scheme scheme;
+    String authScheme = context.getAuthenticationScheme();
+    if (authScheme == null)
+      scheme = Scheme.NOSCHEME;
+    else if (authScheme.equalsIgnoreCase(Scheme.BASIC.name()))
+      scheme = Scheme.BASIC;
+    else
+      scheme = Scheme.DIGEST;
+    sb.append(scheme).append("|");
+  }
+
+  private static void addRoleInfo(SecurityContext context, StringBuilder sb) {
+    java.security.Principal userPrincipal = context.getUserPrincipal();
+    String principal = userPrincipal == null ? "" : userPrincipal.getName();
+    sb.append(principal).append("|");
+  }
+
+  private static void addPrincipalInfo(SecurityContext context,
+      StringBuilder sb) {
+    Role role;
+    if (context.isUserInRole(Role.DIRECTOR.name()))
+      role = Role.DIRECTOR;
+    else if (context.isUserInRole(Role.OTHERROLE.name()))
+      role = Role.OTHERROLE;
+    else
+      role = Role.NOROLE;
+    sb.append(role).append("|");
+  }
+
+  @GET
+  @Path("/Context")
+  public Response test(@Context SecurityContext context) {
+    StringBuilder sb = new StringBuilder();
+    addSecuredInfo(context, sb);
+    addPrincipalInfo(context, sb);
+    addRoleInfo(context, sb);
+    addSchemaInfo(context, sb);
+    return Response.ok(sb.toString()).build();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java
new file mode 100644
index 0000000..b692372
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/JAXRSBasicClientIT.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.securitycontext.basic;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet;
+import jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet.Scheme;
+
+import jakarta.ws.rs.core.Response;
+
+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.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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ *                     user;
+ *                     password;
+ *                     authuser;
+ *                     authpassword;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSBasicClientIT
+    extends jakarta.ws.rs.tck.ee.rs.core.securitycontext.JAXRSClient {
+
+  private static final long serialVersionUID = 340277879725875946L;
+
+  public JAXRSBasicClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_core_securitycontext_basic_web/Servlet");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException {
+
+    InputStream inStream = JAXRSBasicClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_securitycontext_basic_web.war");
+    archive.addClasses(jakarta.ws.rs.tck.ee.rs.core.securitycontext.TSAppConfig.class, jakarta.ws.rs.tck.ee.rs.core.securitycontext.TestServlet.class);
+    archive.setWebXML(new StringAsset(webXml));
+    archive.addAsResource("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml");
+    archive.addAsResource("jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml");
+    return archive;
+
+  }
+
+  /* Run test */
+
+  /*
+   * @testName: noAuthorizationTest
+   * 
+   * @assertion_ids:
+   * 
+   * @test_Strategy: Send no authorization, make sure of 401 response
+   */
+  @Test
+  public void noAuthorizationTest() throws Fault {
+    super.noAuthorizationTest();
+  }
+
+  /*
+   * @testName: basicAuthorizationAdminTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:169; JAXRS:JAVADOC:170; JAXRS:JAVADOC:171;
+   * JAXRS:JAVADOC:172; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Send basic authorization, check security context
+   */
+  //@Test
+  public void basicAuthorizationAdminTest() throws Fault {
+    setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+    setProperty(Property.BASIC_AUTH_USER, user);
+    setProperty(Property.BASIC_AUTH_PASSWD, password);
+
+    setProperty(Property.SEARCH_STRING, TestServlet.Security.UNSECURED.name());
+    setProperty(Property.SEARCH_STRING, TestServlet.Role.DIRECTOR.name());
+    setProperty(Property.SEARCH_STRING, user);
+    setProperty(Property.SEARCH_STRING, TestServlet.Scheme.BASIC.name());
+    invokeRequest();
+  }
+
+  /*
+   * @testName: basicAuthorizationIncorrectUserTest
+   * 
+   * @assertion_ids:
+   * 
+   * @test_Strategy: Send basic authorization, check security context
+   */
+  @Test
+  public void basicAuthorizationIncorrectUserTest() throws Fault {
+    setProperty(Property.STATUS_CODE,
+        getStatusCode(Response.Status.UNAUTHORIZED));
+    setProperty(Property.BASIC_AUTH_USER, Scheme.NOSCHEME.name());
+    setProperty(Property.BASIC_AUTH_PASSWD, password);
+    invokeRequest();
+  }
+
+  /*
+   * @testName: basicAuthorizationIncorrectPasswordTest
+   * 
+   * @assertion_ids:
+   * 
+   * @test_Strategy: Send basic authorization, check security context
+   */
+  @Test
+  public void basicAuthorizationIncorrectPasswordTest() throws Fault {
+    setProperty(Property.STATUS_CODE,
+        getStatusCode(Response.Status.UNAUTHORIZED));
+    setProperty(Property.BASIC_AUTH_USER, authuser);
+    setProperty(Property.BASIC_AUTH_PASSWD, password);
+    invokeRequest();
+  }
+
+  /*
+   * @testName: basicAuthorizationStandardUserTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:169; JAXRS:JAVADOC:170; JAXRS:JAVADOC:171;
+   * JAXRS:JAVADOC:172; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Send basic authorization with made up Realm, check security
+   * context
+   */
+  //@Test
+  public void basicAuthorizationStandardUserTest() throws Fault {
+    setProperty(Property.STATUS_CODE, getStatusCode(Response.Status.OK));
+    setProperty(Property.BASIC_AUTH_USER, authuser);
+    setProperty(Property.BASIC_AUTH_PASSWD, authpassword);
+
+    setProperty(Property.SEARCH_STRING, TestServlet.Security.UNSECURED.name());
+    setProperty(Property.SEARCH_STRING, TestServlet.Role.OTHERROLE.name());
+    setProperty(Property.SEARCH_STRING, authuser);
+    setProperty(Property.SEARCH_STRING, TestServlet.Scheme.BASIC.name());
+    invokeRequest();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml
new file mode 100644
index 0000000..3b846be
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/securitycontext/common.xml
@@ -0,0 +1,58 @@
+<!--
+
+    Copyright (c) 2012, 2018 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
+
+-->
+
+<project name="jaxrs_ee_core_securitycontext" basedir="." default="package" >    
+    <property name="resource.classes" 
+              value="com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet.class,
+    				 com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Security.class,
+    				 com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Scheme.class,
+					 com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Role.class,
+    				 com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TestServlet$Principal.class"/>
+    <property name="appconfig.class"
+              value="com/sun/ts/tests/jaxrs/ee/rs/core/securitycontext/TSAppConfig.class" />
+              
+	<include file="../../../../common/common.xml"/>              
+                     
+	<target name="package" depends="build.TSAppConfig">
+		<ant antfile="${ts.home}/src/com/sun/ts/tests/jaxrs/common/common.xml" target="package"/>
+        <antcall target="copy.sun-web.xml"/>        
+        <antcall target="copy.sun-application.xml"/>        		   
+	</target>    
+	    
+    <target name="copy.sun-web.xml"> 
+        <copy failonerror="true" 
+        file="${app.name}_web.war.sun-web.xml" 
+        tofile="${ts.home}/dist/${pkg.dir}/${app.name}_web.war.sun-web.xml"/>
+    </target>
+    
+    <target name="copy.sun-application.xml">
+        <copy failonerror="true"
+              file="${app.name}_web.ear.sun-application.xml"
+              tofile="${ts.home}/dist/${pkg.dir}/${app.name}_web.ear.sun-application.xml" />    
+    </target>
+	
+	<target name="check.TSAppConfig.built">
+		<available file="${ts.home}/classes/${appconfig.class}" property="ts.app.config.present"/>
+	</target>
+	
+	<target name="build.TSAppConfig" depends="check.TSAppConfig.built" unless="ts.app.config.present">
+		<echo>BUILDING</echo>
+		<ant antfile="../build.xml" useNativeBasedir="true" target="compile"/>
+	</target>	
+    
+</project>
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java
new file mode 100644
index 0000000..9d4a4e8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/JAXRSClientIT.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (c) 2007, 2018 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.uriinfo;
+
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import java.io.InputStream;
+import java.io.IOException;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = -5479757659703717839L;
+
+  protected static final String ROOT = "jaxrs_ee_core_uriinfo_web";
+
+  protected static final String RESOURCE = "resource";
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/" + ROOT + "/" + RESOURCE);
+  }
+
+  
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_core_uriinfo_web.war");
+    archive.addClasses(TSAppConfig.class, URIInfoTest.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: queryTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:249; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that
+   * UriInfo.getQueryParameters() works.
+   */
+  @Test
+  public void queryTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "query?stringtest=cts&inttest=-2147483648?"));
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        "stringtest=cts|inttest=-2147483648?");
+    invoke();
+  }
+
+  /*
+   * @testName: queryTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:250; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that
+   * UriInfo.getQueryParameters(true) works.
+   */
+  @Test
+  public void queryTest1() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET,
+        "query1?stringtest=cts%20&inttest=-2147483648?%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        "stringtest=cts |inttest=-2147483648? 10");
+    invoke();
+  }
+
+  /*
+   * @testName: queryTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:250; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that
+   * UriInfo.getQueryParameters(false) works.
+   */
+  @Test
+  public void queryTest2() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "query2?stringtest=cts%20&inttest=-2147483648%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        "stringtest=cts%20|inttest=-2147483648%2010");
+    invoke();
+  }
+
+  /*
+   * @testName: aPathTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:236; JAXRS:JAVADOC:237;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getAbsolutePath() and
+   * getAbsolutePathBuilder() work.
+   */
+  @Test
+  public void aPathTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "apath"));
+    setProperty(Property.SEARCH_STRING,
+        "http://" + _hostname + ":" + _port + getContextRoot() + "/apath");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+    invoke();
+  }
+
+  /*
+   * @testName: baseUriTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:238; JAXRS:JAVADOC:239;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getBaseUri() and
+   * getBaseUriBuilder() work.
+   */
+  @Test
+  public void baseUriTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "baseuri"));
+    setProperty(Property.SEARCH_STRING,
+        "http://" + _hostname + ":" + _port + "/" + ROOT);
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+    invoke();
+  }
+
+  /*
+   * @testName: pathTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:243;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPath() work.
+   */
+  @Test
+  public void pathTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "path"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/path");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:244;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPath(true) work.
+   */
+  @Test
+  public void pathTest1() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "path1%20/%2010"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/path1 / 10");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:244;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPath(false) work.
+   */
+  @Test
+  public void pathTest2() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "path2%20/%2010"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/path2%20/%2010");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathSegTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:247;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathSegments() work.
+   */
+  @Test
+  public void pathSegTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathseg"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+    setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathSegTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:248;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathSegments(true) work.
+   */
+  @Test
+  public void pathSegTest1() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathseg1%20/%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+    setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg1 / 10/");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathSegTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:248;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathSegments(false) work.
+   */
+  @Test
+  public void pathSegTest2() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathseg2%20/%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, RESOURCE);
+    setProperty(Property.UNORDERED_SEARCH_STRING, "pathseg2%20/%2010/");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:245; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathParameters() work.
+   */
+  @Test
+  public void pathParamTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathparam/a/b"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, "a=a|b=b");
+    invoke();
+  }
+
+  /*
+   * @testName: pathParamTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:246; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathParameters(true) work.
+   */
+  @Test
+  public void pathParamTest1() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathparam1/%20/%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, "a= |b= 10");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathParamTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:246; JAXRS:JAVADOC:97;
+   * 
+   * @test_Strategy: Client send a request to a resource, which handles the
+   * request using UriInfo. Verify that UriInfo.getPathParameters(false) work.
+   */
+  @Test
+  public void pathParamTest2() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "pathparam2/%20/%2010"));
+    setProperty(Property.UNORDERED_SEARCH_STRING, "a=%20|b=%2010");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, ROOT);
+    invoke();
+  }
+
+  /*
+   * @testName: requestURITest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:251; JAXRS:JAVADOC:252;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that getRequestUri() and
+   * getRequestUriBuilder() work.
+   */
+  @Test
+  public void requestURITest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "request?stringtest=cts&inttest=-2147483648"));
+    setProperty(Property.UNORDERED_SEARCH_STRING,
+        "http://" + _hostname + ":" + _port + getContextRoot()
+            + "/request?stringtest=cts&inttest=-2147483648");
+    setProperty(Property.UNEXPECTED_RESPONSE_MATCH, "FAILED");
+    invoke();
+  }
+
+  /*
+   * @testName: getMatchedResourcesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:240; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that getMatchedResources()
+   * work.
+   */
+  @Test
+  public void getMatchedResourcesTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "resource"));
+    setProperty(Property.SEARCH_STRING, URIInfoTest.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getMatchedURIsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:241;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that getMatchedURIs() work.
+   */
+  @Test
+  public void getMatchedURIsTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "uri"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/uri");
+    setProperty(Property.SEARCH_STRING, RESOURCE);
+    setProperty(Property.SEARCH_STRING, "number=2");
+    invoke();
+  }
+
+  /*
+   * @testName: getMatchedURIsTest1
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:242;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that getMatchedURIs(true)
+   * work.
+   */
+  @Test
+  public void getMatchedURIsTest1() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "uri1"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/uri1");
+    setProperty(Property.SEARCH_STRING, RESOURCE);
+    setProperty(Property.SEARCH_STRING, "number=2");
+    invoke();
+  }
+
+  /*
+   * @testName: getMatchedURIsTest2
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:242;
+   * 
+   * @test_Strategy: Client send a request with query parameters to a resource,
+   * which handles the request using UriInfo. Verify that getMatchedURIs(false)
+   * work.
+   */
+  @Test
+  public void getMatchedURIsTest2() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, "uri2"));
+    setProperty(Property.SEARCH_STRING, RESOURCE + "/uri2");
+    setProperty(Property.SEARCH_STRING, RESOURCE);
+    setProperty(Property.SEARCH_STRING, "number=2");
+    invoke();
+  }
+
+  /*
+   * @testName: getNormalizedUriTest
+   * 
+   * @assertion_ids: JAXRS:SPEC:61;
+   * 
+   * @test_Strategy: The normalized request URI MUST be reflected in the URIs
+   * obtained from an injected UriInfo
+   */
+  @Test
+  public void getNormalizedUriTest() throws Fault {
+    setProperty(Property.REQUEST, buildRequest(GET, URIInfoTest.DECODED));
+    invoke();
+    assertBodyGreaterThanOne();
+
+    setProperty(Property.REQUEST, buildRequest(GET, URIInfoTest.ENCODED));
+    invoke();
+    assertBodyGreaterThanOne();
+  }
+
+  private void assertBodyGreaterThanOne() throws Fault {
+    int i = Integer.parseInt(getResponseBody());
+    assertTrue(i > 1, "Got unexpected response body"+ getResponseBody());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java
new file mode 100644
index 0000000..346b2e7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.uriinfo;
+
+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(URIInfoTest.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java
new file mode 100644
index 0000000..e744479
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/core/uriinfo/URIInfoTest.java
@@ -0,0 +1,244 @@
+/*
+ * 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.core.uriinfo;
+
+import java.net.URI;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.PathSegment;
+import jakarta.ws.rs.core.UriBuilder;
+import jakarta.ws.rs.core.UriInfo;
+
+@Path(value = "resource")
+public class URIInfoTest {
+
+  @GET
+  @Path("/query")
+  public String queryTest(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getQueryParameters().keySet()) {
+      buf.append(param + "=" + info.getQueryParameters().getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/query1")
+  public String queryTest1(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getQueryParameters(true).keySet()) {
+      buf.append(param + "=" + info.getQueryParameters(true).getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/query2")
+  public String queryTest2(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getQueryParameters(false).keySet()) {
+      buf.append(param + "=" + info.getQueryParameters(false).getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/apath")
+  public String apathTest(@Context UriInfo info) {
+    StringBuilder sb = new StringBuilder();
+    URI uri = info.getAbsolutePath();
+    UriBuilder urib = info.getAbsolutePathBuilder();
+
+    sb.append(uri.toString());
+    if (!uri.toString().equals(urib.build().toString())) {
+      sb.append("Got unexpected = " + urib.build().toString());
+      sb.append("FAILED");
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/path")
+  public String pathTest(@Context UriInfo info) {
+    return info.getPath();
+  }
+
+  @GET
+  @Path("/path1%20/%2010")
+  public String pathTest1(@Context UriInfo info) {
+    return info.getPath(true);
+  }
+
+  @GET
+  @Path("/path2%20/%2010")
+  public String pathTest2(@Context UriInfo info) {
+    return info.getPath(false);
+  }
+
+  @GET
+  @Path("/baseuri")
+  public String baseUriTest(@Context UriInfo info) {
+    StringBuilder sb = new StringBuilder();
+    URI uri = info.getBaseUri();
+    UriBuilder urib = info.getBaseUriBuilder();
+
+    sb.append(uri.toString());
+    if (!uri.toString().equals(urib.build().toString())) {
+      sb.append("Got unexpected = " + urib.build().toString());
+      sb.append("FAILED");
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/pathparam/{a}/{b}")
+  public String pathparamTest(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getPathParameters().keySet()) {
+      buf.append(param + "=" + info.getPathParameters().getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/pathparam1/{a}/{b}")
+  public String pathparamTest1(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getPathParameters(true).keySet()) {
+      buf.append(param + "=" + info.getPathParameters(true).getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/pathparam2/{a}/{b}")
+  public String pathparamTest2(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String param : info.getPathParameters(false).keySet()) {
+      buf.append(param + "=" + info.getPathParameters(false).getFirst(param));
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/pathseg")
+  public String pathsegTest(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (PathSegment param : info.getPathSegments()) {
+      buf.append(param.getPath() + "/");
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/pathseg1%20/%2010")
+  public String pathsegTest1(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (PathSegment param : info.getPathSegments(true)) {
+      buf.append(param.getPath() + "/");
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/pathseg2%20/%2010")
+  public String pathsegTest2(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (PathSegment param : info.getPathSegments(false)) {
+      buf.append(param.getPath() + "/");
+    }
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/request")
+  public String requestTest(@Context UriInfo info) {
+    StringBuilder sb = new StringBuilder();
+    URI uri = info.getRequestUri();
+    UriBuilder urib = info.getRequestUriBuilder();
+
+    sb.append(uri.toString());
+    if (!uri.toString().equals(urib.build().toString())) {
+      sb.append("Got unexpected = " + urib.build().toString());
+      sb.append("FAILED");
+    }
+    return sb.toString();
+  }
+
+  @GET
+  @Path("/resource")
+  public String resourcesTest(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (Object resource : info.getMatchedResources()) {
+      buf.append(resource.toString() + "=");
+    }
+    buf.append("number=" + info.getMatchedResources().size());
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/uri")
+  public String urisTest(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (Object resource : info.getMatchedURIs()) {
+      buf.append(resource.toString() + "=");
+    }
+    buf.append("number=" + info.getMatchedURIs().size());
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/uri1")
+  public String urisTest1(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String resource : info.getMatchedURIs(true)) {
+      buf.append(resource + "=");
+    }
+    buf.append("number=" + info.getMatchedURIs(true).size());
+    return buf.toString();
+  }
+
+  @GET
+  @Path("/uri2")
+  public String urisTest2(@Context UriInfo info) {
+    StringBuilder buf = new StringBuilder();
+    for (String resource : info.getMatchedURIs(false)) {
+      buf.append(resource + "=");
+    }
+    buf.append("number=" + info.getMatchedURIs(false).size());
+    return buf.toString();
+  }
+
+  public static final String ENCODED = "%50%51%52%30%39%70%71%72/%7e%2d%2E%5f";
+
+  public static final String DECODED = "PQR09pqr/~-._";
+
+  @GET
+  @Path("{id1}/{id2}")
+  public String normalizedUri(@Context UriInfo info) {
+    int ret = 1;
+    if (!info.getAbsolutePath().toString().contains(ENCODED))
+      ret += 10;
+    if (!info.getPath().toString().contains(ENCODED))
+      ret += 100;
+    if (!info.getRequestUri().toString().contains(ENCODED))
+      ret += 1000;
+    return String.valueOf(ret);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java
new file mode 100644
index 0000000..9a3532e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumContextResolver.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.contextresolver;
+
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class EnumContextResolver implements ContextResolver<EnumProvider> {
+
+  @Override
+  public EnumProvider getContext(Class<?> type) {
+    return type == EnumProvider.class ? EnumProvider.JAXRS : null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java
new file mode 100644
index 0000000..e0b69e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/EnumProvider.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.contextresolver;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+public enum EnumProvider {
+  TCK, CTS, JAXRS;
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java
new file mode 100644
index 0000000..5ade242
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/contextresolver/TextPlainEnumContextResolver.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.contextresolver;
+
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+@Produces(MediaType.TEXT_PLAIN)
+public class TextPlainEnumContextResolver
+    implements ContextResolver<EnumProvider> {
+  @Override
+  public EnumProvider getContext(Class<?> type) {
+    return type == EnumProvider.class ? EnumProvider.CTS : null;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java
new file mode 100644
index 0000000..6065478
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/AnyExceptionExceptionMapper.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class AnyExceptionExceptionMapper implements ExceptionMapper<Exception> {
+
+  @Override
+  public Response toResponse(Exception arg0) {
+    Status status = Status.NO_CONTENT;
+    if (arg0 instanceof WebApplicationException)
+      return ((WebApplicationException) arg0).getResponse();
+    else if (arg0 instanceof RuntimeException)
+      throw new RuntimeException("CTS Test RuntimeException", arg0);
+    else if (arg0 instanceof IOException)
+      status = Status.SERVICE_UNAVAILABLE;
+    else if (arg0 != null)
+      status = Status.NOT_ACCEPTABLE;
+    return Response.status(status).build();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java
new file mode 100644
index 0000000..3d37bbe
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/exceptionmapper/IOExceptionExceptionMapper.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class IOExceptionExceptionMapper
+    implements ExceptionMapper<IOException> {
+
+  @Override
+  public Response toResponse(IOException exception) {
+    return Response.status(Status.ACCEPTED).build();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java
new file mode 100644
index 0000000..f0a4b6f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/WriterClient.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.clientwriter;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ * 
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class WriterClient<CONTEXTOPERATION extends Enum<?>>
+    extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 8110273180216593061L;
+
+  /**
+   * Set the header OPERATION to a proper value Also set the entity, it is good
+   * as it is here for most of the tests. For the rest, the entity needs to be
+   * replaced.
+   */
+  protected void setOperationAndEntity(CONTEXTOPERATION op) {
+    addHeader(TemplateInterceptorBody.OPERATION, op.name());
+    setRequestContentEntity(TemplateInterceptorBody.ENTITY);
+  }
+
+  /**
+   * Invoke and convert IOException to Fault
+   */
+  protected void invoke() throws Fault {
+    try {
+      setProperty(Property.REQUEST, buildRequest(Request.POST, ""));
+      super.invoke();
+    } catch (Exception cause) {
+      if (cause instanceof IOException)
+        throw new Fault(cause.getMessage());
+      else
+        throw new Fault(cause);
+    }
+  }
+
+  /**
+   * Register providers to client configuration
+   * 
+   * @param response
+   *          ClientRequestFilter#abortWith response
+   */
+  protected abstract void addProviders();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..fdb6680
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,383 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorTwo;
+
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+  private static final long serialVersionUID = -5479399808367387477L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_clientwriter_interceptorcontext_web/resource");
+    addProviders();
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_clientwriter_interceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getAnnotationsTest() throws Fault {
+    Annotation[] annotations = ContextOperation.class.getAnnotations();
+    Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+        MediaType.WILDCARD_TYPE, annotations);
+    setOperationAndEntity(ContextOperation.GETANNOTATIONS);
+    setRequestContentEntity(entity);
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getGenericTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETGENERICTYPE);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get media type of HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getMediaTypeTest() throws Fault {
+    Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+        MediaType.APPLICATION_JSON_TYPE);
+    setOperationAndEntity(ContextOperation.GETMEDIATYPE);
+    setRequestContentEntity(entity);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns null if there is no property by that name.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyIsNullTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns an enumeration containing the property names
+   * available within the context of the current request/response exchange
+   * context.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyNamesTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTYNAMES);
+    for (int i = 0; i != 5; i++)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          TemplateInterceptorBody.PROPERTY + i);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesIsReadOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection containing the
+   * property names available within the context of the current request/response
+   * exchange context.
+   * 
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyNamesIsReadOnlyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTYNAMESISREADONLY);
+    setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get Java type supported by corresponding message body
+   * provider.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETTYPE);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: removePropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Removes a property with the given name from the current
+   * request/response exchange context. After removal, subsequent calls to
+   * getProperty(java.lang.String) to retrieve the property value will return
+   * null.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void removePropertyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.REMOVEPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update annotations on the formal declaration of the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setAnnotationsTest() throws Fault {
+    Annotation[] annotations = WriterInterceptorOne.class.getAnnotations();
+    setOperationAndEntity(ContextOperation.SETANNOTATIONS);
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsNullThrowsNPETest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Throws NullPointerException - in case the input parameter
+   * is null.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setAnnotationsNullThrowsNPETest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETANNOTATIONSNULL);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+    invoke();
+  }
+
+  /*
+   * @testName: setGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update type of the object to be produced or written.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setGenericTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETGENERICTYPE);
+    setProperty(Property.SEARCH_STRING, "[B");
+    invoke();
+  }
+
+  /*
+   * @testName: setMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update media type of HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setMediaTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETMEDIATYPE);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Binds an object to a given property name in the current
+   * request/response exchange context. If the name specified is already used
+   * for a property, this method will replace the value of the property with the
+   * new value.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setPropertyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: If a null value is passed, the effect is the same as
+   * calling the removeProperty(String) method.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setPropertyNullTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETPROPERTYNULL);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update Java type before calling message body provider.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setTypeTest() throws Fault {
+    ByteArrayInputStream bais = new ByteArrayInputStream(
+        TemplateInterceptorBody.ENTITY.getBytes());
+    Reader reader = new InputStreamReader(bais);
+    setOperationAndEntity(ContextOperation.SETTYPE);
+    setRequestContentEntity(reader);
+    addProvider(InputStreamReaderProvider.class);
+    invoke();
+    InputStreamReader isr = getResponseBody(InputStreamReader.class);
+    try {
+      String entity = JaxrsUtil.readFromReader(isr);
+      assertTrue(entity.contains(InputStreamReader.class.getName()),
+          "Expected"+ InputStreamReader.class.getName()+ "not found");
+      logMsg("#setType set correct type", entity);
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+  }
+
+  // /////////////////////////////////////////////////////////////////////
+  @Override
+  protected void addProviders() {
+    addProvider(WriterInterceptorTwo.class);
+    addProvider(new WriterInterceptorOne());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java
new file mode 100644
index 0000000..45c0545
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/Resource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+  @POST
+  public String post(String entity) {
+    return entity;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..070c688
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.interceptorcontext;
+
+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/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..4cdb0e5
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.OnWriteExceptionThrowingStringBean;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ProceedException;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorTwo;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+  private static final long serialVersionUID = 2500912584762173255L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_clientwriter_writerinterceptorcontext_web/resource");
+    addProviders();
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_clientwriter_writerinterceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:933; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get object to be written as HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getEntityTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETENTITY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY);
+    invoke();
+  }
+
+  /*
+   * @testName: getHeadersOperationOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersOperationOnlyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETHEADERS);
+    setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+        TemplateInterceptorBody.OPERATION);
+    invoke();
+  }
+
+  /*
+   * @testName: getHeadersTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersTest() throws Fault {
+    Property p = Property.UNORDERED_SEARCH_STRING;
+    setOperationAndEntity(ContextOperation.GETHEADERS);
+    setProperty(p, TemplateInterceptorBody.OPERATION);
+    setTextCaser(TextCaser.LOWER);
+    for (int i = 0; i != 5; i++) {
+      addHeader(TemplateInterceptorBody.PROPERTY + i, "any");
+      setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+    }
+    invoke();
+  }
+
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersIsMutableTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETHEADERSISMUTABLE);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+    invoke();
+  }
+
+  /*
+   * @testName: getOutputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:935; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get the output stream for the object to be written.
+   * 
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getOutputStreamTest() throws Fault {
+    Property p = Property.UNORDERED_SEARCH_STRING;
+    setOperationAndEntity(ContextOperation.GETOUTPUTSTREAM);
+    setProperty(p, TemplateInterceptorBody.ENTITY);
+    setProperty(p, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsIOExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:937; JAXRS:JAVADOC:930;
+   * JAXRS:JAVADOC:931;
+   * 
+   * @test_Strategy: Proceed to the next interceptor in the chain.
+   * Throws:IOException - if an IO exception arises.
+   * 
+   * proceed is actually called in every clientwriter.writerinterceptorcontext
+   * test
+   *
+   * WriterInterceptor.aroundWriteTo
+   * 
+   * WriterInterceptor.aroundWriteTo throws IOException
+   */
+  @Test
+  public void proceedThrowsIOExceptionTest() throws Fault {
+    setOperationAndEntity(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:1009; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Proceed to the next interceptor in the chain.
+   * Throws:WebApplicationException - thrown by the wrapped {@code
+   * MessageBodyWriter.writeTo} method.
+   * 
+   * proceed is actually called in every clientwriter.writerinterceptorcontext
+   * test
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+    addProvider(StringBeanEntityProvider.class);
+    addHeader(TemplateInterceptorBody.OPERATION,
+        ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION.name());
+    setRequestContentEntity(
+        new OnWriteExceptionThrowingStringBean(TemplateInterceptorBody.ENTITY));
+    try {
+      invoke();
+    } catch (Exception e) {
+      ProceedException p = assertCause(e, ProceedException.class,
+          "Proceed did not throw exception");
+      assertContains(p.getMessage(), TemplateInterceptorBody.WAE,
+          "Unexpected message received", p.getMessage());
+      logMsg(p.getMessage());
+    }
+  }
+
+  /*
+   * @testName: setEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:938; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update object to be written as HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setEntityTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETENTITY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+    invoke();
+  }
+
+  /*
+   * @testName: setOutputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:939; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update the output stream for the object to be written.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setOutputStreamTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETOUTPUTSTREAM);
+    setProperty(Property.SEARCH_STRING,
+        TemplateInterceptorBody.ENTITY.replace('t', 'x'));
+    invoke();
+  }
+
+  // /////////////////////////////////////////////////////////////////////
+  @Override
+  protected void addProviders() {
+    addProvider(new WriterInterceptorTwo());
+    addProvider(WriterInterceptorOne.class);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..14e1c30
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/Resource.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+  @POST
+  public String post(String entity) {
+    return entity;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..18ef1de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.clientwriter.writerinterceptorcontext;
+
+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/ext/interceptor/containerreader/ReaderClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/ReaderClient.java
new file mode 100644
index 0000000..22949b1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/ReaderClient.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.containerreader;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ * 
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class ReaderClient<CONTEXTOPERATION extends Enum<?>>
+    extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 8110273180216593061L;
+
+  /**
+   * Set the header OPERATION to a proper value Also set the entity, it is good
+   * as it is here for most of the tests. For the rest, the entity needs to be
+   * replaced.
+   */
+  protected void setOperationAndEntity(CONTEXTOPERATION op) {
+    addHeader(TemplateInterceptorBody.OPERATION, op.name());
+    setRequestContentEntity(TemplateInterceptorBody.ENTITY);
+  }
+
+  /**
+   * Invoke and convert IOException to Fault
+   */
+  protected void invoke() throws Fault {
+    invoke("string");
+  }
+
+  /**
+   * Invoke and convert IOException to Fault
+   */
+  protected void invoke(String method) throws Fault {
+    try {
+      setProperty(Property.REQUEST, buildRequest(Request.POST, method));
+      super.invoke();
+    } catch (Exception cause) {
+      if (cause instanceof IOException)
+        throw new Fault(cause.getMessage());
+      else
+        throw new Fault(cause);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..604dcc2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.ReaderClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.MediaType;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends ReaderClient<ContextOperation> {
+
+  private static final long serialVersionUID = 6573164759617152350L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_containerreader_interceptorcontext_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerreader_interceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class,
+      jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+      jakarta.ws.rs.tck.common.JAXRSCommonClient.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorOne.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorTwo.class,
+      Resource.class);
+    archive.addPackages(false, "jakarta.ws.rs.tck.common.client",
+      "jakarta.ws.rs.tck.common.webclient", 
+      "jakarta.ws.rs.tck.common.webclient.handler",
+      "jakarta.ws.rs.tck.common.webclient.http",
+      "jakarta.ws.rs.tck.common.webclient.validation",
+      "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+      "jakarta.ws.rs.tck.api.rs.ext.interceptor.reader"
+    );
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getAnnotationsTest() throws Fault {
+    Method m;
+    try {
+      m = Resource.class.getMethod("post", String.class);
+    } catch (Exception e) {
+      throw new Fault(e);
+    }
+    Annotation[] annotations = m.getParameterAnnotations()[0];
+    Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+        MediaType.WILDCARD_TYPE, annotations);
+    setOperationAndEntity(ContextOperation.GETANNOTATIONS);
+    setRequestContentEntity(entity);
+    setTextCaser(TextCaser.LOWER); // Case insensitive
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getGenericTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETGENERICTYPE);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get media type of HTTP entity.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getMediaTypeTest() throws Fault {
+    Entity<String> entity = Entity.entity(TemplateInterceptorBody.ENTITY,
+        MediaType.APPLICATION_JSON_TYPE);
+    setOperationAndEntity(ContextOperation.GETMEDIATYPE);
+    setRequestContentEntity(entity);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Returns null if there is no property by that name.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getPropertyIsNullTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection containing the
+   * property names available within the context of the current request/response
+   * exchange context.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getPropertyNamesTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTYNAMES);
+    for (int i = 0; i != 5; i++)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          TemplateInterceptorBody.PROPERTY + i);
+    invoke();
+  }
+
+  /*
+   * @testName: getPropertyNamesIsReadOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection containing the
+   * property names available within the context of the current request/response
+   * exchange context.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getPropertyNamesIsReadOnlyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETPROPERTYNAMESISREADONLY);
+    setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: getTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get Java type supported by corresponding message body
+   * provider.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETTYPE);
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke();
+  }
+
+  /*
+   * @testName: removePropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Removes a property with the given name from the current
+   * request/response exchange context. After removal, subsequent calls to
+   * getProperty(java.lang.String) to retrieve the property value will return
+   * null.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void removePropertyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.REMOVEPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Update annotations on the formal declaration of the
+   * artifact that initiated the intercepted entity provider invocation.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setAnnotationsTest() throws Fault {
+    Annotation[] annotations = WriterInterceptorOne.class.getAnnotations();
+    setOperationAndEntity(ContextOperation.SETANNOTATIONS);
+    setTextCaser(TextCaser.LOWER);
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke();
+  }
+
+  /*
+   * @testName: setAnnotationsNullThrowsNPETest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Throws NullPointerException - in case the input parameter
+   * is null.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setAnnotationsNullThrowsNPETest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETANNOTATIONSNULL);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+    invoke();
+  }
+
+  /*
+   * @testName: setGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Update type of the object to be produced or written.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setGenericTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETGENERICTYPE);
+    setProperty(Property.SEARCH_STRING, "[B");
+    invoke();
+  }
+
+  /*
+   * @testName: setMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Update media type of HTTP entity.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setMediaTypeTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETMEDIATYPE);
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Binds an object to a given property name in the current
+   * request/response exchange context. If the name specified is already used
+   * for a property, this method will replace the value of the property with the
+   * new value.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setPropertyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETPROPERTY);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke();
+  }
+
+  /*
+   * @testName: setPropertyNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: If a null value is passed, the effect is the same as
+   * calling the removeProperty(String) method.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setPropertyNullTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETPROPERTYNULL);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke();
+  }
+
+  /*
+   * @testName: setTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Update Java type before calling message body provider.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setTypeTest() throws Fault {
+    ByteArrayInputStream bais = new ByteArrayInputStream(
+        TemplateInterceptorBody.ENTITY.getBytes());
+    Reader reader = new InputStreamReader(bais);
+    setOperationAndEntity(ContextOperation.SETTYPE);
+    setRequestContentEntity(reader);
+    addProvider(InputStreamReaderProvider.class);
+    invoke("inputstreamreader");
+    InputStreamReader isr = getResponseBody(InputStreamReader.class);
+    try {
+      String entity = JaxrsUtil.readFromReader(isr);
+      assertTrue(entity.contains(InputStreamReader.class.getName()),
+          "Expected"+ InputStreamReader.class.getName()+ "not found");
+      logMsg("#setType set correct type", entity);
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java
new file mode 100644
index 0000000..1997acc
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/Resource.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+  @POST
+  @Path("string")
+  public String post(@NotNull @Size(min = 2) String entity) {
+    return entity;
+  }
+
+  @POST
+  @Path("inputstreamreader")
+  public String post(InputStreamReader reader) throws IOException {
+    String entity = JaxrsUtil.readFromReader(reader);
+    reader.close();
+    return entity;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..451b74a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.interceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.interceptorcontext.ReaderInterceptorTwo;
+
+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);
+    resources.add(ReaderInterceptorOne.class);
+    resources.add(ReaderInterceptorTwo.class);
+    resources.add(InputStreamReaderProvider.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..c54b3ef
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,230 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.common.client.TextCaser;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.ReaderClient;
+
+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.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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends ReaderClient<ContextOperation> {
+
+  private static final long serialVersionUID = 3006391868445878375L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_containerreader_readerinterceptorcontext_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerreader_readerinterceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class, Resource.class,
+      jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+      jakarta.ws.rs.tck.common.provider.StringBean.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.ReaderClient.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.TemplateReaderInterceptor.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBean.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBeanEntityProvider.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorOne.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorTwo.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.InterceptorOneBody.class,
+      jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.InterceptorTwoBody.class
+    );
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: getHeadersOperationOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getHeadersOperationOnlyTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETHEADERS);
+    setProperty(Property.SEARCH_STRING_IGNORE_CASE,
+        TemplateInterceptorBody.OPERATION);
+    setPrintEntity(true);
+    invoke();
+  }
+
+  /*
+   * @testName: getHeadersHeadersSetTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getHeadersHeadersSetTest() throws Fault {
+    Property p = Property.UNORDERED_SEARCH_STRING;
+    setOperationAndEntity(ContextOperation.GETHEADERS);
+    setProperty(p, TemplateInterceptorBody.OPERATION);
+    setTextCaser(TextCaser.LOWER);
+    for (int i = 0; i != 5; i++) {
+      addHeader(TemplateInterceptorBody.PROPERTY + i, "any");
+      setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+    }
+    invoke();
+  }
+
+  /* Run test */
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:923; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getHeadersIsMutableTest() throws Fault {
+    setOperationAndEntity(ContextOperation.GETHEADERSISMUTABLE);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+    invoke();
+  }
+
+  /*
+   * @testName: getInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:924; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Get the input stream of the object to be read.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void getInputStreamTest() throws Fault {
+    String entity = "getInputStreamEntity";
+    setOperationAndEntity(ContextOperation.GETINPUTSTREAM);
+    setRequestContentEntity(entity);
+    setProperty(Property.SEARCH_STRING, entity);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsIOExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:926; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Throws: IOException - if an IO error arises
+   * 
+   * proceed is actually called in every
+   * containerreader.readerinterceptorcontext test
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void proceedThrowsIOExceptionTest() throws Fault {
+    setOperationAndEntity(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+    invoke();
+  }
+
+  /*
+   * @testName: proceedThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:925; JAXRS:JAVADOC:1008; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Throws: WebApplicationException - thrown by the wrapped
+   * {@code MessageBodyReader.readFrom} method.
+   * 
+   * Proceed is tested in any of the interceptor tests.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+    setOperationAndEntity(ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.WAE);
+    invoke("errorbean");
+  }
+
+  /*
+   * @testName: setInputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:927; JAXRS:JAVADOC:920;
+   * 
+   * @test_Strategy: Update the input stream of the object to be read.
+   * 
+   * ReaderInterceptor.aroundReadFrom
+   */
+  @Test
+  public void setInputStreamTest() throws Fault {
+    setOperationAndEntity(ContextOperation.SETINPUTSTREAM);
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke();
+  }
+
+  // =====================
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..2a08540
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/Resource.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBean;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+
+@Path("resource")
+public class Resource {
+
+  @POST
+  @Path("string")
+  public String post(String entity) {
+    return entity;
+  }
+
+  @POST
+  @Path("errorbean")
+  public String errorBean(ExceptionThrowingStringBean bean) {
+    return bean.get();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..cad2721
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerreader.readerinterceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ExceptionThrowingStringBeanEntityProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorOne;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.reader.readerinterceptorcontext.ReaderInterceptorTwo;
+
+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);
+    resources.add(ReaderInterceptorOne.class);
+    resources.add(ReaderInterceptorTwo.class);
+    resources.add(ExceptionThrowingStringBeanEntityProvider.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java
new file mode 100644
index 0000000..840f835
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/WriterClient.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.containerwriter;
+
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+
+/**
+ * Client with given ContextOperation enum, so that an enum name is passed as a
+ * http header to an interceptor. Due to the ContextOperation, the proper method
+ * on an interceptor is called.
+ * 
+ * @param <CONTEXTOPERATION>
+ */
+public abstract class WriterClient<CONTEXTOPERATION extends Enum<?>>
+    extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = -9222693803307311300L;
+
+  /**
+   * Invoke and convert CONTEXTOPERATION to a path
+   */
+  protected void invoke(CONTEXTOPERATION op) throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(Request.GET, op.name().toLowerCase()));
+    super.invoke();
+  }
+
+  /**
+   * Invoke and convert CONTEXTOPERATION to a path
+   */
+  protected void invoke(CONTEXTOPERATION op, Request method) throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(method, op.name().toLowerCase()));
+    super.invoke();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..a588331
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,350 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.io.InputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.WriterClient;
+
+import jakarta.ws.rs.core.MediaType;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+  private static final long serialVersionUID = -3980167967224950515L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_containerwriter_interceptorcontext_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerwriter_interceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class, 
+      jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+      jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor.class,
+      Resource.class);
+    archive.addPackages(false, "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+      "jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext");
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:903; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getAnnotationsTest() throws Fault {
+    Annotation[] annotations = ContextOperation.class.getAnnotations();
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke(ContextOperation.GETANNOTATIONS);
+  }
+
+  /*
+   * @testName: getGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:904; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get an array of the annotations formally declared on the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getGenericTypeTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke(ContextOperation.GETGENERICTYPE);
+  }
+
+  /*
+   * @testName: getMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:905; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get media type of HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getMediaTypeTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_JSON);
+    invoke(ContextOperation.GETMEDIATYPE);
+  }
+
+  /*
+   * @testName: getPropertyIsNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:906; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns null if there is no property by that name.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyIsNullTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke(ContextOperation.GETPROPERTY);
+  }
+
+  /*
+   * @testName: getPropertyNamesIsReadOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns immutable java.util.Collection containing the
+   * property names available within the context of the current request/response
+   * exchange context.
+   * 
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyNamesIsReadOnlyTest() throws Fault {
+    setProperty(Property.UNORDERED_SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke(ContextOperation.GETPROPERTYNAMESISREADONLY);
+  }
+
+  /*
+   * @testName: getPropertyNamesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:1007; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Returns an enumeration containing the property names
+   * available within the context of the current request/response exchange
+   * context.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getPropertyNamesTest() throws Fault {
+    for (int i = 0; i != 5; i++)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          TemplateInterceptorBody.PROPERTY + i);
+    invoke(ContextOperation.GETPROPERTYNAMES);
+  }
+
+  /*
+   * @testName: getTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:908; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get Java type supported by corresponding message body
+   * provider.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getTypeTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, String.class.getName());
+    invoke(ContextOperation.GETTYPE);
+  }
+
+  /*
+   * @testName: removePropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:909; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Removes a property with the given name from the current
+   * request/response exchange context. After removal, subsequent calls to
+   * getProperty(java.lang.String) to retrieve the property value will return
+   * null.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void removePropertyTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke(ContextOperation.REMOVEPROPERTY);
+  }
+
+  /*
+   * @testName: setAnnotationsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update annotations on the formal declaration of the
+   * artifact that initiated the intercepted entity provider invocation.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setAnnotationsTest() throws Fault {
+    Annotation[] annotations = ContextOperation.class.getAnnotations();
+    for (Annotation a : annotations)
+      setProperty(Property.UNORDERED_SEARCH_STRING,
+          a.annotationType().getName());
+    invoke(ContextOperation.SETANNOTATIONS);
+  }
+
+  /*
+   * @testName: setAnnotationsNullThrowsNPETest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:910; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Throws NullPointerException - in case the input parameter
+   * is null.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setAnnotationsNullThrowsNPETest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NPE);
+    invoke(ContextOperation.SETANNOTATIONSNULL);
+  }
+
+  /*
+   * @testName: setGenericTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:911; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update type of the object to be produced or written.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setGenericTypeTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, "[B");
+    invoke(ContextOperation.SETGENERICTYPE);
+  }
+
+  /*
+   * @testName: setMediaTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:912; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update media type of HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setMediaTypeTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, MediaType.APPLICATION_FORM_URLENCODED);
+    invoke(ContextOperation.SETMEDIATYPE);
+  }
+
+  /*
+   * @testName: setPropertyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Binds an object to a given property name in the current
+   * request/response exchange context. If the name specified is already used
+   * for a property, this method will replace the value of the property with the
+   * new value.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setPropertyTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY2);
+    invoke(ContextOperation.SETPROPERTY);
+  }
+
+  /*
+   * @testName: setPropertyNullTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:913; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: If a null value is passed, the effect is the same as
+   * calling the removeProperty(String) method.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setPropertyNullTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.NULL);
+    invoke(ContextOperation.SETPROPERTYNULL);
+  }
+
+  /*
+   * @testName: setTypeTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:914; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update Java type before calling message body provider.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setTypeTest() throws Fault {
+    addProvider(InputStreamReaderProvider.class);
+    invoke(ContextOperation.SETTYPE);
+    InputStreamReader isr = getResponseBody(InputStreamReader.class);
+    try {
+      String entity = JaxrsUtil.readFromReader(isr);
+      assertTrue(entity.contains(InputStreamReader.class.getName()),
+          "Expected"+ InputStreamReader.class.getName()+ "not found");
+      logMsg("#setType set correct type", entity);
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java
new file mode 100644
index 0000000..4ca8081
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/Resource.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.ContextOperation;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+@Path("resource")
+public class Resource {
+
+  @GET
+  @Path("{id}")
+  public Response genericResponse(@PathParam("id") String path) {
+    ContextOperation op = ContextOperation.valueOf(path.toUpperCase());
+    ResponseBuilder builder = createResponseBuilderWithHeader(op);
+    switch (op) {
+    case GETANNOTATIONS:
+      Annotation[] annotations = ContextOperation.class.getAnnotations();
+      builder = builder.entity(TemplateInterceptorBody.ENTITY, annotations);
+      break;
+    case GETMEDIATYPE:
+      builder = builder.type(MediaType.APPLICATION_JSON_TYPE);
+      break;
+    case SETTYPE:
+      ByteArrayInputStream bais = new ByteArrayInputStream(
+          TemplateInterceptorBody.ENTITY.getBytes());
+      Reader reader = new InputStreamReader(bais);
+      builder = builder.entity(reader);
+      break;
+    default:
+      break;
+    }
+    Response response = builder.build();
+    return response;
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+
+  ResponseBuilder createResponseBuilderWithHeader(ContextOperation op) {
+    Response.ResponseBuilder builder = Response.ok();
+    // set a header with ContextOperation so that the filter knows what to
+    // do
+    builder = builder.header(TemplateInterceptorBody.OPERATION, op.name());
+    builder = builder.entity(TemplateInterceptorBody.ENTITY);
+    return builder;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..780adce
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/TSAppConfig.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.interceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext.WriterInterceptorTwo;
+
+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);
+    resources.add(WriterInterceptorOne.class);
+    resources.add(WriterInterceptorTwo.class);
+    resources.add(InputStreamReaderProvider.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java
new file mode 100644
index 0000000..76f6b40
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/JAXRSClientIT.java
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.WriterClient;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends WriterClient<ContextOperation> {
+
+  private static final long serialVersionUID = -8158424518609416304L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot(
+        "/jaxrs_ee_rs_ext_interceptor_containerwriter_writerinterceptorcontext_web/resource");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_rs_ext_interceptor_containerwriter_writerinterceptorcontext_web.war");
+    archive.addClasses(TSAppConfig.class, 
+    jakarta.ws.rs.tck.common.util.JaxrsUtil.class,
+    jakarta.ws.rs.tck.common.provider.StringBean.class,
+    jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider.class,
+    jakarta.ws.rs.tck.common.impl.ReplacingOutputStream.class,
+    jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor.class,
+    Resource.class);
+    archive.addPackages(false, 
+      "jakarta.ws.rs.tck.api.rs.ext.interceptor",
+      "jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext");
+
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+  /*
+   * @testName: getEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:933; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get object to be written as HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getEntityTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.ENTITY);
+    invoke(ContextOperation.GETENTITY);
+  }
+
+  /*
+   * @testName: getHeadersOperationOnlyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   * 
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersOperationOnlyTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+    invoke(ContextOperation.GETHEADERS);
+  }
+
+  /*
+   * @testName: getHeadersTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersTest() throws Fault {
+    Property p = Property.UNORDERED_SEARCH_STRING;
+    setProperty(p, TemplateInterceptorBody.OPERATION);
+    for (int i = 0; i != 5; i++)
+      setProperty(p, TemplateInterceptorBody.PROPERTY + i);
+    invoke(ContextOperation.GETHEADERS);
+  }
+
+  /*
+   * @testName: getHeadersIsMutableTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:934; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get mutable map of HTTP headers.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getHeadersIsMutableTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.PROPERTY);
+    invoke(ContextOperation.GETHEADERSISMUTABLE);
+  }
+
+  /*
+   * @testName: getOutputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:935; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Get the output stream for the object to be written.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void getOutputStreamTest() throws Fault {
+    Property p = Property.UNORDERED_SEARCH_STRING;
+    setProperty(p, TemplateInterceptorBody.ENTITY);
+    setProperty(p, TemplateInterceptorBody.NULL);
+    invoke(ContextOperation.GETOUTPUTSTREAM);
+  }
+
+  /*
+   * @testName: proceedThrowsIOExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:937; JAXRS:JAVADOC:930;
+   * JAXRS:JAVADOC:931;
+   * 
+   * @test_Strategy: Proceed to the next interceptor in the chain.
+   * Throws:IOException - if an IO exception arises.
+   * 
+   * proceed is actually called in every clientwriter.writerinterceptorcontext
+   * test
+   *
+   * WriterInterceptor.aroundWriteTo
+   * 
+   * WriterInterceptor.aroundWriteTo throws IOException
+   */
+  @Test
+  public void proceedThrowsIOExceptionTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.IOE);
+    invoke(ContextOperation.PROCEEDTHROWSIOEXCEPTION);
+  }
+
+  /*
+   * @testName: proceedThrowsWebApplicationExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:936; JAXRS:JAVADOC:1009; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Proceed to the next interceptor in the chain.
+   * Throws:WebApplicationException thrown by the wrapped {@code
+   * MessageBodyWriter.writeTo} method.
+   * 
+   * proceed is actually called in every clientwriter.writerinterceptorcontext
+   * test
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void proceedThrowsWebApplicationExceptionTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.WAE);
+    invoke(ContextOperation.PROCEEDTHROWSWEBAPPEXCEPTION);
+  }
+
+  /*
+   * @testName: setEntityTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:938; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update object to be written as HTTP entity.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setEntityTest() throws Fault {
+    setProperty(Property.SEARCH_STRING, TemplateInterceptorBody.OPERATION);
+    invoke(ContextOperation.SETENTITY);
+  }
+
+  /*
+   * @testName: setOutputStreamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:939; JAXRS:JAVADOC:930;
+   * 
+   * @test_Strategy: Update the output stream for the object to be written.
+   *
+   * WriterInterceptor.aroundWriteTo
+   */
+  @Test
+  public void setOutputStreamTest() throws Fault {
+    setProperty(Property.SEARCH_STRING,
+        TemplateInterceptorBody.ENTITY.replace('t', 'x'));
+    invoke(ContextOperation.SETOUTPUTSTREAM);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java
new file mode 100644
index 0000000..a4ad607
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/Resource.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ContextOperation;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.OnWriteExceptionThrowingStringBean;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.ResponseBuilder;
+
+@Path("resource")
+public class Resource {
+
+  @GET
+  @Path("{id}")
+  public Response genericResponse(@PathParam("id") String path) {
+    ContextOperation op = ContextOperation.valueOf(path.toUpperCase());
+    ResponseBuilder builder = createResponseBuilderWithHeader(op);
+    switch (op) {
+    case GETHEADERS:
+      for (int i = 0; i != 5; i++)
+        builder = builder.header(TemplateInterceptorBody.PROPERTY + i, "any");
+      break;
+    case PROCEEDTHROWSWEBAPPEXCEPTION:
+      builder.entity(new OnWriteExceptionThrowingStringBean(
+          TemplateInterceptorBody.ENTITY));
+      break;
+    default:
+      break;
+    }
+    Response response = builder.build();
+    return response;
+  }
+
+  // ///////////////////////////////////////////////////////////////////////
+
+  static ResponseBuilder createResponseBuilderWithHeader(ContextOperation op) {
+    Response.ResponseBuilder builder = Response.ok();
+    // set a header with ContextOperation so that the filter knows what to
+    // do
+    builder = builder.header(TemplateInterceptorBody.OPERATION, op.name());
+    builder = builder.entity(TemplateInterceptorBody.ENTITY);
+    return builder;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java
new file mode 100644
index 0000000..88a442e
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/TSAppConfig.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.containerwriter.writerinterceptorcontext;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InputStreamReaderProvider;
+import jakarta.ws.rs.tck.common.provider.StringBeanEntityProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.ProceedExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext.WriterInterceptorTwo;
+
+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);
+    resources.add(WriterInterceptorOne.class);
+    resources.add(WriterInterceptorTwo.class);
+    resources.add(InputStreamReaderProvider.class);
+    resources.add(StringBeanEntityProvider.class);
+    resources.add(ProceedExceptionMapper.class);
+    return resources;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java
new file mode 100644
index 0000000..86c3e87
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/TemplateWriterInterceptor.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorCallbackMethods;
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptor;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+/**
+ * This class is a superclass for any interceptor @Provider. Any such provider
+ * is then given a body, inherited from TemplateInterceptorBody. The body
+ * actually contains methods with name equalIgnoreCase to ContextOperation items
+ * name, the name of the method executed is passed by http header OPERATION
+ * 
+ * @see TemplateInterceptorBody
+ * 
+ *      The injection of the body solves the issue with inheritance from two
+ *      super-classes.
+ */
+public abstract class TemplateWriterInterceptor
+    implements WriterInterceptor, InterceptorCallbackMethods {
+
+  protected WriterInterceptorContext writerCtx;
+
+  protected TemplateInterceptorBody<WriterInterceptorContext> interceptorBody;
+
+  public TemplateWriterInterceptor(
+      TemplateInterceptorBody<WriterInterceptorContext> interceptorBody) {
+    super();
+    this.interceptorBody = interceptorBody;
+  }
+
+  @Override
+  public void aroundWriteTo(WriterInterceptorContext ctx) throws IOException {
+    this.writerCtx = ctx;
+    interceptorBody.executeMethod(writerCtx, this);
+  }
+
+  @Override
+  public void writeEntity(String entity) {
+    Type type = writerCtx.getGenericType();
+    if (type instanceof Class) {
+      Class<?> clazz = ((Class<?>) type);
+      if (clazz == InputStreamReader.class) {
+        ByteArrayInputStream bis = new ByteArrayInputStream(entity.getBytes());
+        InputStreamReader reader = new InputStreamReader(bis);
+        writerCtx.setEntity(reader);
+      } else {
+        writerCtx.setEntity(entity);
+      }
+    }
+  }
+
+  @Override
+  public Object proceed() throws IOException {
+    writerCtx.proceed();
+    return null;
+  }
+
+  @Override
+  public String getHeaderString() {
+    MultivaluedMap<String, Object> headers = writerCtx.getHeaders();
+    return (String) headers.getFirst(TemplateInterceptorBody.OPERATION);
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java
new file mode 100644
index 0000000..73ab437
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorOne.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyOne;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+@Provider
+@Priority(100)
+public class WriterInterceptorOne extends TemplateWriterInterceptor {
+
+  public WriterInterceptorOne() {
+    super(new InterceptorBodyOne<WriterInterceptorContext>());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java
new file mode 100644
index 0000000..79145f6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/interceptorcontext/WriterInterceptorTwo.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.interceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.InterceptorBodyTwo;
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+@Provider
+@Priority(200)
+public class WriterInterceptorTwo extends TemplateWriterInterceptor {
+
+  public WriterInterceptorTwo() {
+    super(new InterceptorBodyTwo<WriterInterceptorContext>());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java
new file mode 100644
index 0000000..5482efa
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ContextOperation.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.interceptor.writer.writerinterceptorcontext;
+
+public enum ContextOperation {
+  GETENTITY, GETHEADERS, GETHEADERSISMUTABLE, GETOUTPUTSTREAM, FROMPROCEEDTHROWSWEBAPPEXCEPTION, // On
+                                                                                                 // return
+                                                                                                 // with
+                                                                                                 // WebAppException
+                                                                                                 // The
+                                                                                                 // Exception
+                                                                                                 // is
+                                                                                                 // not
+                                                                                                 // thrown
+                                                                                                 // again
+  PROCEEDTHROWSIOEXCEPTION, PROCEEDTHROWSWEBAPPEXCEPTION, SETENTITY, SETOUTPUTSTREAM
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java
new file mode 100644
index 0000000..aa68c01
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyOne.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.impl.ReplacingOutputStream;
+import jakarta.ws.rs.tck.common.util.JaxrsUtil;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+public class InterceptorBodyOne
+    extends TemplateInterceptorBody<WriterInterceptorContext> {
+
+  public void getEntity() {
+    Object entity = context.getEntity();
+    setEntity(entity);
+  }
+
+  public void getHeaders() {
+    MultivaluedMap<String, Object> headers = context.getHeaders();
+    String keys = JaxrsUtil.iterableToString(";", headers.keySet());
+    setEntity(keys);
+  }
+
+  public void getHeadersIsMutable() {
+    MultivaluedMap<String, Object> headers = context.getHeaders();
+    Object o = headers.getFirst(PROPERTY);
+    assertTrue(o == null, PROPERTY, "header allready exist");
+    headers.add(PROPERTY, PROPERTY);
+  }
+
+  public void getOutputStream() throws IOException {
+    setEntityToOutputStream(NULL);
+  }
+
+  public void proceedThrowsIOException() {
+    try {
+      context.proceed(); // Should throw IOException which is wrapped in
+      setEntity(NULL); // TemplateWriterInterceptor to RuntimeExecption
+    } catch (IOException ioe) {
+      setEntity(IOE); // let the client know
+    } catch (Throwable t) {
+      throw new RuntimeException(t);
+    }
+  }
+
+  public String proceedThrowsWebAppException() throws IOException {
+    try {
+      context.proceed(); // Should throw WebApplicationException in
+      throw new ProceedException(NULL); // TemplateWriterInterceptor
+    } catch (WebApplicationException e) {
+      throw new ProceedException(WAE);
+    } catch (IOException e) {
+      throw new ProceedException(NULL); // TemplateWriterInterceptor to
+      // RuntimeExecption
+    }
+  }
+
+  public void fromProceedThrowsWebAppException() throws IOException {
+    // intentionally blank, no need to do enything
+    // this is called on an interceptor on a response given by
+    // ProceedException.getResponse()
+  }
+
+  public void setEntity() {
+    context.setEntity(OPERATION);
+  }
+
+  public void setOutputStream() throws IOException {
+    OutputStream originalStream = context.getOutputStream();
+    OutputStream replace = new ReplacingOutputStream(originalStream, 't', 'x');
+    context.setOutputStream(replace);
+  }
+
+  private void setEntityToOutputStream(String entity) throws IOException {
+    OutputStream stream = context.getOutputStream();
+    stream.write(entity.getBytes());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java
new file mode 100644
index 0000000..79b505a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/InterceptorBodyTwo.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.ext.WriterInterceptorContext;
+
+public class InterceptorBodyTwo
+    extends TemplateInterceptorBody<WriterInterceptorContext> {
+  @Override
+  protected Object operationMethodNotFound(String operation)
+      throws IOException {
+    return proceed();
+  }
+
+  public void getHeadersIsMutable() {
+    MultivaluedMap<String, Object> headers = context.getHeaders();
+    Object o = headers.getFirst(PROPERTY);
+    assertTrue(o != null, PROPERTY, "header NOT found");
+    setEntity(o);
+  }
+
+  public void proceedThrowsIOException() throws IOException {
+    throw new IOException("Interceptor test IoException");
+  }
+
+  public void proceedThrowsWebAppException() throws IOException {
+    context.proceed();
+  }
+
+  public void setEntity() {
+    Object entity = context.getEntity();
+    setEntity(entity);
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java
new file mode 100644
index 0000000..0951377
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/OnWriteExceptionThrowingStringBean.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.WebApplicationException;
+
+public class OnWriteExceptionThrowingStringBean extends StringBean {
+
+  public OnWriteExceptionThrowingStringBean(String header) {
+    super(header);
+  }
+
+  @Override
+  public String get() {
+    String header = super.get();
+    if (header.equals(TemplateInterceptorBody.WAE))
+      return header;
+    else
+      throw new WebApplicationException(new IOException(header));
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java
new file mode 100644
index 0000000..67c45cd
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedException.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.api.rs.ext.interceptor.TemplateInterceptorBody;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.Response;
+
+public class ProceedException extends WebApplicationException {
+
+  private static final long serialVersionUID = -8012949565468746147L;
+
+  private String msg;
+
+  public ProceedException(String msg) {
+    super(
+        Response.ok(msg)
+            .header(TemplateInterceptorBody.OPERATION,
+                ContextOperation.FROMPROCEEDTHROWSWEBAPPEXCEPTION.name())
+            .build());
+    this.msg = msg;
+  }
+
+  /**
+   * Acyclic getCause() returns equivalent of this
+   */
+  @Override
+  public Throwable getCause() {
+    return new ProceedException(msg) {
+      private static final long serialVersionUID = 256996856963444570L;
+
+      @Override
+      public Throwable getCause() {
+        return null;
+      }
+    };
+  }
+
+  @Override
+  public String getMessage() {
+    return msg;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java
new file mode 100644
index 0000000..44568c6
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/ProceedExceptionMapper.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.ExceptionMapper;
+
+public class ProceedExceptionMapper
+    implements ExceptionMapper<ProceedException> {
+
+  @Override
+  public Response toResponse(ProceedException exception) {
+    return exception.getResponse();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java
new file mode 100644
index 0000000..92dc4de
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorOne.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(100)
+public class WriterInterceptorOne extends TemplateWriterInterceptor {
+
+  public WriterInterceptorOne() {
+    super(new InterceptorBodyOne());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java
new file mode 100644
index 0000000..0bae703
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/interceptor/writer/writerinterceptorcontext/WriterInterceptorTwo.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.writerinterceptorcontext;
+
+import jakarta.ws.rs.tck.ee.rs.ext.interceptor.writer.TemplateWriterInterceptor;
+
+import jakarta.annotation.Priority;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+@Priority(200)
+public class WriterInterceptorTwo extends TemplateWriterInterceptor {
+
+  public WriterInterceptorTwo() {
+    super(new InterceptorBodyTwo());
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java
new file mode 100644
index 0000000..9f5e01f
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityAnnotation.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2012, 2018 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.ext.messagebodyreaderwriter;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface EntityAnnotation {
+  String value();
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java
new file mode 100644
index 0000000..d7669e7
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageReader.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.AbstractMessageBodyRW;
+
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.Provider;
+
+/**
+ * This class is used by
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
+ */
+@Provider
+public class EntityMessageReader extends AbstractMessageBodyRW
+    implements MessageBodyReader<ReadableWritableEntity> {
+
+  @Override
+  public boolean isReadable(Class<?> type, Type genericType,
+      Annotation[] annotations, MediaType mediaType) {
+    String path = getSpecifiedAnnotationValue(annotations,
+        EntityAnnotation.class);
+    if (path == null)
+      return false;
+    path = path.toLowerCase();
+    boolean readable = path.contains("body");
+    readable |= path.contains("head");
+    readable |= path.contains("ioexception");
+    readable |= path.contains("webexception");
+    readable &= MediaType.TEXT_XML_TYPE.isCompatible(mediaType);
+    readable &= ReadableWritableEntity.class.isAssignableFrom(type);
+    return readable;
+  }
+
+  @Override
+  public ReadableWritableEntity readFrom(Class<ReadableWritableEntity> type,
+      Type genericType, Annotation[] annotations, MediaType mediaType,
+      MultivaluedMap<String, String> httpHeaders, InputStream entityStream)
+      throws IOException, WebApplicationException {
+    String ea = getSpecifiedAnnotationValue(annotations, EntityAnnotation.class)
+        .toLowerCase();
+    String entity = "null";
+    if (ea.contains("body"))
+      entity = readInputStream(entityStream);
+    else if (ea.contains("head"))
+      entity = httpHeaders.getFirst(ReadableWritableEntity.NAME);
+    else if (ea.contains("ioexception"))
+      throw new IOException("CTS test IOException");
+    else if (ea.contains("webexception")) {
+      entity = httpHeaders.getFirst(ReadableWritableEntity.NAME);
+      throw new WebApplicationException(Status.valueOf(entity));
+    }
+    return ReadableWritableEntity.fromString(entity);
+  }
+
+  String readInputStream(InputStream is) throws IOException {
+    InputStreamReader isr = new InputStreamReader(is);
+    BufferedReader br = new BufferedReader(isr);
+    return br.readLine();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
index cac6e91..052313f 100644
--- a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/EntityMessageWriter.java
@@ -31,7 +31,7 @@
 
 /**
  * This class is used by
- * com.sun.ts.tests.jaxrs.ee.rs.ext.providers.ProvidersServlet
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
  */
 @Provider
 public class EntityMessageWriter extends AbstractMessageBodyRW
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
index 5143385..cea33cb 100644
--- a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/messagebodyreaderwriter/ReadableWritableEntity.java
@@ -18,7 +18,7 @@
 
 /**
  * This class is used by
- * com.sun.ts.tests.jaxrs.ee.rs.ext.providers.ProvidersServlet
+ * jakarta.ws.rs.tck.ee.rs.ext.providers.ProvidersServlet
  */
 public class ReadableWritableEntity {
   private String entity;
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java
new file mode 100644
index 0000000..80202f3
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverter.Lazy;
+
+@Lazy
+public class AtomicIntegerLazyParamConverter
+    implements ParamConverter<AtomicInteger> {
+
+  @Override
+  public AtomicInteger fromString(String value)
+      throws IllegalArgumentException {
+    return new AtomicInteger(Integer.parseInt(value));
+  }
+
+  @Override
+  public String toString(AtomicInteger value) throws IllegalArgumentException {
+    return String.valueOf(value.get());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java
new file mode 100644
index 0000000..195fa93
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/AtomicIntegerLazyParamConverterProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class AtomicIntegerLazyParamConverterProvider
+    implements ParamConverterProvider {
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+      Annotation[] annotations) {
+    if (rawType == AtomicInteger.class)
+      return (ParamConverter<T>) new AtomicIntegerLazyParamConverter();
+    return null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java
new file mode 100644
index 0000000..1ad24ff
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverter.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.tck.common.impl.StringDataSource;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.ext.ParamConverter;
+
+public class DataSourceParamConverter implements ParamConverter<DataSource> {
+
+  @Override
+  public DataSource fromString(String value) throws IllegalArgumentException {
+    StringDataSource sds = new StringDataSource(value,
+        MediaType.TEXT_PLAIN_TYPE);
+    return sds;
+  }
+
+  @Override
+  public String toString(DataSource value) throws IllegalArgumentException {
+    return value.getName();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java
new file mode 100644
index 0000000..33b5b6a
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/DataSourceParamConverterProvider.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class DataSourceParamConverterProvider
+    implements ParamConverterProvider {
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+      Annotation[] annotations) {
+    if (DataSource.class.isAssignableFrom(rawType))
+      return (ParamConverter<T>) new DataSourceParamConverter();
+    return null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java
new file mode 100644
index 0000000..f75f5d1
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/JAXRSClientIT.java
@@ -0,0 +1,548 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.common.client.JaxrsCommonClient;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response.Status;
+
+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.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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSClientIT extends JaxrsCommonClient {
+
+  private static final long serialVersionUID = 863071027768369551L;
+
+  public JAXRSClientIT() {
+    setup();
+    setContextRoot("/jaxrs_ee_ext_paramconverter_web");
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_ext_paramconverter_web.war");
+    archive.addClasses(Resource.class, Locator.class, DataSourceParamConverter.class, DataSourceParamConverterProvider.class,
+      StringBeanParamConverter.class, StringBeanParamConverterProvider.class, AtomicIntegerLazyParamConverter.class, AtomicIntegerLazyParamConverterProvider.class, 
+      jakarta.ws.rs.tck.common.provider.PrintingErrorHandler.class,
+      jakarta.ws.rs.tck.common.provider.StringBean.class, 
+      jakarta.ws.rs.tck.common.impl.StringDataSource.class, 
+      TSAppConfig.class);
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+
+  /* Run test */
+
+  /*
+   * @testName: isParamCoverterInApplicationSingletonsUsedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:919;
+   * 
+   * @test_Strategy: Providers implementing ParamConverterProvider contract must
+   * be either programmatically registered in a JAX-RS runtime
+   */
+  @Test
+  public void isParamCoverterInApplicationSingletonsUsedTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequest(Request.GET, "dsquery?param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: isParamCoverterInApplicationClassesUsedTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:919;
+   * 
+   * @test_Strategy: Providers implementing ParamConverterProvider contract must
+   * be either programmatically registered in a JAX-RS runtime
+   */
+  @Test
+  public void isParamCoverterInApplicationClassesUsedTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequest(Request.GET, "sbquery?param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: atomicIntegerPassesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:919;
+   * 
+   * @test_Strategy: Providers implementing ParamConverterProvider contract must
+   * be either programmatically registered in a JAX-RS runtime
+   */
+  @Test
+  public void atomicIntegerPassesTest() throws Fault {
+    String query = "10";
+    setPropertyRequest(Request.GET, "aiquery?param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: atomicIntegerIsLazyDeployableAndThrowsErrorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:919;
+   * 
+   * @test_Strategy: Providers implementing ParamConverterProvider contract must
+   * be either programmatically registered in a JAX-RS runtime
+   */
+  @Test
+  public void atomicIntegerIsLazyDeployableAndThrowsErrorTest() throws Fault {
+    setPropertyRequest(Request.GET, "aiquery");
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.NOT_ACCEPTABLE));
+    invoke();
+  }
+
+  /*
+   * @testName: pathParamUsesParamConvertorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void pathParamUsesParamConvertorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequest(Request.GET, "sbpath/", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: matrixParamUsesParamConvertorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void matrixParamUsesParamConvertorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequest(Request.GET, "sbmatrix;param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: formParamUsesParamConvertorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void formParamUsesParamConvertorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setProperty(Property.REQUEST_HEADERS,
+        buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+    setPropertyRequest(Request.POST, "sbform/");
+    setProperty(Property.CONTENT, "param=" + query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: cookieParamUsesParamConvertorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void cookieParamUsesParamConvertorTest() throws Fault {
+    String query = "ABCDEFGH";
+    buildCookie(query);
+    setPropertyRequest(Request.GET, "sbcookie");
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: headerParamUsesParamConvertorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void headerParamUsesParamConvertorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setProperty(Property.REQUEST_HEADERS, "param:" + query);
+    setPropertyRequest(Request.GET, "sbheader");
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInQueryParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInQueryParamTest() throws Fault {
+    setPropertyRequest(Request.GET, "sbquery");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInMatrixParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInMatrixParamTest() throws Fault {
+    setPropertyRequest(Request.GET, "sbmatrix;");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInPathParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInPathParamTest() throws Fault {
+    setPropertyRequest(Request.GET, "sbpath/default");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInFormParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInFormParamTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+    setPropertyRequest(Request.POST, "sbform/");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInCookieParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInCookieParamTest() throws Fault {
+    setPropertyRequest(Request.GET, "sbcookie");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueInHeaderParamTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value in the resource or provider
+   * model, that is during the application deployment, before any value default
+   * or otherwise is actually required
+   */
+  @Test
+  public void defaultValueInHeaderParamTest() throws Fault {
+    setPropertyRequest(Request.GET, "sbheader");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: queryParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void queryParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequestInLocator(Request.GET, "sbquery/sbquery?param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueQueryParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValueQueryParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequestInLocator(Request.GET, "sbquery/sbquery?", query);
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: pathParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void pathParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequestInLocator(Request.GET, "sbpath/sbpath/", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValuePathParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValuePathParamInLocatorTest() throws Fault {
+    setPropertyRequestInLocator(Request.GET, "sbpath/sbpath/default");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: matrixParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void matrixParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setPropertyRequestInLocator(Request.GET, "sbmatrix/sbmatrix;param=", query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueMatrixParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValueMatrixParamInLocatorTest() throws Fault {
+    setPropertyRequestInLocator(Request.GET, "sbmatrix/sbmatrix");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: formParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void formParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setProperty(Property.REQUEST_HEADERS,
+        buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+    setPropertyRequestInLocator(Request.POST, "sbform/sbform");
+    setProperty(Property.CONTENT, "param=" + query);
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueFormParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValueFormParamInLocatorTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        buildContentType(MediaType.APPLICATION_FORM_URLENCODED_TYPE));
+    setPropertyRequestInLocator(Request.POST, "sbform/sbform");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: cookieParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void cookieParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    buildCookie(query);
+    setPropertyRequestInLocator(Request.GET, "sbcookie/sbcookie");
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueCookieParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValueCookieParamInLocatorTest() throws Fault {
+    setPropertyRequestInLocator(Request.GET, "sbcookie/sbcookie");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  /*
+   * @testName: headerParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: Parse the supplied value and create an instance of
+   */
+  @Test
+  public void headerParamInLocatorTest() throws Fault {
+    String query = "ABCDEFGH";
+    setProperty(Property.REQUEST_HEADERS, "param:" + query);
+    setPropertyRequestInLocator(Request.GET, "sbheader/sbheader");
+    setProperty(Property.SEARCH_STRING, query);
+    invoke();
+  }
+
+  /*
+   * @testName: defaultValueHeaderParamInLocatorTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:915;
+   * 
+   * @test_Strategy: selected ParamConverter instance MUST be used eagerly by a
+   * JAX-RS runtime to convert any default value
+   */
+  @Test
+  public void defaultValueHeaderParamInLocatorTest() throws Fault {
+    setPropertyRequestInLocator(Request.GET, "sbheader/sbheader");
+    setProperty(Property.SEARCH_STRING, Resource.DEFAULT);
+    invoke();
+  }
+
+  // ////////////////////////////////////////////////////////////////////
+  private//
+  void setPropertyRequestInResource(Request request, String... resource) {
+    StringBuilder sb = new StringBuilder("resource/");
+    for (String r : resource)
+      sb.append(r);
+    setProperty(Property.REQUEST, buildRequest(request, sb.toString()));
+  }
+
+  private void setPropertyRequest(Request request, String... resource) {
+    setPropertyRequestInResource(request, resource);
+  }
+
+  private//
+  void setPropertyRequestInLocator(Request request, String... resource) {
+    StringBuilder sb = new StringBuilder("locator/");
+    for (String r : resource)
+      sb.append(r);
+    setProperty(Property.REQUEST, buildRequest(request, sb.toString()));
+  }
+
+  private void buildCookie(String cookieValue) {
+    StringBuilder sb = new StringBuilder();
+    sb.append("Cookie: param=").append(cookieValue);
+    setProperty(Property.REQUEST_HEADERS, sb.toString());
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java
new file mode 100644
index 0000000..6f32344
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Locator.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("locator")
+public class Locator {
+
+  @Path("sbquery")
+  public Resource stringBeanQuery() {
+    return new Resource();
+  }
+
+  @Path("sbpath")
+  public Resource stringBeanPath() {
+    return new Resource();
+  }
+
+  @Path("sbmatrix")
+  public Resource stringBeanMatrix() {
+    return new Resource();
+  }
+
+  @Path("sbform")
+  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+  public Resource stringBeanForm() {
+    return new Resource();
+  }
+
+  @Path("sbcookie")
+  public Resource stringBeanCookie() {
+    return new Resource();
+  }
+
+  @Path("sbheader")
+  public Resource stringBeanHeader() {
+    return new Resource();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java
new file mode 100644
index 0000000..6f2b061
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/Resource.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.activation.DataSource;
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.CookieParam;
+import jakarta.ws.rs.DefaultValue;
+import jakarta.ws.rs.FormParam;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.MatrixParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.PathParam;
+import jakarta.ws.rs.QueryParam;
+import jakarta.ws.rs.core.MediaType;
+
+@Path("resource")
+public class Resource {
+  public static final String NULL = "NULL";
+
+  public static final String DEFAULT = "DEFAULT";
+
+  @Path("sbquery")
+  @GET
+  public String stringBeanQuery(
+      @DefaultValue(DEFAULT) @QueryParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("dsquery")
+  @GET
+  public String dataSourceQuery(@QueryParam("param") DataSource param) {
+    return param.getName();
+  }
+
+  @Path("aiquery")
+  @GET
+  public String atomicIntegerQuery(
+      @DefaultValue(DEFAULT) @QueryParam("param") AtomicInteger param) {
+    return String.valueOf(param.get());
+  }
+
+  @Path("sbpath/{param}")
+  @GET
+  public String stringBeanPath(@PathParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("sbpath/default")
+  @GET
+  public String stringBeanPathNeverHere(
+      @DefaultValue(DEFAULT) @PathParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("sbmatrix")
+  @GET
+  public String stringBeanMatrix(
+      @DefaultValue(DEFAULT) @MatrixParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("sbform")
+  @POST
+  @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+  public String stringBeanForm(
+      @DefaultValue(DEFAULT) @FormParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("sbcookie")
+  @GET
+  public String stringBeanCookie(
+      @DefaultValue(DEFAULT) @CookieParam("param") StringBean param) {
+    return param.get();
+  }
+
+  @Path("sbheader")
+  @GET
+  public String stringBeanHeader(
+      @DefaultValue(DEFAULT) @HeaderParam("param") StringBean param) {
+    return param.get();
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java
new file mode 100644
index 0000000..1a03c70
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.ext.ParamConverter;
+
+public class StringBeanParamConverter implements ParamConverter<StringBean> {
+
+  @Override
+  public StringBean fromString(String value) throws IllegalArgumentException {
+    return new StringBean(value);
+  }
+
+  @Override
+  public String toString(StringBean value) throws IllegalArgumentException {
+    return value.get();
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java
new file mode 100644
index 0000000..02d46e9
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/StringBeanParamConverterProvider.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import jakarta.ws.rs.tck.common.provider.StringBean;
+
+import jakarta.ws.rs.ext.ParamConverter;
+import jakarta.ws.rs.ext.ParamConverterProvider;
+import jakarta.ws.rs.ext.Provider;
+
+@Provider
+public class StringBeanParamConverterProvider
+    implements ParamConverterProvider {
+
+  @SuppressWarnings("unchecked")
+  @Override
+  public <T> ParamConverter<T> getConverter(Class<T> rawType, Type genericType,
+      Annotation[] annotations) {
+    if (rawType == StringBean.class)
+      return (ParamConverter<T>) new StringBeanParamConverter();
+    return null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java
new file mode 100644
index 0000000..dfe52e2
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/TSAppConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.paramconverter;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.common.provider.PrintingErrorHandler;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+  @Override
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(Resource.class);
+    resources.add(Locator.class);
+    resources.add(StringBeanParamConverterProvider.class);
+    resources.add(AtomicIntegerLazyParamConverterProvider.class);
+    resources.add(PrintingErrorHandler.class);
+    return resources;
+  }
+
+  @Override
+  public Set<Object> getSingletons() {
+    Set<Object> set = new HashSet<Object>();
+    set.add(new DataSourceParamConverterProvider());
+    return set;
+  }
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java
new file mode 100644
index 0000000..d369738
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/JAXRSProvidersClientIT.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+import java.io.InputStream;
+import java.io.IOException;
+import jakarta.ws.rs.tck.lib.util.TestUtil;
+import jakarta.ws.rs.tck.common.JAXRSCommonClient;
+
+import jakarta.ws.rs.tck.common.webclient.http.HttpResponse;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response.Status;
+
+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;
+
+/*
+ * @class.setup_props: webServerHost;
+ *                     webServerPort;
+ */
+@ExtendWith(ArquillianExtension.class)
+public class JAXRSProvidersClientIT
+    //extends jakarta.ws.rs.tck.ee.rs.core.application.JAXRSClientIT {
+    extends JAXRSCommonClient {
+
+  private static final long serialVersionUID = -935293219512493643L;
+
+  protected int expectedSingletons = 1;
+
+  protected int expectedClasses = 1;
+
+  public JAXRSProvidersClientIT() {
+    setup();
+    TSAppConfig cfg = new TSAppConfig();
+    setContextRoot("/jaxrs_ee_ext_providers_web/ProvidersServlet");
+    expectedClasses = cfg.getClasses().size();
+    expectedSingletons = cfg.getSingletons().size();
+  }
+
+  @BeforeEach
+  void logStartTest(TestInfo testInfo) {
+    TestUtil.logMsg("STARTING TEST : "+testInfo.getDisplayName());
+  }
+
+  @AfterEach
+  void logFinishTest(TestInfo testInfo) {
+    TestUtil.logMsg("FINISHED TEST : "+testInfo.getDisplayName());
+  }
+
+  @Deployment(testable = false)
+  public static WebArchive createDeployment() throws IOException{
+
+    InputStream inStream = JAXRSProvidersClientIT.class.getClassLoader().getResourceAsStream("jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template");
+    String webXml = editWebXmlString(inStream);
+
+    WebArchive archive = ShrinkWrap.create(WebArchive.class, "jaxrs_ee_ext_providers_web.war");
+    archive.addClasses(TSAppConfig.class, ProvidersServlet.class, 
+      jakarta.ws.rs.tck.common.AbstractMessageBodyRW.class, 
+      jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet.class,
+      jakarta.ws.rs.tck.ee.rs.core.application.ApplicationHolderSingleton.class,
+      jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider.class,
+      jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumContextResolver.class,
+      jakarta.ws.rs.tck.ee.rs.ext.contextresolver.TextPlainEnumContextResolver.class,
+      jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper.class,
+      jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.IOExceptionExceptionMapper.class,
+      jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityAnnotation.class,
+      jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageReader.class,
+      jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageWriter.class,
+      jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity.class
+    );
+    archive.setWebXML(new StringAsset(webXml));
+    return archive;
+
+  }
+
+  /* Run test */
+
+  /*
+   * @testName: getSingletonsTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:23
+   * 
+   * @test_Strategy: Check that the implementation returns set of
+   * TSAppConfig.CLASSLIST
+   */
+  @Test
+  public void getSingletonsTest() throws Fault {
+    //super.getSingletonsTest();
+    setProperty(REQUEST, buildRequest(GET, "GetSingletons"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+    assertTrue(getReturnedNumber() == expectedSingletons,
+        "Application.getSingletons() return incorrect value:"+
+        getReturnedNumber());
+  }
+
+  /*
+   * @testName: getClassesTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:22
+   * 
+   * @test_Strategy: Check the implementation injects TSAppConfig
+   */
+  @Test
+  public void getClassesTest() throws Fault {
+    //super.getClassesTest();
+    setProperty(REQUEST, buildRequest(GET, "GetClasses"));
+    setProperty(STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+    assertTrue(getReturnedNumber() == expectedClasses,
+        "Application.getClasses() return incorrect value:"+
+        getReturnedNumber());
+  }
+
+  /*
+   * @testName: isRegisteredTextPlainContextResolverTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:269; JAXRS:JAVADOC:280; JAXRS:JAVADOC:299;
+   * JAXRS:SPEC:40; JAXRS:SPEC:80; JAXRS:SPEC:81;
+   * 
+   * @test_Strategy: Register ContextResolver and try to get proper Provider
+   * 
+   * When injecting an instance of one of the types listed in section 9.2, the
+   * instance supplied MUST be capable of selecting the correct context for a
+   * particular request.
+   * 
+   * Context providers MAY return null from the getContext method if they do not
+   * wish to provide their context for a particular Java type.
+   * 
+   * Context provider implementations MAY restrict the media types they support
+   * using the @Produces annotation.
+   */
+  @Test
+  public void isRegisteredTextPlainContextResolverTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredTextPlainContextResolver"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredAppJsonContextResolverTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:269; JAXRS:JAVADOC:280; JAXRS:JAVADOC:299;
+   * JAXRS:SPEC:40; JAXRS:SPEC:80; JAXRS:SPEC:81;
+   * 
+   * @test_Strategy: Register ContextResolver and try to get proper Provider
+   * 
+   * When injecting an instance of one of the types listed in section 9.2, the
+   * instance supplied MUST be capable of selecting the correct context for a
+   * particular request.
+   * 
+   * Context providers MAY return null from the getContext method if they do not
+   * wish to provide their context for a particular Java type.
+   * 
+   * Context provider implementations MAY restrict the media types they support
+   * using the @Produces annotation. Absence implies that any media type is
+   * supported.
+   */
+  @Test
+  public void isRegisteredAppJsonContextResolverTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredAppJsonContextResolver"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredExceptionMapperRuntimeExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:270; JAXRS:JAVADOC:281; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Try to get proper ExceptionMapper
+   */
+  @Test
+  public void isRegisteredExceptionMapperRuntimeExceptionTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredExceptionMapperRuntimeEx"));
+    setProperty(Property.STATUS_CODE,
+        getStatusCode(Status.INTERNAL_SERVER_ERROR));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredExceptionMapperNullExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:281;
+   * 
+   * @test_Strategy: Try to get proper ExceptionMapper
+   */
+  @Test
+  public void isRegisteredExceptionMapperNullExceptionTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredExceptionMapperNullEx"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.NO_CONTENT));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredRuntimeExceptionExceptionMapperTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:281; JAXRS:JAVADOC:300; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Try to get RuntimeExceptionExceptionMapper but there is
+   * none
+   */
+  @Test
+  public void isRegisteredRuntimeExceptionExceptionMapperTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredRuntimeExceptionMapper"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredIOExceptionExceptionMapperTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:281;
+   * 
+   * @test_Strategy: Try to get IOExceptionExceptionMapper
+   */
+  @Test
+  public void isRegisteredIOExceptionExceptionMapperTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredIOExceptionMapper"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredMessageBodyWriterWildcardTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+   * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check what is returned for wildcard is for text/plain
+   */
+  @Test
+  public void isRegisteredMessageBodyWriterWildcardTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredWriterWildcard"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredMessageBodyWriterXmlTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+   * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check BodyWriter is returned for text/xml
+   */
+  @Test
+  public void isRegisteredMessageBodyWriterXmlTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredMessageWriterXml"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredMessageBodyReaderWildcardTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:282;
+   * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check what is returned for wildcard is for text/plain
+   */
+  @Test
+  public void isRegisteredMessageBodyReaderWildcardTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredMessageReaderWildCard"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: isRegisteredMessageBodReaderXmlTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:282;
+   * JAXRS:JAVADOC:299; JAXRS:SPEC:40;
+   * 
+   * @test_Strategy: Check BodyReader is returned for text/xml
+   */
+  @Test
+  public void isRegisteredMessageBodReaderXmlTest() throws Fault {
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "isRegisteredMessageReaderXml"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: writeBodyEntityUsingWriterTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:283;
+   * JAXRS:JAVADOC:132; JAXRS:JAVADOC:275; JAXRS:JAVADOC:276; JAXRS:JAVADOC:304;
+   * 
+   * @test_Strategy: Check BodyWriter is used for text/xml to write entity
+   */
+  @Test
+  public void writeBodyEntityUsingWriterTest() throws Fault {
+    String ename = EnumProvider.JAXRS.name();
+    String search = new ReadableWritableEntity(ename).toXmlString();
+    setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "writeBodyEntityUsingWriter"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    setProperty(Property.SEARCH_STRING, search);
+    invoke();
+  }
+
+  /*
+   * @testName: writeHeaderEntityUsingWriterTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:87; JAXRS:JAVADOC:276; JAXRS:JAVADOC:132;
+   * JAXRS:JAVADOC:275; JAXRS:JAVADOC:277; JAXRS:JAVADOC:304;
+   * 
+   * @test_Strategy: Check HeaderWriter is used for text/xml to write entity
+   */
+  @Test
+  public void writeHeaderEntityUsingWriterTest() throws Fault {
+    String ename = EnumProvider.JAXRS.name();
+    String search = new ReadableWritableEntity(ename).toXmlString();
+    setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "writeHeaderEntityUsingWriter"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    setProperty(Property.EXPECTED_HEADERS,
+        ReadableWritableEntity.NAME + ":" + search);
+    invoke();
+  }
+
+  /*
+   * @testName: writeIOExceptionUsingWriterTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:281; JAXRS:JAVADOC:304; JAXRS:JAVADOC:87;
+   * JAXRS:JAVADOC:132; JAXRS:JAVADOC:277; JAXRS:JAVADOC:278;
+   * 
+   * @test_Strategy: Check EntityWriter is used and IOException is written using
+   * mapper
+   */
+  @Test
+  public void writeIOExceptionUsingWriterTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "writeIOExceptionUsingWriter"));
+    // Depending whether the response has been committed
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+    setProperty(Property.STATUS_CODE,
+        getStatusCode(Status.INTERNAL_SERVER_ERROR));
+    invoke();
+  }
+
+  /*
+   * @testName: writeIOExceptionWithoutWriterTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:304; JAXRS:JAVADOC:281; JAXRS:SPEC:16.2;
+   * 
+   * @test_Strategy: Check IOExceptionExceptionMapper is chosen
+   */
+  @Test
+  public void writeIOExceptionWithoutWriterTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS, "Accept: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest(GET, "writeIOExceptionWithoutWriter"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+    invoke();
+  }
+
+  /*
+   * @testName: readEntityFromHeaderTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:JAVADOC:138;
+   * JAXRS:JAVADOC:304; JAXRS:JAVADOC:282;
+   * 
+   * @test_Strategy: Put entity to header and read it using reader
+   */
+  @Test
+  public void readEntityFromHeaderTest() throws Fault {
+    ReadableWritableEntity entity;
+    entity = new ReadableWritableEntity(EnumProvider.JAXRS.name());
+    String header = ReadableWritableEntity.NAME + ":" + entity.toXmlString();
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST_HEADERS, header);
+    setProperty(Property.REQUEST, buildRequest("POST", "readEntityFromHeader"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: readEntityFromBodyTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:JAVADOC:138;
+   * JAXRS:JAVADOC:304; JAXRS:JAVADOC:282;
+   * 
+   * @test_Strategy: Put entity to body and read it using reader
+   */
+  @Test
+  public void readEntityFromBodyTest() throws Fault {
+    ReadableWritableEntity entity;
+    entity = new ReadableWritableEntity(EnumProvider.JAXRS.name());
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST, buildRequest("POST", "readEntityFromBody"));
+    setProperty(Property.CONTENT, entity.toXmlString());
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.OK));
+    invoke();
+  }
+
+  /*
+   * @testName: readEntityIOExceptionTest
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:273; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+   * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272;
+   * 
+   * @test_Strategy: Put entity to body and read it using reader
+   */
+  @Test
+  public void readEntityIOExceptionTest() throws Fault {
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest("POST", "readEntityIOException"));
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.ACCEPTED));
+    invoke();
+  }
+
+  /*
+   * @testName: readEntityWebException400Test
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:274; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+   * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:SPEC:16.2;
+   * 
+   * @test_Strategy: Put entity to body and read it using reader
+   */
+  @Test
+  public void readEntityWebException400Test() throws Fault {
+    String code = ReadableWritableEntity.NAME + ":" + Status.BAD_REQUEST.name();
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest("POST", "readEntityWebException"));
+    setProperty(Property.REQUEST_HEADERS, code);
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.BAD_REQUEST));
+    invoke();
+  }
+
+  /*
+   * @testName: readEntityWebException410Test
+   * 
+   * @assertion_ids: JAXRS:JAVADOC:274; JAXRS:JAVADOC:138; JAXRS:JAVADOC:304;
+   * JAXRS:JAVADOC:282; JAXRS:JAVADOC:271; JAXRS:JAVADOC:272; JAXRS:SPEC:16.2;
+   * 
+   * @test_Strategy: Put entity to body and read it using reader
+   */
+  @Test
+  public void readEntityWebException410Test() throws Fault {
+    String code = ReadableWritableEntity.NAME + ":" + Status.GONE.name();
+    setProperty(Property.REQUEST_HEADERS,
+        "Content-Type: " + MediaType.TEXT_XML);
+    setProperty(Property.REQUEST,
+        buildRequest("POST", "readEntityWebException"));
+    setProperty(Property.REQUEST_HEADERS, code);
+    setProperty(Property.STATUS_CODE, getStatusCode(Status.GONE));
+    invoke();
+  }
+  
+  // ///////////////////////////////////////////////////////////////////////
+
+  protected int getReturnedNumber() throws Fault {
+    HttpResponse response = _testCase.getResponse();
+    String body;
+    try {
+      body = response.getResponseBodyAsString();
+    } catch (IOException e) {
+      throw new Fault(e);
+    }
+    return Integer.parseInt(body);
+  }
+
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java
new file mode 100644
index 0000000..fb7560b
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/ProvidersServlet.java
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityAnnotation;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+
+import jakarta.ws.rs.Consumes;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.ext.ContextResolver;
+import jakarta.ws.rs.ext.ExceptionMapper;
+import jakarta.ws.rs.ext.MessageBodyReader;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Providers;
+
+@Path("ProvidersServlet")
+public class ProvidersServlet extends ApplicationServlet {
+  @Context
+  Providers providers;
+
+  private EnumProvider getEnumProvider(MediaType type) {
+    ContextResolver<EnumProvider> scr = providers
+        .getContextResolver(EnumProvider.class, type);
+    EnumProvider ep = scr.getContext(EnumProvider.class);
+    return ep;
+  }
+
+  Response getResponseByEnumProvider(EnumProvider expected,
+      EnumProvider given) {
+    Status status = Status.NO_CONTENT;
+    if (given != null)
+      status = given != expected ? Status.NOT_ACCEPTABLE : Status.OK;
+    return Response.status(status).build();
+  }
+
+  @GET
+  @Path("isRegisteredContextResolver")
+  public Response isRegisteredContextResolver() {
+    EnumProvider ep = getEnumProvider(MediaType.WILDCARD_TYPE);
+    return getResponseByEnumProvider(EnumProvider.JAXRS, ep);
+  }
+
+  @GET
+  @Path("isRegisteredTextPlainContextResolver")
+  public Response isRegisteredTextPlainContextResolver() {
+    EnumProvider ep = getEnumProvider(MediaType.TEXT_PLAIN_TYPE);
+    return getResponseByEnumProvider(EnumProvider.CTS, ep);
+  }
+
+  @GET
+  @Path("isRegisteredAppJsonContextResolver")
+  public Response isRegisteredAppJsonContextResolver() {
+    EnumProvider ep = getEnumProvider(MediaType.APPLICATION_JSON_TYPE);
+    return getResponseByEnumProvider(EnumProvider.JAXRS, ep);
+  }
+
+  @GET
+  @Path("isRegisteredExceptionMapperRuntimeEx")
+  public Response isRegisteredExceptionMapperRuntimeException() {
+    ExceptionMapper<Exception> em = providers
+        .getExceptionMapper(Exception.class);
+    return em.toResponse(new RuntimeException());
+  }
+
+  @GET
+  @Path("isRegisteredExceptionMapperNullEx")
+  public Response isRegisteredExceptionMapperNullException() {
+    ExceptionMapper<Exception> em = providers
+        .getExceptionMapper(Exception.class);
+    return em.toResponse(null);
+  }
+
+  @GET
+  @Path("isRegisteredRuntimeExceptionMapper")
+  public Response isRegisteredRuntimeExceptionMapper() {
+    ExceptionMapper<RuntimeException> em = providers
+        .getExceptionMapper(RuntimeException.class);
+    Status status = Status.NOT_ACCEPTABLE;
+    if (em != null && AnyExceptionExceptionMapper.class.isInstance(em))
+      status = Status.OK;
+    // This serverError() is to get ResponseBuilder with status != OK
+    return Response.serverError().status(status).build();
+  }
+
+  @GET
+  @Path("isRegisteredIOExceptionMapper")
+  public Response isRegisteredIOExceptionExceptionMapper() {
+    ExceptionMapper<IOException> em = providers
+        .getExceptionMapper(IOException.class);
+    return em.toResponse(new IOException());
+  }
+
+  @GET
+  @Path("isRegisteredMessageReaderWildCard")
+  public Response isRegisteredEntityMessageReaderWildcard() {
+    MessageBodyReader<ReadableWritableEntity> reader;
+    reader = providers.getMessageBodyReader(ReadableWritableEntity.class, null,
+        getArgumentAnnotations("readEntityFromBody"), MediaType.WILDCARD_TYPE);
+    Status status = reader == null ? Status.NOT_ACCEPTABLE : Status.OK;
+    return Response.status(status).build();
+  }
+
+  @GET
+  @Path("isRegisteredMessageReaderXml")
+  public Response isRegisteredEntityMessageReaderXml() {
+    MessageBodyReader<ReadableWritableEntity> reader;
+    reader = providers.getMessageBodyReader(ReadableWritableEntity.class, null,
+        getArgumentAnnotations("readEntityFromBody"), MediaType.TEXT_XML_TYPE);
+    Status status = reader == null ? Status.NOT_ACCEPTABLE : Status.OK;
+    return Response.status(status).build();
+  }
+
+  @GET
+  @Path("isRegisteredWriterWildcard")
+  public Response isRegisteredWriterWildCard() {
+    MessageBodyWriter<ReadableWritableEntity> writer;
+    writer = providers.getMessageBodyWriter(ReadableWritableEntity.class, null,
+        getMethodAnnotations("writeBodyEntityUsingWriter"),
+        MediaType.WILDCARD_TYPE);
+    Status status = writer == null ? Status.NOT_ACCEPTABLE : Status.OK;
+    return Response.status(status).build();
+  }
+
+  @GET
+  @Path("isRegisteredMessageWriterXml")
+  public Response isRegisteredWriterXml() {
+    MessageBodyWriter<ReadableWritableEntity> entity;
+    entity = providers.getMessageBodyWriter(ReadableWritableEntity.class, null,
+        getMethodAnnotations("writeBodyEntityUsingWriter"),
+        MediaType.TEXT_XML_TYPE);
+    Status status = entity == null ? Status.NOT_ACCEPTABLE : Status.OK;
+    return Response.status(status).build();
+  }
+
+  @GET
+  @Produces(MediaType.TEXT_XML)
+  @Path("writeBodyEntityUsingWriter")
+  public Response writeBodyEntityUsingWriter() {
+    ReadableWritableEntity rwe = new ReadableWritableEntity(
+        EnumProvider.JAXRS.name());
+    return Response.ok(rwe).build();
+  }
+
+  @GET
+  @Produces(MediaType.TEXT_XML)
+  @Path("writeHeaderEntityUsingWriter")
+  public Response writeHeaderEntityUsingWriter() {
+    ReadableWritableEntity rwe = new ReadableWritableEntity(
+        EnumProvider.JAXRS.name());
+    return Response.ok(rwe).build();
+  }
+
+  @GET
+  @Produces(MediaType.TEXT_XML)
+  @Path("writeIOExceptionWithoutWriter")
+  public Response writeIOExceptionWithoutWriter() throws IOException {
+    throw new IOException("123 exception");
+  }
+
+  @GET
+  @Produces(MediaType.TEXT_XML)
+  @Path("writeIOExceptionUsingWriter")
+  public Response writeIOExceptionUsingWriter() throws IOException {
+    ReadableWritableEntity rwe = new ReadableWritableEntity("");
+    return Response.ok(rwe).build();
+  }
+
+  @POST
+  @Consumes(MediaType.TEXT_XML)
+  @Path("readEntityFromHeader")
+  public Response readEntityFromHeader(
+      @EntityAnnotation("Header") ReadableWritableEntity entity) {
+    Status status = Status.NO_CONTENT;
+    if (entity != null) {
+      boolean b = entity.toString().equals(EnumProvider.JAXRS.name());
+      status = b ? Status.OK : Status.NOT_ACCEPTABLE;
+    }
+    return Response.status(status).build();
+  }
+
+  @POST
+  @Consumes(MediaType.TEXT_XML)
+  @Path("readEntityFromBody")
+  public Response readEntityFromBody(
+      @EntityAnnotation("Body") ReadableWritableEntity entity) {
+    Status status = Status.NO_CONTENT;
+    if (entity != null) {
+      boolean b = entity.toString().equals(EnumProvider.JAXRS.name());
+      status = b ? Status.OK : Status.NOT_ACCEPTABLE;
+    }
+    return Response.status(status).build();
+  }
+
+  @POST
+  @Consumes(MediaType.TEXT_XML)
+  @Path("readEntityIOException")
+  public Response readEntityIOException(
+      @EntityAnnotation("IOException") ReadableWritableEntity entity) {
+    return Response.ok().build();
+  }
+
+  @POST
+  @Consumes(MediaType.TEXT_XML)
+  @Path("readEntityWebException")
+  public Response readEntityWebException(
+      @EntityAnnotation("WebException") ReadableWritableEntity entity) {
+    return Response.ok().build();
+  }
+
+  private Annotation[] getMethodAnnotations(String methodName) {
+    Method[] methods = getClass().getMethods();
+    for (Method method : methods)
+      if (method.getName().equals(methodName))
+        return method.getAnnotations();
+    return null;
+  }
+
+  private Annotation[] getArgumentAnnotations(String methodName) {
+    Method[] methods = getClass().getMethods();
+    for (Method method : methods)
+      if (method.getName().equals(methodName))
+        return method.getParameterAnnotations()[0];
+    return null;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java
new file mode 100644
index 0000000..a2fc9b8
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/providers/TSAppConfig.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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
+ */
+
+package jakarta.ws.rs.tck.ee.rs.ext.providers;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationHolderSingleton;
+import jakarta.ws.rs.tck.ee.rs.core.application.ApplicationServlet;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumContextResolver;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.EnumProvider;
+import jakarta.ws.rs.tck.ee.rs.ext.contextresolver.TextPlainEnumContextResolver;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.AnyExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.exceptionmapper.IOExceptionExceptionMapper;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageReader;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.EntityMessageWriter;
+import jakarta.ws.rs.tck.ee.rs.ext.messagebodyreaderwriter.ReadableWritableEntity;
+
+import jakarta.ws.rs.core.Application;
+
+public class TSAppConfig extends Application {
+
+  @Override
+  public java.util.Set<java.lang.Class<?>> getClasses() {
+    Set<Class<?>> resources = new HashSet<Class<?>>();
+    resources.add(ProvidersServlet.class);
+    resources.add(EnumContextResolver.class);
+    resources.add(ApplicationServlet.class);
+    resources.add(TextPlainEnumContextResolver.class);
+    resources.add(AnyExceptionExceptionMapper.class);
+    resources.add(IOExceptionExceptionMapper.class);
+    resources.add(EntityMessageWriter.class);
+    resources.add(EntityMessageReader.class);
+    return resources;
+  }
+
+  @Override
+  public Set<Object> getSingletons() {
+    Set<Object> singletons = new HashSet<Object>();
+    singletons.add(EnumProvider.CTS);
+    singletons.add(new ReadableWritableEntity(""));
+    singletons.add(new ApplicationHolderSingleton(this));
+    return singletons;
+  }
+
+}
diff --git a/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml
new file mode 100644
index 0000000..c08b530
--- /dev/null
+++ b/jaxrs-tck/src/main/java/jakarta/ws/rs/tck/ee/rs/ext/runtimedelegate/common.xml
@@ -0,0 +1,29 @@
+<!--
+
+    Copyright (c) 2012, 2018 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
+
+-->
+
+<project name="jaxrs_ee_ext_runtime_delegate_common" basedir="." default="usage">
+
+	<import file="../../../../../../../../../../bin/xml/ts.import.xml" />
+
+	<target name="compile">
+		<ant antfile="../../../../api/rs/ext/runtimedelegate/build.xml" useNativeBasedir="true" target="compile" />
+		<ts.javac includes="${pkg.dir}/**/*.java,
+                  com/sun/ts/tests/jaxrs/common/*.java" />
+	</target>
+
+</project>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template
new file mode 100644
index 0000000..e125eef
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/clientrequestcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTS_JAXRS_SPEC_CLIENT_CLIENTREQUESTCONTEXT</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.clientrequestcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTS_JAXRS_SPEC_CLIENT_CLIENTREQUESTCONTEXT</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/client/invocationbuilder/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template
new file mode 100644
index 0000000..79cf8d0
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/invocationbuilder/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTS_JAXRS_SPEC_CLIENT_INVOCATIONBUILDER</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.invocationbuilder.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTS_JAXRS_SPEC_CLIENT_INVOCATIONBUILDER</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/client/syncinvoker/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template
new file mode 100644
index 0000000..119e198
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/client/syncinvoker/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTS_JAXRS_SPEC_CLIENT_SYNCINVOKER</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.syncinvoker.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTS_JAXRS_SPEC_CLIENT_SYNCINVOKER</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/application/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/application/web.xml.template
new file mode 100644
index 0000000..07ea02f
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/application/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>CTSJAXRSAPPSERVLET</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.application.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSAPPSERVLET</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/configurable/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template
new file mode 100644
index 0000000..3ecbaa2
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configurable/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2013, 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>CTSJAXRSConfigurable</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.configurable.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSConfigurable</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/configuration/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template
new file mode 100644
index 0000000..bebac5a
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/configuration/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2013, 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>CTSJAXRSConfiguration</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.configurable.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSConfiguration</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/headers/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/headers/web.xml.template
new file mode 100644
index 0000000..0ca9800
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/headers/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-RSCOREHEADERS</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.headers.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAX-RSCOREHEADERS</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/response/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/response/web.xml.template
new file mode 100644
index 0000000..dcab3cf
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/response/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-RSRESPONSE</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.response.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAX-RSRESPONSE</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/responsebuilder/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template
new file mode 100644
index 0000000..20b661e
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/responsebuilder/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTS_JAXRS_RESPONSEBUILDER</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.responsebuilder.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTS_JAXRS_RESPONSEBUILDER</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/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml
new file mode 100644
index 0000000..0e9e638
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.ear.sun-application.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 2018 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
+
+-->
+
+<!DOCTYPE sun-application PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 J2EE Application 1.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-application_1_4-0.dtd">
+<sun-application>
+  <web>
+    <web-uri>jaxrs_ee_core_securitycontext_basic_web.war</web-uri>
+    <context-root>jaxrs_ee_core_securitycontext_basic_web</context-root>
+  </web>
+  <unique-id>0</unique-id>
+  <security-role-mapping>
+    <role-name>DIRECTOR</role-name>
+    <principal-name>j2ee</principal-name>
+  </security-role-mapping>
+  <security-role-mapping>
+    <role-name>OTHERROLE</role-name>
+    <principal-name>javajoe</principal-name>
+  </security-role-mapping>  
+</sun-application>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
new file mode 100644
index 0000000..5f9a0f3
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/jaxrs_ee_core_securitycontext_basic_web.war.sun-web.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 2018 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
+
+-->
+
+<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Sun ONE Application Server 8.0 Servlet 2.4//EN" "http://www.sun.com/software/sunone/appserver/dtds/sun-web-app_2_5-0.dtd">
+<sun-web-app>
+  <context-root>jaxrs_ee_core_securitycontext_basic_web</context-root>
+  <security-role-mapping>
+    <role-name>DIRECTOR</role-name>
+    <principal-name>j2ee</principal-name>
+  </security-role-mapping>
+  <security-role-mapping>
+    <role-name>OTHERROLE</role-name>
+    <principal-name>javajoe</principal-name>
+  </security-role-mapping>    
+</sun-web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template
new file mode 100644
index 0000000..8b45684
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/securitycontext/basic/web.xml.template
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRSSECURITYCONTEXTBASIC</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.securitycontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>        
+		<security-role-ref>
+		        <role-name>staff</role-name>
+		        <role-link>DIRECTOR</role-link>
+		</security-role-ref>
+		<security-role-ref>
+		        <role-name>guest</role-name>
+		        <role-link>OTHERROLE</role-link>
+		</security-role-ref>
+    </servlet>
+	<security-constraint>
+	    <display-name>Servlet</display-name>
+	    <web-resource-collection>
+	        <web-resource-name>Servlet</web-resource-name>
+	        <description></description>
+	        <url-pattern>/Servlet/*</url-pattern>
+	        <http-method>GET</http-method>
+	        <http-method>POST</http-method>
+	        <http-method>HEAD</http-method>
+	        <http-method>PUT</http-method>
+	    </web-resource-collection>
+	    <auth-constraint>
+	        <description>Have to be a USER</description>
+	        <role-name>DIRECTOR</role-name>
+	        <role-name>OTHERROLE</role-name>
+	    </auth-constraint>
+	    <user-data-constraint>
+	      <transport-guarantee>NONE</transport-guarantee>
+	    </user-data-constraint>
+	</security-constraint>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSSECURITYCONTEXTBASIC</servlet-name>
+        <url-pattern>/*</url-pattern>
+    </servlet-mapping>
+    <session-config>
+        <session-timeout>30</session-timeout>
+    </session-config>
+	<login-config>
+	    <auth-method>BASIC</auth-method>
+	</login-config>
+	<security-role>
+		<description>director</description>
+		<role-name>DIRECTOR</role-name>
+	</security-role>
+	<security-role>
+		<description>some other role name</description>
+		<role-name>OTHERROLE</role-name>
+	</security-role>
+</web-app>
diff --git a/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/web.xml.template
new file mode 100644
index 0000000..12132bc
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/core/uriinfo/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-RSURIINFO</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.uriinfo.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAX-RSURIINFO</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/ext/interceptor/clientwriter/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..10730d2
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CLIENT_WRITER_INTERCEPTOR</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.ext.interceptor.clientwriter.interceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CLIENT_WRITER_INTERCEPTOR</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/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..4289c5a
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/clientwriter/writerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CLIENT_WRITER_WRITERINTERCEPTOR</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.ext.interceptor.clientwriter.writerinterceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CLIENT_WRITER_WRITERINTERCEPTOR</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/ext/interceptor/containerreader/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..67a5a61
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CONTAINER_READER_INTERCEPTOR</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.ext.interceptor.containerreader.interceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CONTAINER_READER_INTERCEPTOR</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/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..d683a97
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerreader/readerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CONTAINER_READER_READERINTERCEPTOR</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.ext.interceptor.containerreader.readerinterceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CONTAINER_READER_READERINTERCEPTOR</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/ext/interceptor/containerwriter/interceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template
new file mode 100644
index 0000000..570b1ec
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/interceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CONTAINER_WRITER_INTERCEPTOR</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.ext.interceptor.containerwriter.interceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CONTAINER_WRITER_INTERCEPTOR</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/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template
new file mode 100644
index 0000000..7088145
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/interceptor/containerwriter/writerinterceptorcontext/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRS_CONTAINER_WRITER_WRITERINTERCEPTOR</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.ext.interceptor.containerwriter.writerinterceptorcontext.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRS_CONTAINER_WRITER_WRITERINTERCEPTOR</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/ext/paramconverter/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template
new file mode 100644
index 0000000..605baf7
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/paramconverter/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRSEXTPARAMCONVERTER</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.ext.paramconverter.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSEXTPARAMCONVERTER</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/ext/providers/web.xml.template b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template
new file mode 100644
index 0000000..7a17b02
--- /dev/null
+++ b/jaxrs-tck/src/main/resources/jakarta/ws/rs/tck/ee/rs/ext/providers/web.xml.template
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 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>CTSJAXRSEXTPROVIDERS</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.ext.providers.TSAppConfig</param-value>
+        </init-param>
+        <load-on-startup>1</load-on-startup>
+    </servlet>
+    <servlet-mapping>
+        <servlet-name>CTSJAXRSEXTPROVIDERS</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 79dd4f5..8f10525 100644
--- a/jersey-tck/pom.xml
+++ b/jersey-tck/pom.xml
@@ -134,6 +134,10 @@
                                 <webServerHost>localhost</webServerHost>
                                 <webServerPort>8080</webServerPort>
                                 <junit.log.traceflag>true</junit.log.traceflag>
+                                <user>j2ee</user>
+                                <password>j2ee</password>
+                                <authuser>javajoe</authuser>
+                                <authpassword>javajoe</authpassword>
                                 <porting.ts.url.class.1>jakarta.ws.rs.tck.lib.implementation.sun.common.SunRIURL</porting.ts.url.class.1>
                             </systemPropertyVariables>
                             <environmentVariables>
