Merge remote-tracking branch 'upstream/3.x' into 3.1

Signed-off-by: Maxim Nesen <maxim.nesen@oracle.com>
diff --git a/bom/pom.xml b/bom/pom.xml
index 7e75992..32bf17d 100644
--- a/bom/pom.xml
+++ b/bom/pom.xml
@@ -65,6 +65,11 @@
             </dependency>
             <dependency>
                 <groupId>org.glassfish.jersey.connectors</groupId>
+                <artifactId>jersey-apache5-connector</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.glassfish.jersey.connectors</groupId>
                 <artifactId>jersey-helidon-connector</artifactId>
                 <version>${project.version}</version>
             </dependency>
@@ -193,16 +198,11 @@
                 <artifactId>jersey-proxy-client</artifactId>
                 <version>${project.version}</version>
             </dependency>
-<!--            <dependency>-->
-<!--                <groupId>org.glassfish.jersey.ext</groupId>-->
-<!--                <artifactId>jersey-spring4</artifactId>-->
-<!--                <version>${project.version}</version>-->
-<!--            </dependency>-->
-<!--            <dependency>-->
-<!--                <groupId>org.glassfish.jersey.ext</groupId>-->
-<!--                <artifactId>jersey-spring5</artifactId>-->
-<!--                <version>${project.version}</version>-->
-<!--            </dependency>-->
+            <dependency>
+                <groupId>org.glassfish.jersey.ext</groupId>
+                <artifactId>jersey-spring6</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.glassfish.jersey.ext</groupId>
                 <artifactId>jersey-declarative-linking</artifactId>
@@ -263,11 +263,11 @@
                 <artifactId>jersey-rx-client-rxjava2</artifactId>
                 <version>${project.version}</version>
             </dependency>
-<!--            <dependency>-->
-<!--                <groupId>org.glassfish.jersey.ext.microprofile</groupId>-->
-<!--                <artifactId>jersey-mp-rest-client</artifactId>-->
-<!--                <version>${project.version}</version>-->
-<!--            </dependency>-->
+            <dependency>
+                <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+                <artifactId>jersey-mp-rest-client</artifactId>
+                <version>${project.version}</version>
+            </dependency>
             <dependency>
                 <groupId>org.glassfish.jersey.media</groupId>
                 <artifactId>jersey-media-jaxb</artifactId>
diff --git a/bundles/apidocs/pom.xml b/bundles/apidocs/pom.xml
index 3ac78a5..7e3c65c 100644
--- a/bundles/apidocs/pom.xml
+++ b/bundles/apidocs/pom.xml
@@ -60,11 +60,21 @@
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-apache5-connector</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-grizzly-connector</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-helidon-connector</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-jdk-connector</artifactId>
             <version>${project.version}</version>
         </dependency>
@@ -191,6 +201,11 @@
             <version>${project.version}</version>
         </dependency>
         <dependency>
+            <groupId>org.glassfish.jersey.ext.microprofile</groupId>
+            <artifactId>jersey-mp-rest-client</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+        <dependency>
             <groupId>org.glassfish.jersey.ext</groupId>
             <artifactId>jersey-wadl-doclet</artifactId>
             <version>${project.version}</version>
diff --git a/connectors/apache-connector/pom.xml b/connectors/apache-connector/pom.xml
index b406464..f366855 100644
--- a/connectors/apache-connector/pom.xml
+++ b/connectors/apache-connector/pom.xml
@@ -55,11 +55,6 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheClientProperties.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheClientProperties.java
index d5c2ff8..099fa31 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheClientProperties.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheClientProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -89,8 +89,8 @@
 
     /**
      * A value of {@code true} indicates that configured connection manager should be shared
-     * among multiple Jersey {@link org.glassfish.jersey.client.ClientRuntime} instances. It means that closing
-     * a particular {@link org.glassfish.jersey.client.ClientRuntime} instance does not shut down the underlying
+     * among multiple Jersey {@code ClientRuntime} instances. It means that closing
+     * a particular {@code ClientRuntime} instance does not shut down the underlying
      * connection manager automatically. In such case, the connection manager life-cycle
      * should be fully managed by the application code. To release all allocated resources,
      * caller code should especially ensure {@link org.apache.http.conn.HttpClientConnectionManager#shutdown()} gets
@@ -114,7 +114,7 @@
      * <p/>
      * The value MUST be an instance of {@link org.apache.http.client.config.RequestConfig}.
      * <p/>
-     * If the property is absent default request configuration will be used.
+     * If the property is absent the default request configuration will be used.
      * <p/>
      * The name of the configuration property is <tt>{@value}</tt>.
      *
@@ -137,9 +137,9 @@
     /**
      * ConnectionReuseStrategy for the {@link org.apache.http.client.HttpClient}.
      * <p/>
-     * The value MUST be an instance of {@link org.apache.http.impl.ConnectionReuseStrategy}.
+     * The value MUST be an instance of {@link org.apache.http.ConnectionReuseStrategy}.
      * <p/>
-     * If the property is absent the default reuse strategy of the Apache HTTP library will be used
+     * If the property is absent the default reuse strategy of the Apache HTTP library will be used.
      * <p/>
      * The name of the configuration property is <tt>{@value}</tt>.
      */
@@ -158,7 +158,9 @@
 
 
     /**
-     * Strategy that closes the Apache Connection. Accepts an instance of {@link ApacheConnectionClosingStrategy}.
+     * <p>
+     *  Strategy that closes the Apache Connection. Accepts an instance of {@link ApacheConnectionClosingStrategy}.
+     * </p>
      *
      * @see ApacheConnectionClosingStrategy
      * @since 2.30
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
index dafd360..0b08871 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnector.java
@@ -110,18 +110,22 @@
  * <p/>
  * The following properties are only supported at construction of this class:
  * <ul>
+ * <li>{@link ApacheClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
  * <li>{@link ApacheClientProperties#CONNECTION_MANAGER}</li>
- * <li>{@link ApacheClientProperties#REQUEST_CONFIG}</li>
+ * <li>{@link ApacheClientProperties#CONNECTION_MANAGER_SHARED}</li>
+ * <li>{@link ApacheClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
  * <li>{@link ApacheClientProperties#CREDENTIALS_PROVIDER}</li>
  * <li>{@link ApacheClientProperties#DISABLE_COOKIES}</li>
  * <li>{@link ApacheClientProperties#KEEPALIVE_STRATEGY}</li>
+ * <li>{@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING} - default value is {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED}</li>
- * <li>{@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link ApacheClientProperties#REQUEST_CONFIG}</li>
  * <li>{@link ApacheClientProperties#RETRY_HANDLER}</li>
  * <li>{@link ApacheClientProperties#REUSE_STRATEGY}</li>
+ * <li>{@link ApacheClientProperties#USE_SYSTEM_PROPERTIES}</li>
  * </ul>
  * <p>
  * This connector uses {@link RequestEntityProcessing#CHUNKED chunked encoding} as a default setting. This can
diff --git a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java
index 39b78ee..8aa3877 100644
--- a/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java
+++ b/connectors/apache-connector/src/main/java/org/glassfish/jersey/apache/connector/ApacheConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -33,19 +33,23 @@
  * <p>
  * The following connector configuration properties are supported:
  * <ul>
+ * <li>{@link ApacheClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
  * <li>{@link ApacheClientProperties#CONNECTION_MANAGER}</li>
- * <li>{@link ApacheClientProperties#REQUEST_CONFIG}</li>
+ * <li>{@link ApacheClientProperties#CONNECTION_MANAGER_SHARED}</li>
+ * <li>{@link ApacheClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
  * <li>{@link ApacheClientProperties#CREDENTIALS_PROVIDER}</li>
  * <li>{@link ApacheClientProperties#DISABLE_COOKIES}</li>
  * <li>{@link ApacheClientProperties#KEEPALIVE_STRATEGY}</li>
+ * <li>{@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING}
  * - default value is {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED}</li>
- * <li>{@link ApacheClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link ApacheClientProperties#REQUEST_CONFIG}</li>
  * <li>{@link ApacheClientProperties#RETRY_HANDLER}</li>
  * <li>{@link ApacheClientProperties#REUSE_STRATEGY}</li>
+ * <li>{@link ApacheClientProperties#USE_SYSTEM_PROPERTIES}</li>
  * </ul>
  * </p>
  * <p>
diff --git a/connectors/apache5-connector/pom.xml b/connectors/apache5-connector/pom.xml
new file mode 100644
index 0000000..6e24418
--- /dev/null
+++ b/connectors/apache5-connector/pom.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0"?>
+<!--
+
+    Copyright (c) 2022 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.glassfish.jersey.connectors</groupId>
+        <artifactId>project</artifactId>
+        <version>3.1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-apache5-connector</artifactId>
+    <packaging>jar</packaging>
+    <name>jersey-connectors-apache5</name>
+
+    <description>Jersey Client Transport via Apache HttpClient 5.x</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.httpcomponents.client5</groupId>
+            <artifactId>httpclient5</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-grizzly2-http</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ClientProperties.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ClientProperties.java
new file mode 100644
index 0000000..df4c8e0
--- /dev/null
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ClientProperties.java
@@ -0,0 +1,207 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.util.Map;
+
+import org.glassfish.jersey.internal.util.PropertiesClass;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+
+/**
+ * Configuration options specific to the Client API that utilizes {@link Apache5ConnectorProvider}.
+ *
+ * @author jorgeluisw@mac.com
+ * @author Paul Sandoz
+ * @author Pavel Bucek
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Steffen Nießing
+ */
+@PropertiesClass
+public final class Apache5ClientProperties {
+
+    /**
+     * The credential provider that should be used to retrieve
+     * credentials from a user. Credentials needed for proxy authentication
+     * are stored here as well.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.client5.http.auth.CredentialsProvider}.
+     * <p/>
+     * If the property is absent a default provider will be used.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String CREDENTIALS_PROVIDER = "jersey.config.apache5.client.credentialsProvider";
+
+    /**
+     * A value of {@code false} indicates the client should handle cookies
+     * automatically using HttpClient's default cookie policy. A value
+     * of {@code true} will cause the client to ignore all cookies.
+     * <p/>
+     * The value MUST be an instance of {@link java.lang.Boolean}.
+     * <p/>
+     * The default value is {@code false}.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String DISABLE_COOKIES = "jersey.config.apache5.client.handleCookies";
+
+    /**
+     * A value of {@code true} indicates that a client should send an
+     * authentication request even before the server gives a 401
+     * response.
+     * <p>
+     * This property may only be set prior to constructing Apache connector using {@link Apache5ConnectorProvider}.
+     * <p/>
+     * The value MUST be an instance of {@link java.lang.Boolean}.
+     * <p/>
+     * The default value is {@code false}.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String PREEMPTIVE_BASIC_AUTHENTICATION = "jersey.config.apache5.client.preemptiveBasicAuthentication";
+
+    /**
+     * Connection Manager which will be used to create {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.client5.http.io.HttpClientConnectionManager}.
+     * <p/>
+     * If the property is absent a default Connection Manager will be used
+     * ({@link org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager}).
+     * If you want to use this client in multi-threaded environment, be sure you override default value with
+     * {@link org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager} instance.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String CONNECTION_MANAGER = "jersey.config.apache5.client.connectionManager";
+
+    /**
+     * A value of {@code true} indicates that configured connection manager should be shared
+     * among multiple Jersey {@code ClientRuntime} instances. It means that closing
+     * a particular {@code ClientRuntime} instance does not shut down the underlying
+     * connection manager automatically. In such case, the connection manager life-cycle
+     * should be fully managed by the application code. To release all allocated resources,
+     * caller code should especially ensure {@link org.apache.hc.client5.http.io.HttpClientConnectionManager#close()} gets
+     * invoked eventually.
+     * <p>
+     * This property may only be set prior to constructing Apache connector using {@link Apache5ConnectorProvider}.
+     * <p/>
+     * The value MUST be an instance of {@link java.lang.Boolean}.
+     * <p/>
+     * The default value is {@code false}.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     *
+     * @since 2.18
+     */
+    public static final String CONNECTION_MANAGER_SHARED = "jersey.config.apache5.client.connectionManagerShared";
+
+    /**
+     * Request configuration for the {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * Http parameters which will be used to create {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.client5.http.config.RequestConfig}.
+     * <p/>
+     * If the property is absent default request configuration will be used.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     *
+     * @since 2.5
+     */
+    public static final String REQUEST_CONFIG = "jersey.config.apache5.client.requestConfig";
+
+    /**
+     * HttpRequestRetryStrategy which will be used to create {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.client5.http.HttpRequestRetryStrategy}.
+     * <p/>
+     * If the property is absent a default retry handler will be used
+     * ({@link org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy}).
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String RETRY_STRATEGY = "jersey.config.apache5.client.retryStrategy";
+
+    /**
+     * ConnectionReuseStrategy for the {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.core5.http.ConnectionReuseStrategy}.
+     * <p/>
+     * If the property is absent the default reuse strategy of the Apache HTTP library will be used
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String REUSE_STRATEGY = "jersey.config.apache5.client.reuseStrategy";
+
+    /**
+     * ConnectionKeepAliveStrategy for the {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * <p/>
+     * The value MUST be an instance of {@link org.apache.hc.client5.http.ConnectionKeepAliveStrategy}.
+     * <p/>
+     * If the property is absent the default keepalive strategy of the Apache HTTP library will be used
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String KEEPALIVE_STRATEGY = "jersey.config.apache5.client.keepAliveStrategy";
+
+
+    /**
+     * Strategy that closes the Apache Connection. Accepts an instance of {@link Apache5ConnectionClosingStrategy}.
+     *
+     * @see Apache5ConnectionClosingStrategy
+     * @since 2.30
+     */
+    public static final String CONNECTION_CLOSING_STRATEGY = "jersey.config.apache5.client.connectionClosingStrategy";
+
+    /**
+     * A value of {@code false} indicates the client will use default ApacheConnector params. A value
+     * of {@code true} will cause the client to take into account the system properties
+     * {@code https.protocols}, {@code https.cipherSuites}, {@code http.keepAlive},
+     * {@code http.maxConnections}.
+     * <p/>
+     * The value MUST be an instance of {@link java.lang.Boolean}.
+     * <p/>
+     * The default value is {@code false}.
+     * <p/>
+     * The name of the configuration property is <tt>{@value}</tt>.
+     */
+    public static final String USE_SYSTEM_PROPERTIES = "jersey.config.apache5.client.useSystemProperties";
+
+    /**
+     * Get the value of the specified property.
+     *
+     * If the property is not set or the actual property value type is not compatible with the specified type, the method will
+     * return {@code null}.
+     *
+     * @param properties    Map of properties to get the property value from.
+     * @param key           Name of the property.
+     * @param type          Type to retrieve the value as.
+     * @param <T>           Type of the property value.
+     * @return Value of the property or {@code null}.
+     *
+     * @since 2.8
+     */
+    public static <T> T getValue(final Map<String, ?> properties, final String key, final Class<T> type) {
+        return PropertiesHelper.getValue(properties, key, type, null);
+    }
+
+    /**
+     * Prevents instantiation.
+     */
+    private Apache5ClientProperties() {
+        throw new AssertionError("No instances allowed.");
+    }
+}
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectionClosingStrategy.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectionClosingStrategy.java
new file mode 100644
index 0000000..ad23f2d
--- /dev/null
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectionClosingStrategy.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.glassfish.jersey.client.ClientRequest;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URISyntaxException;
+
+/**
+ * Strategy that defines the way the Apache client releases resources. The client enables closing the content stream
+ * and the response. From the Apache documentation:
+ * <pre>
+ *     The difference between closing the content stream and closing the response is that
+ *     the former will attempt to keep the underlying connection alive by consuming the
+ *     entity content while the latter immediately shuts down and discards the connection.
+ * </pre>
+ * In the case of Chunk content stream, the stream is not closed on the server side, and the client can hang on reading
+ * the closing chunk. Using the {@link org.glassfish.jersey.client.ClientProperties#READ_TIMEOUT} property can prevent
+ * this hanging forever and the reading of the closing chunk is terminated when the time is out. The other option, when
+ * the timeout is not set, is to abort the Apache client request. This is the default for Apache Client 4.5.1+ when the
+ * read timeout is not set.
+ * <p/>
+ * Another option is not to close the content stream, which is possible by the Apache client documentation. In this case,
+ * however, the server side may not be notified and would not close its chunk stream.
+ */
+public interface Apache5ConnectionClosingStrategy {
+    /**
+     * Method to close the connection.
+     * @param clientRequest The {@link ClientRequest} to get {@link ClientRequest#getConfiguration() configuration},
+     *                      and {@link ClientRequest#resolveProperty(String, Class) resolve properties}.
+     * @param request Apache {@code HttpUriRequest} that can be {@code abort}ed.
+     * @param response Apache {@code CloseableHttpResponse} that can be {@code close}d.
+     * @param stream The entity stream that can be {@link InputStream#close() closed}.
+     * @throws IOException In case of some of the closing methods throws {@link IOException}
+     */
+    void close(ClientRequest clientRequest, HttpUriRequest request, CloseableHttpResponse response, InputStream stream)
+            throws IOException;
+
+    /**
+     * Strategy that aborts Apache HttpRequests for the case of Chunked Stream, closes the stream, and response next.
+     */
+    class Apache5GracefulClosingStrategy implements Apache5ConnectionClosingStrategy {
+        private static final String UNIX_PROTOCOL = "unix";
+
+        static final Apache5GracefulClosingStrategy INSTANCE = new Apache5GracefulClosingStrategy();
+
+        @Override
+        public void close(ClientRequest clientRequest, HttpUriRequest request, CloseableHttpResponse response, InputStream stream)
+                throws IOException {
+            boolean isUnixProtocol = false;
+            try {
+                isUnixProtocol = UNIX_PROTOCOL.equals(request.getUri().getScheme());
+            } catch (URISyntaxException ex) {
+                // Ignore
+            }
+            if (response.getEntity() != null && response.getEntity().isChunked() && !isUnixProtocol) {
+                request.abort();
+            }
+            try {
+                stream.close();
+            } catch (IOException ex) {
+                // Ignore
+            } finally {
+                response.close();
+            }
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
new file mode 100644
index 0000000..5cc2e63
--- /dev/null
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5Connector.java
@@ -0,0 +1,817 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.Future;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import java.util.stream.Collectors;
+
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configuration;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.hc.client5.http.ConnectionKeepAliveStrategy;
+import org.apache.hc.client5.http.HttpRequestRetryStrategy;
+import org.apache.hc.client5.http.auth.AuthCache;
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.CredentialsStore;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequest;
+import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.apache.hc.client5.http.cookie.BasicCookieStore;
+import org.apache.hc.client5.http.cookie.CookieStore;
+import org.apache.hc.client5.http.cookie.StandardCookieSpec;
+import org.apache.hc.client5.http.impl.auth.BasicAuthCache;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.auth.BasicScheme;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
+import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.protocol.HttpClientContext;
+import org.apache.hc.client5.http.socket.ConnectionSocketFactory;
+import org.apache.hc.client5.http.socket.LayeredConnectionSocketFactory;
+import org.apache.hc.client5.http.socket.PlainConnectionSocketFactory;
+import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactory;
+import org.apache.hc.core5.http.ConnectionReuseStrategy;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpEntity;
+import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.config.Http1Config;
+import org.apache.hc.core5.http.config.Registry;
+import org.apache.hc.core5.http.config.RegistryBuilder;
+import org.apache.hc.core5.http.impl.DefaultContentLengthStrategy;
+import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
+import org.apache.hc.core5.http.io.entity.BufferedHttpEntity;
+import org.apache.hc.core5.ssl.SSLContexts;
+import org.apache.hc.core5.util.TextUtils;
+import org.apache.hc.core5.util.Timeout;
+import org.apache.hc.core5.util.VersionInfo;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientRequest;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.client.spi.AsyncConnectorCallback;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.internal.util.PropertiesHelper;
+import org.glassfish.jersey.message.internal.HeaderUtils;
+import org.glassfish.jersey.message.internal.OutboundMessageContext;
+import org.glassfish.jersey.message.internal.ReaderWriter;
+import org.glassfish.jersey.message.internal.Statuses;
+
+/**
+ * A {@link Connector} that utilizes the Apache HTTP Client to send and receive
+ * HTTP request and responses.
+ * <p/>
+ * The following properties are only supported at construction of this class:
+ * <ul>
+ * <li>{@link Apache5ClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#CONNECTION_MANAGER}</li>
+ * <li>{@link Apache5ClientProperties#CONNECTION_MANAGER_SHARED}</li>
+ * <li>{@link Apache5ClientProperties#DISABLE_COOKIES}</li>
+ * <li>{@link Apache5ClientProperties#CREDENTIALS_PROVIDER}</li>
+ * <li>{@link Apache5ClientProperties#KEEPALIVE_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING} - default value is {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED}</li>
+ * <li>{@link Apache5ClientProperties#REQUEST_CONFIG}</li>
+ * <li>{@link Apache5ClientProperties#RETRY_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#REUSE_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#USE_SYSTEM_PROPERTIES}</li>
+ * </ul>
+ * <p>
+ * This connector uses {@link RequestEntityProcessing#CHUNKED chunked encoding} as a default setting. This can
+ * be overridden by the {@link ClientProperties#REQUEST_ENTITY_PROCESSING}. By default the
+ * {@link ClientProperties#CHUNKED_ENCODING_SIZE} property is only supported by using default connection manager. If custom
+ * connection manager needs to be used then chunked encoding size can be set by providing a custom
+ * {@link org.apache.hc.core5.http.io.HttpClientConnection} (via custom {@link org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory})
+ * and overriding {@code createOutputStream} method.
+ * </p>
+ * <p>
+ * Using of authorization is dependent on the chunk encoding setting. If the entity
+ * buffering is enabled, the entity is buffered and authorization can be performed
+ * automatically in response to a 401 by sending the request again. When entity buffering
+ * is disabled (chunked encoding is used) then the property
+ * {@link Apache5ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION} must
+ * be set to {@code true}.
+ * </p>
+ * <p>
+ * Registration of {@link Apache5HttpClientBuilderConfigurator} instance on the
+ * {@link jakarta.ws.rs.client.Client#register(Object) Client} is supported. A configuration provided by
+ * {@link Apache5HttpClientBuilderConfigurator} will override the {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder}
+ * configuration set by using the properties.
+ * </p>
+ * <p>
+ * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an
+ * entity is not read from the response then
+ * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called
+ * after processing the response to release connection-based resources.
+ * </p>
+ * <p>
+ * Client operations are thread safe, the HTTP connection may
+ * be shared between different threads.
+ * </p>
+ * <p>
+ * If a response entity is obtained that is an instance of {@link Closeable}
+ * then the instance MUST be closed after processing the entity to release
+ * connection-based resources.
+ * </p>
+ * <p>
+ * The following methods are currently supported: HEAD, GET, POST, PUT, DELETE, OPTIONS, PATCH and TRACE.
+ * </p>
+ *
+ * @author jorgeluisw@mac.com
+ * @author Paul Sandoz
+ * @author Pavel Bucek
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Steffen Nießing
+ * @see Apache5ClientProperties#CONNECTION_MANAGER
+ */
+class Apache5Connector implements Connector {
+
+    private static final Logger LOGGER = Logger.getLogger(Apache5Connector.class.getName());
+    private static final VersionInfo vi;
+    private static final String release;
+
+    static {
+        vi = VersionInfo.loadVersionInfo("org.apache.hc.client5", HttpClientBuilder.class.getClassLoader());
+        release = (vi != null) ? vi.getRelease() : VersionInfo.UNAVAILABLE;
+    }
+
+    private final CloseableHttpClient client;
+    private final CookieStore cookieStore;
+    private final boolean preemptiveBasicAuth;
+    private final RequestConfig requestConfig;
+
+    /**
+     * Create the new Apache HTTP Client connector.
+     *
+     * @param client JAX-RS client instance for which the connector is being created.
+     * @param config client configuration.
+     */
+    Apache5Connector(final Client client, final Configuration config) {
+        final Object connectionManager = config.getProperties().get(Apache5ClientProperties.CONNECTION_MANAGER);
+        if (connectionManager != null) {
+            if (!(connectionManager instanceof HttpClientConnectionManager)) {
+                LOGGER.log(
+                        Level.WARNING,
+                        LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                Apache5ClientProperties.CONNECTION_MANAGER,
+                                connectionManager.getClass().getName(),
+                                HttpClientConnectionManager.class.getName())
+                );
+            }
+        }
+
+        Object keepAliveStrategy = config.getProperties().get(Apache5ClientProperties.KEEPALIVE_STRATEGY);
+        if (keepAliveStrategy != null) {
+            if (!(keepAliveStrategy instanceof ConnectionKeepAliveStrategy)) {
+                LOGGER.log(
+                        Level.WARNING,
+                        LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                Apache5ClientProperties.KEEPALIVE_STRATEGY,
+                                keepAliveStrategy.getClass().getName(),
+                                ConnectionKeepAliveStrategy.class.getName())
+                );
+                keepAliveStrategy = null;
+            }
+        }
+
+        Object reuseStrategy = config.getProperties().get(Apache5ClientProperties.REUSE_STRATEGY);
+        if (reuseStrategy != null) {
+            if (!(reuseStrategy instanceof ConnectionReuseStrategy)) {
+                LOGGER.log(
+                        Level.WARNING,
+                        LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                Apache5ClientProperties.REUSE_STRATEGY,
+                                reuseStrategy.getClass().getName(),
+                                ConnectionReuseStrategy.class.getName())
+                );
+                reuseStrategy = null;
+            }
+        }
+
+        Object reqConfig = config.getProperties().get(Apache5ClientProperties.REQUEST_CONFIG);
+        if (reqConfig != null) {
+            if (!(reqConfig instanceof RequestConfig)) {
+                LOGGER.log(
+                        Level.WARNING,
+                        LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                Apache5ClientProperties.REQUEST_CONFIG,
+                                reqConfig.getClass().getName(),
+                                RequestConfig.class.getName())
+                );
+                reqConfig = null;
+            }
+        }
+
+        final SSLContext sslContext = client.getSslContext();
+        final HttpClientBuilder clientBuilder = HttpClientBuilder.create();
+
+        clientBuilder.setConnectionManager(getConnectionManager(client, config, sslContext));
+        clientBuilder.setConnectionManagerShared(
+                PropertiesHelper.getValue(
+                        config.getProperties(),
+                        Apache5ClientProperties.CONNECTION_MANAGER_SHARED,
+                        false,
+                        null
+                )
+        );
+        if (keepAliveStrategy != null) {
+            clientBuilder.setKeepAliveStrategy((ConnectionKeepAliveStrategy) keepAliveStrategy);
+        }
+        if (reuseStrategy != null) {
+            clientBuilder.setConnectionReuseStrategy((ConnectionReuseStrategy) reuseStrategy);
+        }
+
+        final RequestConfig.Builder requestConfigBuilder = RequestConfig.custom();
+
+        final Object credentialsProvider = config.getProperty(Apache5ClientProperties.CREDENTIALS_PROVIDER);
+        if (credentialsProvider != null && (credentialsProvider instanceof CredentialsProvider)) {
+            clientBuilder.setDefaultCredentialsProvider((CredentialsProvider) credentialsProvider);
+        }
+
+        final Object retryHandler = config.getProperties().get(Apache5ClientProperties.RETRY_STRATEGY);
+        if (retryHandler != null && (retryHandler instanceof HttpRequestRetryStrategy)) {
+            clientBuilder.setRetryStrategy((HttpRequestRetryStrategy) retryHandler);
+        }
+
+        final Object proxyUri;
+        proxyUri = config.getProperty(ClientProperties.PROXY_URI);
+        if (proxyUri != null) {
+            final URI u = getProxyUri(proxyUri);
+            final HttpHost proxy = new HttpHost(u.getScheme(), u.getHost(), u.getPort());
+            final String userName;
+            userName = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_USERNAME, String.class);
+            if (userName != null) {
+                final String password;
+                password = ClientProperties.getValue(config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
+
+                if (password != null) {
+                    final CredentialsStore credsProvider = new BasicCredentialsProvider();
+                    credsProvider.setCredentials(
+                            new AuthScope(u.getHost(), u.getPort()),
+                            new UsernamePasswordCredentials(userName, password.toCharArray())
+                    );
+                    clientBuilder.setDefaultCredentialsProvider(credsProvider);
+                }
+            }
+            clientBuilder.setProxy(proxy);
+        }
+
+        final Boolean preemptiveBasicAuthProperty = (Boolean) config.getProperties()
+                .get(Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION);
+        this.preemptiveBasicAuth = (preemptiveBasicAuthProperty != null) ? preemptiveBasicAuthProperty : false;
+
+        final boolean ignoreCookies = PropertiesHelper.isProperty(
+                config.getProperties(),
+                Apache5ClientProperties.DISABLE_COOKIES
+        );
+
+        if (reqConfig != null) {
+            final RequestConfig.Builder reqConfigBuilder = RequestConfig.copy((RequestConfig) reqConfig);
+            if (ignoreCookies) {
+                reqConfigBuilder.setCookieSpec(StandardCookieSpec.IGNORE);
+            }
+            requestConfig = reqConfigBuilder.build();
+        } else {
+            if (ignoreCookies) {
+                requestConfigBuilder.setCookieSpec(StandardCookieSpec.IGNORE);
+            }
+            requestConfig = requestConfigBuilder.build();
+        }
+
+        if (requestConfig.getCookieSpec() == null || !requestConfig.getCookieSpec().equals(StandardCookieSpec.IGNORE)) {
+            this.cookieStore = new BasicCookieStore();
+            clientBuilder.setDefaultCookieStore(cookieStore);
+        } else {
+            this.cookieStore = null;
+        }
+        clientBuilder.setDefaultRequestConfig(requestConfig);
+
+        LinkedList<Object> contracts = config.getInstances().stream()
+                .filter(Apache5HttpClientBuilderConfigurator.class::isInstance)
+                .collect(Collectors.toCollection(LinkedList::new));
+
+        HttpClientBuilder configuredBuilder = clientBuilder;
+        for (Object configurator : contracts) {
+            configuredBuilder = ((Apache5HttpClientBuilderConfigurator) configurator).configure(configuredBuilder);
+        }
+
+        this.client = configuredBuilder.build();
+    }
+
+    private HttpClientConnectionManager getConnectionManager(final Client client,
+                                                             final Configuration config,
+                                                             final SSLContext sslContext) {
+        final Object cmObject = config.getProperties().get(Apache5ClientProperties.CONNECTION_MANAGER);
+
+        // Connection manager from configuration.
+        if (cmObject != null) {
+            if (cmObject instanceof HttpClientConnectionManager) {
+                return (HttpClientConnectionManager) cmObject;
+            } else {
+                LOGGER.log(
+                        Level.WARNING,
+                        LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                Apache5ClientProperties.CONNECTION_MANAGER,
+                                cmObject.getClass().getName(),
+                                HttpClientConnectionManager.class.getName())
+                );
+            }
+        }
+
+        final boolean useSystemProperties =
+            PropertiesHelper.isProperty(config.getProperties(), Apache5ClientProperties.USE_SYSTEM_PROPERTIES);
+
+        // Create custom connection manager.
+        return createConnectionManager(
+                client,
+                config,
+                sslContext,
+            useSystemProperties);
+    }
+
+    private HttpClientConnectionManager createConnectionManager(
+            final Client client,
+            final Configuration config,
+            final SSLContext sslContext,
+            final boolean useSystemProperties) {
+
+        final String[] supportedProtocols = useSystemProperties ? split(
+                System.getProperty("https.protocols")) : null;
+        final String[] supportedCipherSuites = useSystemProperties ? split(
+                System.getProperty("https.cipherSuites")) : null;
+
+        HostnameVerifier hostnameVerifier = client.getHostnameVerifier();
+
+        final LayeredConnectionSocketFactory sslSocketFactory;
+        if (sslContext != null) {
+            sslSocketFactory = new SSLConnectionSocketFactory(
+                    sslContext, supportedProtocols, supportedCipherSuites, hostnameVerifier);
+        } else {
+            if (useSystemProperties) {
+                sslSocketFactory = new SSLConnectionSocketFactory(
+                        (SSLSocketFactory) SSLSocketFactory.getDefault(),
+                        supportedProtocols, supportedCipherSuites, hostnameVerifier);
+            } else {
+                sslSocketFactory = new SSLConnectionSocketFactory(
+                        SSLContexts.createDefault(),
+                        hostnameVerifier);
+            }
+        }
+
+        final Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
+                .register("http", PlainConnectionSocketFactory.getSocketFactory())
+                .register("https", sslSocketFactory)
+                .build();
+
+        final Integer chunkSize = ClientProperties.getValue(config.getProperties(),
+                ClientProperties.CHUNKED_ENCODING_SIZE, ClientProperties.DEFAULT_CHUNK_SIZE, Integer.class);
+
+        final PoolingHttpClientConnectionManager connectionManager =
+                new PoolingHttpClientConnectionManager(registry, new ConnectionFactory(chunkSize));
+
+        if (useSystemProperties) {
+            String s = System.getProperty("http.keepAlive", "true");
+            if ("true".equalsIgnoreCase(s)) {
+                s = System.getProperty("http.maxConnections", "5");
+                final int max = Integer.parseInt(s);
+                connectionManager.setDefaultMaxPerRoute(max);
+                connectionManager.setMaxTotal(2 * max);
+            }
+        }
+
+        return connectionManager;
+    }
+
+    private static String[] split(final String s) {
+        if (TextUtils.isBlank(s)) {
+            return null;
+        }
+        return s.split(" *, *");
+    }
+
+    /**
+     * Get the {@link HttpClient}.
+     *
+     * @return the {@link HttpClient}.
+     */
+    @SuppressWarnings("UnusedDeclaration")
+    public HttpClient getHttpClient() {
+        return client;
+    }
+
+    /**
+     * Get the {@link CookieStore}.
+     *
+     * @return the {@link CookieStore} instance or {@code null} when {@value Apache5ClientProperties#DISABLE_COOKIES} set to
+     * {@code true}.
+     */
+    public CookieStore getCookieStore() {
+        return cookieStore;
+    }
+
+    private static URI getProxyUri(final Object proxy) {
+        if (proxy instanceof URI) {
+            return (URI) proxy;
+        } else if (proxy instanceof String) {
+            return URI.create((String) proxy);
+        } else {
+            throw new ProcessingException(LocalizationMessages.WRONG_PROXY_URI_TYPE(ClientProperties.PROXY_URI));
+        }
+    }
+
+    @Override
+    public ClientResponse apply(final ClientRequest clientRequest) throws ProcessingException {
+        final HttpUriRequest request = getUriHttpRequest(clientRequest);
+        final Map<String, String> clientHeadersSnapshot = writeOutBoundHeaders(clientRequest, request);
+
+        try {
+            final CloseableHttpResponse response;
+            final HttpClientContext context = HttpClientContext.create();
+            if (preemptiveBasicAuth) {
+                final AuthCache authCache = new BasicAuthCache();
+                final BasicScheme basicScheme = new BasicScheme();
+                authCache.put(getHost(request), basicScheme);
+                context.setAuthCache(authCache);
+            }
+
+            // If a request-specific CredentialsProvider exists, use it instead of the default one
+            CredentialsProvider credentialsProvider =
+                    clientRequest.resolveProperty(Apache5ClientProperties.CREDENTIALS_PROVIDER, CredentialsProvider.class);
+            if (credentialsProvider != null) {
+                context.setCredentialsProvider(credentialsProvider);
+            }
+
+            response = client.execute(getHost(request), request, context);
+            HeaderUtils.checkHeaderChanges(clientHeadersSnapshot, clientRequest.getHeaders(),
+                    this.getClass().getName(), clientRequest.getConfiguration());
+
+            final Response.StatusType status = response.getReasonPhrase() == null
+                    ? Statuses.from(response.getCode())
+                    : Statuses.from(response.getCode(), response.getReasonPhrase());
+
+            final ClientResponse responseContext = new ClientResponse(status, clientRequest);
+            final List<URI> redirectLocations = context.getRedirectLocations().getAll();
+            if (redirectLocations != null && !redirectLocations.isEmpty()) {
+                responseContext.setResolvedRequestUri(redirectLocations.get(redirectLocations.size() - 1));
+            }
+
+            final Header[] respHeaders = response.getHeaders();
+            final MultivaluedMap<String, String> headers = responseContext.getHeaders();
+            for (final Header header : respHeaders) {
+                final String headerName = header.getName();
+                List<String> list = headers.get(headerName);
+                if (list == null) {
+                    list = new ArrayList<>();
+                }
+                list.add(header.getValue());
+                headers.put(headerName, list);
+            }
+
+            final HttpEntity entity = response.getEntity();
+
+            if (entity != null) {
+                if (headers.get(HttpHeaders.CONTENT_LENGTH) == null) {
+                    headers.add(HttpHeaders.CONTENT_LENGTH, String.valueOf(entity.getContentLength()));
+                }
+
+                final String contentEncoding = entity.getContentEncoding();
+                if (headers.get(HttpHeaders.CONTENT_ENCODING) == null && contentEncoding != null && !contentEncoding.isEmpty()) {
+                    headers.add(HttpHeaders.CONTENT_ENCODING, contentEncoding);
+                }
+            }
+
+            try {
+                final ConnectionClosingMechanism closingMechanism = new ConnectionClosingMechanism(clientRequest, request);
+                responseContext.setEntityStream(getInputStream(response, closingMechanism));
+            } catch (final IOException e) {
+                LOGGER.log(Level.SEVERE, null, e);
+            }
+
+            return responseContext;
+        } catch (final Exception e) {
+            throw new ProcessingException(e);
+        }
+    }
+
+    @Override
+    public Future<?> apply(final ClientRequest request, final AsyncConnectorCallback callback) {
+        try {
+            ClientResponse response = apply(request);
+            callback.response(response);
+            return CompletableFuture.completedFuture(response);
+        } catch (Throwable t) {
+            callback.failure(t);
+            CompletableFuture<Object> future = new CompletableFuture<>();
+            future.completeExceptionally(t);
+            return future;
+        }
+    }
+
+    @Override
+    public String getName() {
+        return "Apache HttpClient " + release;
+    }
+
+    @Override
+    public void close() {
+        try {
+            client.close();
+        } catch (final IOException e) {
+            throw new ProcessingException(LocalizationMessages.FAILED_TO_STOP_CLIENT(), e);
+        }
+    }
+
+    private HttpHost getHost(final HttpUriRequest request) throws URISyntaxException {
+        return new HttpHost(request.getUri().getScheme(), request.getUri().getHost(), request.getUri().getPort());
+    }
+
+    private HttpUriRequest getUriHttpRequest(final ClientRequest clientRequest) {
+        final RequestConfig.Builder requestConfigBuilder = RequestConfig.copy(requestConfig);
+
+        final int connectTimeout = clientRequest.resolveProperty(ClientProperties.CONNECT_TIMEOUT, -1);
+        final int socketTimeout = clientRequest.resolveProperty(ClientProperties.READ_TIMEOUT, -1);
+
+        if (connectTimeout >= 0) {
+            requestConfigBuilder.setConnectTimeout(Timeout.ofMilliseconds(connectTimeout));
+        }
+        if (socketTimeout >= 0) {
+            requestConfigBuilder.setResponseTimeout(Timeout.ofMilliseconds(socketTimeout));
+        }
+
+        final Boolean redirectsEnabled =
+                clientRequest.resolveProperty(ClientProperties.FOLLOW_REDIRECTS, requestConfig.isRedirectsEnabled());
+        requestConfigBuilder.setRedirectsEnabled(redirectsEnabled);
+
+        final Boolean bufferingEnabled = clientRequest.resolveProperty(ClientProperties.REQUEST_ENTITY_PROCESSING,
+                RequestEntityProcessing.class) == RequestEntityProcessing.BUFFERED;
+        final HttpEntity entity = getHttpEntity(clientRequest, bufferingEnabled);
+
+        HttpUriRequestBase httpUriRequestBase = new HttpUriRequestBase(clientRequest.getMethod(), clientRequest.getUri());
+        httpUriRequestBase.setConfig(requestConfigBuilder.build());
+        httpUriRequestBase.setEntity(entity);
+
+        return httpUriRequestBase;
+    }
+
+    private HttpEntity getHttpEntity(final ClientRequest clientRequest, final boolean bufferingEnabled) {
+        final Object entity = clientRequest.getEntity();
+
+        if (entity == null) {
+            return null;
+        }
+
+        if (HttpEntity.class.isInstance(entity)) {
+            return wrapHttpEntity(clientRequest, (HttpEntity) entity);
+        }
+
+        String contentType = clientRequest.getHeaderString(HttpHeaders.CONTENT_TYPE);
+        String contentEncoding = clientRequest.getHeaderString(HttpHeaders.CONTENT_ENCODING);
+
+        final AbstractHttpEntity httpEntity = new AbstractHttpEntity(contentType, contentEncoding) {
+            @Override
+            public void close() throws IOException {
+
+            }
+
+            @Override
+            public boolean isRepeatable() {
+                return false;
+            }
+
+            @Override
+            public long getContentLength() {
+                return -1;
+            }
+
+            @Override
+            public InputStream getContent() throws IOException, IllegalStateException {
+                if (bufferingEnabled) {
+                    final ByteArrayOutputStream buffer = new ByteArrayOutputStream(512);
+                    writeTo(buffer);
+                    return new ByteArrayInputStream(buffer.toByteArray());
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public void writeTo(final OutputStream outputStream) throws IOException {
+                clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {
+                    @Override
+                    public OutputStream getOutputStream(final int contentLength) throws IOException {
+                        return outputStream;
+                    }
+                });
+                clientRequest.writeEntity();
+            }
+
+            @Override
+            public boolean isStreaming() {
+                return false;
+            }
+        };
+
+        return bufferEntity(httpEntity, bufferingEnabled);
+    }
+
+    private HttpEntity wrapHttpEntity(final ClientRequest clientRequest, final HttpEntity originalEntity) {
+        final boolean bufferingEnabled = BufferedHttpEntity.class.isInstance(originalEntity);
+
+        try {
+            clientRequest.setEntity(originalEntity.getContent());
+        } catch (IOException e) {
+            throw new ProcessingException(LocalizationMessages.ERROR_READING_HTTPENTITY_STREAM(e.getMessage()), e);
+        }
+
+        final AbstractHttpEntity httpEntity = new AbstractHttpEntity(
+                originalEntity.getContentType(),
+                originalEntity.getContentEncoding(),
+                originalEntity.isChunked()
+        ) {
+            @Override
+            public void close() throws IOException {
+
+            }
+
+            @Override
+            public boolean isRepeatable() {
+                return originalEntity.isRepeatable();
+            }
+
+            @Override
+            public long getContentLength() {
+                return originalEntity.getContentLength();
+            }
+
+            @Override
+            public InputStream getContent() throws IOException, IllegalStateException {
+               return originalEntity.getContent();
+            }
+
+            @Override
+            public void writeTo(final OutputStream outputStream) throws IOException {
+                clientRequest.setStreamProvider(new OutboundMessageContext.StreamProvider() {
+                    @Override
+                    public OutputStream getOutputStream(final int contentLength) throws IOException {
+                        return outputStream;
+                    }
+                });
+                clientRequest.writeEntity();
+            }
+
+            @Override
+            public boolean isStreaming() {
+                return originalEntity.isStreaming();
+            }
+        };
+
+        return bufferEntity(httpEntity, bufferingEnabled);
+    }
+
+    private static HttpEntity bufferEntity(HttpEntity httpEntity, boolean bufferingEnabled) {
+        if (bufferingEnabled) {
+            try {
+                return new BufferedHttpEntity(httpEntity);
+            } catch (final IOException e) {
+                throw new ProcessingException(LocalizationMessages.ERROR_BUFFERING_ENTITY(), e);
+            }
+        } else {
+            return httpEntity;
+        }
+    }
+
+    private static Map<String, String> writeOutBoundHeaders(final ClientRequest clientRequest,
+                                                            final HttpUriRequest request) {
+        final Map<String, String> stringHeaders =
+                HeaderUtils.asStringHeadersSingleValue(clientRequest.getHeaders(), clientRequest.getConfiguration());
+
+        for (final Map.Entry<String, String> e : stringHeaders.entrySet()) {
+            request.addHeader(e.getKey(), e.getValue());
+        }
+        return stringHeaders;
+    }
+
+    private static InputStream getInputStream(final CloseableHttpResponse response,
+                                              final ConnectionClosingMechanism closingMechanism) throws IOException {
+        final InputStream inputStream;
+
+        if (response.getEntity() == null) {
+            inputStream = new ByteArrayInputStream(new byte[0]);
+        } else {
+            final InputStream i = response.getEntity().getContent();
+            if (i.markSupported()) {
+                inputStream = i;
+            } else {
+                inputStream = new BufferedInputStream(i, ReaderWriter.BUFFER_SIZE);
+            }
+        }
+
+        return closingMechanism.getEntityStream(inputStream, response);
+    }
+
+    /**
+     * The way the Apache CloseableHttpResponse is to be closed.
+     * See https://github.com/eclipse-ee4j/jersey/issues/4321
+     * {@link Apache5ClientProperties#CONNECTION_CLOSING_STRATEGY}
+     */
+    private final class ConnectionClosingMechanism {
+        private Apache5ConnectionClosingStrategy connectionClosingStrategy = null;
+        private final ClientRequest clientRequest;
+        private final HttpUriRequest apacheRequest;
+
+        private ConnectionClosingMechanism(ClientRequest clientRequest, HttpUriRequest apacheRequest) {
+            this.clientRequest = clientRequest;
+            this.apacheRequest = apacheRequest;
+            Object closingStrategyProperty = clientRequest
+                    .resolveProperty(Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY, Object.class);
+            if (closingStrategyProperty != null) {
+                if (Apache5ConnectionClosingStrategy.class.isInstance(closingStrategyProperty)) {
+                    connectionClosingStrategy = (Apache5ConnectionClosingStrategy) closingStrategyProperty;
+                } else {
+                    LOGGER.log(
+                            Level.WARNING,
+                            LocalizationMessages.IGNORING_VALUE_OF_PROPERTY(
+                                    Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY,
+                                    closingStrategyProperty,
+                                    Apache5ConnectionClosingStrategy.class.getName())
+                    );
+                }
+            }
+
+            if (connectionClosingStrategy == null) {
+                connectionClosingStrategy = Apache5ConnectionClosingStrategy.Apache5GracefulClosingStrategy.INSTANCE;
+            }
+        }
+
+        private InputStream getEntityStream(final InputStream inputStream,
+                                            final CloseableHttpResponse response) {
+            InputStream filterStream = new FilterInputStream(inputStream) {
+                @Override
+                public void close() throws IOException {
+                    connectionClosingStrategy.close(clientRequest, apacheRequest, response, in);
+                }
+            };
+            return filterStream;
+        }
+    }
+
+    private static class ConnectionFactory extends ManagedHttpClientConnectionFactory {
+        private ConnectionFactory(final int chunkSize) {
+            super(
+                    Http1Config.custom().setChunkSizeHint(chunkSize).build(),
+                    null,
+                    null,
+                    null,
+                    DefaultContentLengthStrategy.INSTANCE,
+                    DefaultContentLengthStrategy.INSTANCE
+            );
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectorProvider.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectorProvider.java
new file mode 100644
index 0000000..a5a5ffd
--- /dev/null
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ConnectorProvider.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.core.Configurable;
+import jakarta.ws.rs.core.Configuration;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.apache.hc.client5.http.cookie.CookieStore;
+import org.glassfish.jersey.client.Initializable;
+import org.glassfish.jersey.client.spi.Connector;
+import org.glassfish.jersey.client.spi.ConnectorProvider;
+
+/**
+ * Connector provider for Jersey {@link Connector connectors} that utilize
+ * Apache HTTP Client to send and receive HTTP request and responses.
+ * <p>
+ * The following connector configuration properties are supported:
+ * <ul>
+ * <li>{@link Apache5ClientProperties#CONNECTION_CLOSING_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#CONNECTION_MANAGER}</li>
+ * <li>{@link Apache5ClientProperties#CONNECTION_MANAGER_SHARED}</li>
+ * <li>{@link Apache5ClientProperties#DISABLE_COOKIES}</li>
+ * <li>{@link Apache5ClientProperties#CREDENTIALS_PROVIDER}</li>
+ * <li>{@link Apache5ClientProperties#KEEPALIVE_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_URI}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING}
+ * - default value is {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED}</li>
+ * <li>{@link Apache5ClientProperties#REQUEST_CONFIG}</li>
+ * <li>{@link Apache5ClientProperties#RETRY_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#REUSE_STRATEGY}</li>
+ * <li>{@link Apache5ClientProperties#USE_SYSTEM_PROPERTIES}</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Connector instances created via this connector provider use
+ * {@link org.glassfish.jersey.client.RequestEntityProcessing#CHUNKED chunked encoding} as a default setting.
+ * This can be overridden by the {@link org.glassfish.jersey.client.ClientProperties#REQUEST_ENTITY_PROCESSING}.
+ * By default the {@link org.glassfish.jersey.client.ClientProperties#CHUNKED_ENCODING_SIZE} property is only supported
+ * when using the default {@link org.apache.hc.core5.http.io.HttpClientConnection} instance. If custom
+ * connection manager is used, then chunked encoding size can be set by providing a custom
+ * {@link org.apache.hc.core5.http.io.HttpClientConnection} (via custom {@link org.apache.hc.client5.http.impl.io.ManagedHttpClientConnectionFactory})
+ * and overriding it's {@code createOutputStream} method.
+ * </p>
+ * <p>
+ * Use of authorization by the AHC-based connectors is dependent on the chunk encoding setting.
+ * If the entity buffering is enabled, the entity is buffered and authorization can be performed
+ * automatically in response to a 401 by sending the request again. When entity buffering
+ * is disabled (chunked encoding is used) then the property
+ * {@link Apache5ClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION} must
+ * be set to {@code true}.
+ * </p>
+ * <p>
+ * If a {@link org.glassfish.jersey.client.ClientResponse} is obtained and an entity is not read from the response then
+ * {@link org.glassfish.jersey.client.ClientResponse#close()} MUST be called after processing the response to release
+ * connection-based resources.
+ * </p>
+ * <p>
+ * Registration of {@link Apache5HttpClientBuilderConfigurator} instance on the
+ * {@link jakarta.ws.rs.client.Client#register(Object) Client} is supported. A configuration provided by
+ * {@link Apache5HttpClientBuilderConfigurator} will override the {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder}
+ * configuration set by using the properties.
+ * </p>
+ * <p>
+ * If a response entity is obtained that is an instance of {@link java.io.Closeable}
+ * then the instance MUST be closed after processing the entity to release
+ * connection-based resources.
+ * <p/>
+ * <p>
+ * The following methods are currently supported: HEAD, GET, POST, PUT, DELETE, OPTIONS, PATCH and TRACE.
+ * <p/>
+ *
+ * @author Pavel Bucek
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author jorgeluisw at mac.com
+ * @author Marek Potociar
+ * @author Paul Sandoz
+ * @author Maksim Mukosey (mmukosey at gmail.com)
+ * @since 2.5
+ */
+public class Apache5ConnectorProvider implements ConnectorProvider {
+
+    @Override
+    public Connector getConnector(final Client client, final Configuration runtimeConfig) {
+        return new Apache5Connector(client, runtimeConfig);
+    }
+
+    /**
+     * Retrieve the underlying Apache {@link org.apache.hc.client5.http.classic.HttpClient} instance from
+     * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
+     * configured to use {@code ApacheConnectorProvider}.
+     *
+     * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
+     *                  {@code ApacheConnectorProvider}.
+     * @return underlying Apache {@code HttpClient} instance.
+     *
+     * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
+     *                                            nor {@code JerseyWebTarget} instance or in case the component
+     *                                            is not configured to use a {@code ApacheConnectorProvider}.
+     * @since 2.8
+     */
+    public static HttpClient getHttpClient(final Configurable<?> component) {
+        return getConnector(component).getHttpClient();
+    }
+
+    /**
+     * Retrieve the underlying Apache {@link CookieStore} instance from
+     * {@link org.glassfish.jersey.client.JerseyClient} or {@link org.glassfish.jersey.client.JerseyWebTarget}
+     * configured to use {@code ApacheConnectorProvider}.
+     *
+     * @param component {@code JerseyClient} or {@code JerseyWebTarget} instance that is configured to use
+     *                  {@code ApacheConnectorProvider}.
+     * @return underlying Apache {@code CookieStore} instance.
+     * @throws java.lang.IllegalArgumentException in case the {@code component} is neither {@code JerseyClient}
+     *                                            nor {@code JerseyWebTarget} instance or in case the component
+     *                                            is not configured to use a {@code ApacheConnectorProvider}.
+     * @since 2.16
+     */
+    public static CookieStore getCookieStore(final Configurable<?> component) {
+        return getConnector(component).getCookieStore();
+    }
+
+    private static Apache5Connector getConnector(final Configurable<?> component) {
+        if (!(component instanceof Initializable)) {
+            throw new IllegalArgumentException(
+                    LocalizationMessages.INVALID_CONFIGURABLE_COMPONENT_TYPE(component.getClass().getName()));
+        }
+
+        final Initializable<?> initializable = (Initializable<?>) component;
+        Connector connector = initializable.getConfiguration().getConnector();
+        if (connector == null) {
+            initializable.preInitialize();
+            connector = initializable.getConfiguration().getConnector();
+        }
+
+        if (connector instanceof Apache5Connector) {
+            return (Apache5Connector) connector;
+        } else {
+            throw new IllegalArgumentException(LocalizationMessages.EXPECTED_CONNECTOR_PROVIDER_NOT_USED());
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5HttpClientBuilderConfigurator.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5HttpClientBuilderConfigurator.java
new file mode 100644
index 0000000..d179f5c
--- /dev/null
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5HttpClientBuilderConfigurator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
+import org.glassfish.jersey.spi.Contract;
+
+/**
+ * A callback interface used to configure {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder}. It is called immediately before
+ * the {@link Apache5ConnectorProvider} creates {@link org.apache.hc.client5.http.classic.HttpClient}, after the
+ * {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder} is configured using the properties.
+ */
+@Contract
+public interface Apache5HttpClientBuilderConfigurator {
+    /**
+     * A callback method to configure the {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder}
+     * @param httpClientBuilder {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder} object to be further configured
+     * @return the configured {@link org.apache.hc.client5.http.impl.classic.HttpClientBuilder}. If {@code null} is returned the
+     * {@code httpClientBuilder} is used by {@link Apache5ConnectorProvider} instead.
+     */
+    HttpClientBuilder configure(HttpClientBuilder httpClientBuilder);
+}
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/package-info.java
similarity index 72%
copy from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
copy to connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/package-info.java
index e15b2c5..0b05d4b 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
+++ b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2022 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
@@ -15,7 +15,7 @@
  */
 
 /**
- * Jersey server-side Spring 4 integration injection scopes related classes.
- *
+ * Jersey client {@link org.glassfish.jersey.client.spi.Connector connector} based on the
+ * Apache Http Client.
  */
-package org.glassfish.jersey.server.spring.scope;
+package org.glassfish.jersey.apache5.connector;
diff --git a/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties b/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties
new file mode 100644
index 0000000..16dbc30
--- /dev/null
+++ b/connectors/apache5-connector/src/main/resources/org/glassfish/jersey/apache5/connector/localization.properties
@@ -0,0 +1,25 @@
+#
+# Copyright (c) 2022 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
+#
+
+error.buffering.entity=Error buffering the entity.
+error.reading.httpentity.stream=Error reading InputStream from HttpEntity: "{0}"
+failed.to.stop.client=Failed to stop the client.
+# {0} - property name, e.g. jersey.config.client.httpclient.connectionManager; {1}, {2} - full class name
+ignoring.value.of.property=Ignoring value of property "{0}" ("{1}") - not instance of "{2}".
+# {0} - property name - jersey.config.client.httpclient.proxyUri
+wrong.proxy.uri.type=The proxy URI ("{0}") property MUST be an instance of String or URI.
+invalid.configurable.component.type=The supplied component "{0}" is not assignable from JerseyClient or JerseyWebTarget.
+expected.connector.provider.not.used=The supplied component is not configured to use a ApacheConnectorProvider.
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AsyncTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AsyncTest.java
new file mode 100644
index 0000000..88edc8a
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AsyncTest.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.container.AsyncResponse;
+import jakarta.ws.rs.container.Suspended;
+import jakarta.ws.rs.container.TimeoutHandler;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.hamcrest.Matchers;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Asynchronous connector test.
+ *
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
+public class AsyncTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(AsyncTest.class.getName());
+    private static final String PATH = "async";
+
+    /**
+     * Asynchronous test resource.
+     */
+    @Path(PATH)
+    public static class AsyncResource {
+        /**
+         * Typical long-running operation duration.
+         */
+        public static final long OPERATION_DURATION = 1000;
+
+        /**
+         * Long-running asynchronous post.
+         *
+         * @param asyncResponse async response.
+         * @param id            post request id (received as request payload).
+         */
+        @POST
+        public void asyncPost(@Suspended final AsyncResponse asyncResponse, final String id) {
+            LOGGER.info("Long running post operation called with id " + id + " on thread " + Thread.currentThread().getName());
+            new Thread(new Runnable() {
+
+                @Override
+                public void run() {
+                    String result = veryExpensiveOperation();
+                    asyncResponse.resume(result);
+                }
+
+                private String veryExpensiveOperation() {
+                    // ... very expensive operation that typically finishes within 1 seconds, simulated using sleep()
+                    try {
+                        Thread.sleep(OPERATION_DURATION);
+                        return "DONE-" + id;
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                        return "INTERRUPTED-" + id;
+                    } finally {
+                        LOGGER.info("Long running post operation finished on thread " + Thread.currentThread().getName());
+                    }
+                }
+            }, "async-post-runner-" + id).start();
+        }
+
+        /**
+         * Long-running async get request that times out.
+         *
+         * @param asyncResponse async response.
+         */
+        @GET
+        @Path("timeout")
+        public void asyncGetWithTimeout(@Suspended final AsyncResponse asyncResponse) {
+            LOGGER.info("Async long-running get with timeout called on thread " + Thread.currentThread().getName());
+            asyncResponse.setTimeoutHandler(new TimeoutHandler() {
+
+                @Override
+                public void handleTimeout(AsyncResponse asyncResponse) {
+                    asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE)
+                            .entity("Operation time out.").build());
+                }
+            });
+            asyncResponse.setTimeout(1, TimeUnit.SECONDS);
+
+            new Thread(new Runnable() {
+
+                @Override
+                public void run() {
+                    String result = veryExpensiveOperation();
+                    asyncResponse.resume(result);
+                }
+
+                private String veryExpensiveOperation() {
+                    // very expensive operation that typically finishes within 1 second but can take up to 5 seconds,
+                    // simulated using sleep()
+                    try {
+                        Thread.sleep(5 * OPERATION_DURATION);
+                        return "DONE";
+                    } catch (InterruptedException e) {
+                        Thread.currentThread().interrupt();
+                        return "INTERRUPTED";
+                    } finally {
+                        LOGGER.info("Async long-running get with timeout finished on thread " + Thread.currentThread().getName());
+                    }
+                }
+            }).start();
+        }
+
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(AsyncResource.class)
+                .register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    /**
+     * Test asynchronous POST.
+     *
+     * Send 3 async POST requests and wait to receive the responses. Check the response content and
+     * assert that the operation did not take more than twice as long as a single long operation duration
+     * (this ensures async request execution).
+     *
+     * @throws Exception in case of a test error.
+     */
+    @Test
+    public void testAsyncPost() throws Exception {
+        final long tic = System.currentTimeMillis();
+
+        // Submit requests asynchronously.
+        final Future<Response> rf1 = target(PATH).request().async().post(Entity.text("1"));
+        final Future<Response> rf2 = target(PATH).request().async().post(Entity.text("2"));
+        final Future<Response> rf3 = target(PATH).request().async().post(Entity.text("3"));
+        // get() waits for the response
+
+        // workaround for AHC default connection manager limitation of
+        // only 2 open connections per host that may intermittently block
+        // the test
+        final CountDownLatch latch = new CountDownLatch(3);
+        ExecutorService executor = Executors.newFixedThreadPool(3);
+
+        final Future<String> r1 = executor.submit(new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                try {
+                    return rf1.get().readEntity(String.class);
+                } finally {
+                    latch.countDown();
+                }
+            }
+        });
+        final Future<String> r2 = executor.submit(new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                try {
+                    return rf2.get().readEntity(String.class);
+                } finally {
+                    latch.countDown();
+                }
+            }
+        });
+        final Future<String> r3 = executor.submit(new Callable<String>() {
+            @Override
+            public String call() throws Exception {
+                try {
+                    return rf3.get().readEntity(String.class);
+                } finally {
+                    latch.countDown();
+                }
+            }
+        });
+
+        assertTrue("Waiting for results has timed out.", latch.await(5 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS));
+        final long toc = System.currentTimeMillis();
+
+        assertEquals("DONE-1", r1.get());
+        assertEquals("DONE-2", r2.get());
+        assertEquals("DONE-3", r3.get());
+
+        final int asyncTimeoutMultiplier = getAsyncTimeoutMultiplier();
+        LOGGER.info("Using async timeout multiplier: " + asyncTimeoutMultiplier);
+        assertThat("Async processing took too long.", toc - tic, Matchers.lessThan(4 * AsyncResource.OPERATION_DURATION
+                * asyncTimeoutMultiplier));
+
+    }
+
+    /**
+     * Test accessing an operation that times out on the server.
+     *
+     * @throws Exception in case of a test error.
+     */
+    @Test
+    public void testAsyncGetWithTimeout() throws Exception {
+        final Future<Response> responseFuture = target(PATH).path("timeout").request().async().get();
+        // Request is being processed asynchronously.
+        final Response response = responseFuture.get();
+
+        // get() waits for the response
+        assertEquals(503, response.getStatus());
+        assertEquals("Operation time out.", response.readEntity(String.class));
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AuthTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AuthTest.java
new file mode 100644
index 0000000..c39b7d1
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/AuthTest.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+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.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriInfo;
+
+import jakarta.inject.Singleton;
+
+import org.apache.hc.client5.http.auth.AuthScope;
+import org.apache.hc.client5.http.auth.CredentialsStore;
+import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
+import org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
+import org.glassfish.jersey.client.authentication.ResponseAuthenticationException;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class AuthTest extends JerseyTest {
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(PreemptiveAuthResource.class, AuthResource.class);
+    }
+
+    @Path("/")
+    public static class PreemptiveAuthResource {
+
+        @GET
+        public String get(@Context HttpHeaders h) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            assertNotNull(value);
+            return "GET";
+        }
+
+        @POST
+        public String post(@Context HttpHeaders h, String e) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            assertNotNull(value);
+            return e;
+        }
+    }
+
+    @Test
+    public void testPreemptiveAuth() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider)
+                .property(Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION, true);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri());
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testPreemptiveAuthPost() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider)
+                .property(Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION, true);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri());
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+    }
+
+    @Path("/test")
+    @Singleton
+    public static class AuthResource {
+
+        int requestCount = 0;
+        int queryParamsBasicRequestCount = 0;
+        int queryParamsDigestRequestCount = 0;
+
+        @GET
+        public String get(@Context HttpHeaders h) {
+            requestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                assertEquals(1, requestCount);
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            } else {
+                assertTrue(requestCount > 1);
+            }
+
+            return "GET";
+        }
+
+        @GET
+        @Path("filter")
+        public String getFilter(@Context HttpHeaders h) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            }
+
+            return "GET";
+        }
+
+        @GET
+        @Path("basicAndDigest")
+        public String getBasicAndDigest(@Context HttpHeaders h) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"")
+                            .header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
+                            .entity("Forbidden").build());
+            } else if (value.startsWith("Basic")) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"")
+                            .header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
+                            .entity("Digest authentication expected").build());
+            }
+
+            return "GET";
+        }
+
+        @GET
+        @Path("noauth")
+        public String get() {
+            return "GET";
+        }
+
+        @GET
+        @Path("digest")
+        public String getDigest(@Context HttpHeaders h) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Digest realm=\"WallyWorld\"")
+                            .entity("Forbidden").build());
+            }
+
+            return "GET";
+        }
+
+        @POST
+        public String post(@Context HttpHeaders h, String e) {
+            requestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                assertEquals(1, requestCount);
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            } else {
+                assertTrue(requestCount > 1);
+            }
+
+            return e;
+        }
+
+        @POST
+        @Path("filter")
+        public String postFilter(@Context HttpHeaders h, String e) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            }
+
+            return e;
+        }
+
+        @DELETE
+        public void delete(@Context HttpHeaders h) {
+            requestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                assertEquals(1, requestCount);
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            } else {
+                assertTrue(requestCount > 1);
+            }
+        }
+
+        @DELETE
+        @Path("filter")
+        public void deleteFilter(@Context HttpHeaders h) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            }
+        }
+
+        @DELETE
+        @Path("filter/withEntity")
+        public String deleteFilterWithEntity(@Context HttpHeaders h, String e) {
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            }
+
+            return e;
+        }
+
+        @GET
+        @Path("content")
+        public String getWithContent(@Context HttpHeaders h) {
+            requestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                assertEquals(1, requestCount);
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"")
+                            .entity("Forbidden").build());
+            } else {
+                assertTrue(requestCount > 1);
+            }
+
+            return "GET";
+        }
+
+        @GET
+        @Path("contentDigestAuth")
+        public String getWithContentDigestAuth(@Context HttpHeaders h) {
+            requestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                assertEquals(1, requestCount);
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Digest nonce=\"1234\"")
+                            .entity("Forbidden").build());
+            } else {
+                assertTrue(requestCount > 1);
+            }
+
+            return "GET";
+        }
+
+        @GET
+        @Path("queryParamsBasic")
+        public String getQueryParamsBasic(@Context HttpHeaders h, @Context UriInfo uriDetails) {
+            queryParamsBasicRequestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Basic realm=\"WallyWorld\"").build());
+            }
+            return "GET " + queryParamsBasicRequestCount;
+        }
+
+        @GET
+        @Path("queryParamsDigest")
+        public String getQueryParamsDigest(@Context HttpHeaders h, @Context UriInfo uriDetails) {
+            queryParamsDigestRequestCount++;
+            String value = h.getRequestHeaders().getFirst("Authorization");
+            if (value == null) {
+                throw new WebApplicationException(
+                        Response.status(401).header("WWW-Authenticate", "Digest realm=\"WallyWorld\"").build());
+            }
+            return "GET " + queryParamsDigestRequestCount;
+        }
+    }
+
+    @Test
+    public void testAuthGet() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testAuthGetWithRequestCredentialsProvider() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("GET",
+                     r.request()
+                      .property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider)
+                      .get(String.class));
+    }
+
+    @Test
+    public void testAuthGetWithClientFilter() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.basic("name", "password"));
+        WebTarget r = client.target(getBaseUri()).path("test/filter");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testAuthGetWithBasicAndDigestFilter() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universal("name", "password"));
+        WebTarget r = client.target(getBaseUri()).path("test/basicAndDigest");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testAuthGetBasicNoChallenge() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.basicBuilder().build());
+        WebTarget r = client.target(getBaseUri()).path("test/noauth");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testAuthGetWithDigestFilter() {
+        ClientConfig cc = new ClientConfig();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, cm);
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universal("name", "password"));
+        WebTarget r = client.target(getBaseUri()).path("test/digest");
+
+        assertEquals("GET", r.request().get(String.class));
+
+        // Verify the connection that was used for the request is available for reuse
+        // and no connections are leased
+        assertEquals(cm.getTotalStats().getAvailable(), 1);
+        assertEquals(cm.getTotalStats().getLeased(), 0);
+    }
+
+    @Test
+    @Ignore("JERSEY-1750: Cannot retry request with a non-repeatable request entity. How to buffer the entity?"
+            + " Allow repeatable write in jersey?")
+    public void testAuthPost() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+    }
+
+    @Test
+    public void testAuthPostWithClientFilter() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.basic("name", "password"));
+        WebTarget r = client.target(getBaseUri()).path("test/filter");
+
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+    }
+
+    @Test
+    public void testAuthDelete() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        Response response = r.request().delete();
+        assertEquals(response.getStatus(), 204);
+    }
+
+    @Test
+    public void testAuthDeleteWithClientFilter() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.basic("name", "password"));
+        WebTarget r = client.target(getBaseUri()).path("test/filter");
+
+        Response response = r.request().delete();
+        assertEquals(204, response.getStatus());
+    }
+
+    @Test
+    public void testAuthInteractiveGet() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    @Ignore("JERSEY-1750: Cannot retry request with a non-repeatable request entity. How to buffer the entity?"
+            + " Allow repeatable write in jersey?")
+    public void testAuthInteractivePost() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CREDENTIALS_PROVIDER, credentialsProvider);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+    }
+
+    @Test
+    public void testAuthGetWithBasicFilterAndContent() {
+        ClientConfig cc = new ClientConfig();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, cm);
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universalBuilder().build());
+        WebTarget r = client.target(getBaseUri()).path("test/content");
+
+        try {
+            assertEquals("GET", r.request().get(String.class));
+            fail();
+        } catch (ResponseAuthenticationException ex) {
+            // expected
+        }
+
+        // Verify the connection that was used for the request is available for reuse
+        // and no connections are leased
+        assertEquals(cm.getTotalStats().getAvailable(), 1);
+        assertEquals(cm.getTotalStats().getLeased(), 0);
+    }
+
+    @Test
+    public void testAuthGetWithDigestFilterAndContent() {
+        ClientConfig cc = new ClientConfig();
+        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, cm);
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universalBuilder().build());
+        WebTarget r = client.target(getBaseUri()).path("test/contentDigestAuth");
+
+        try {
+            assertEquals("GET", r.request().get(String.class));
+            fail();
+        } catch (ResponseAuthenticationException ex) {
+            // expected
+        }
+
+        // Verify the connection that was used for the request is available for reuse
+        // and no connections are leased
+        assertEquals(cm.getTotalStats().getAvailable(), 1);
+        assertEquals(cm.getTotalStats().getLeased(), 0);
+    }
+
+    @Test
+    public void testAuthGetQueryParamsBasic() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universal("name", "password"));
+
+        WebTarget r = client.target(getBaseUri()).path("test/queryParamsBasic");
+        assertEquals("GET 2", r.request().get(String.class));
+
+        r = client.target(getBaseUri())
+                .path("test/queryParamsBasic")
+                .queryParam("param1", "value1")
+                .queryParam("param2", "value2");
+        assertEquals("GET 3", r.request().get(String.class));
+
+    }
+
+    @Test
+    public void testAuthGetQueryParamsDigest() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        client.register(HttpAuthenticationFeature.universal("name", "password"));
+
+        WebTarget r = client.target(getBaseUri()).path("test/queryParamsDigest");
+        assertEquals("GET 2", r.request().get(String.class));
+
+        r = client.target(getBaseUri())
+                .path("test/queryParamsDigest")
+                .queryParam("param1", "value1")
+                .queryParam("param2", "value2");
+        assertEquals("GET 3", r.request().get(String.class));
+    }
+
+    @Test
+    public void testAuthGetWithConfigurator() {
+        CredentialsStore credentialsProvider = new BasicCredentialsProvider();
+        credentialsProvider.setCredentials(
+                new AuthScope("localhost", getPort()),
+                new UsernamePasswordCredentials("name", "password".toCharArray())
+        );
+        Apache5HttpClientBuilderConfigurator apache5HttpClientBuilderConfigurator = (httpClientBuilder) -> {
+            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+        };
+
+        ClientConfig cc = new ClientConfig();
+        cc.register(apache5HttpClientBuilderConfigurator);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri()).path("test");
+
+        assertEquals("GET", r.request().get(String.class));
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CookieTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CookieTest.java
new file mode 100644
index 0000000..a5ffbed
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CookieTest.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.Cookie;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.NewCookie;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.JerseyClient;
+import org.glassfish.jersey.client.JerseyClientBuilder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class CookieTest extends JerseyTest {
+
+    @Path("/")
+    public static class CookieResource {
+
+        @GET
+        public Response get(@Context HttpHeaders h) {
+            Cookie c = h.getCookies().get("name");
+            String e = (c == null) ? "NO-COOKIE" : c.getValue();
+            return Response.ok(e)
+                    .cookie(new NewCookie("name", "value")).build();
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(CookieResource.class);
+    }
+
+    @Test
+    public void testCookieResource() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("value", r.request().get(String.class));
+    }
+
+    @Test
+    public void testDisabledCookies() {
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.DISABLE_COOKIES, true);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        JerseyClient client = JerseyClientBuilder.createClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+
+        final Apache5Connector connector = (Apache5Connector) client.getConfiguration().getConnector();
+        if (connector.getCookieStore() != null) {
+            assertTrue(connector.getCookieStore().getCookies().isEmpty());
+        } else {
+            assertNull(connector.getCookieStore());
+        }
+    }
+
+    @Test
+    public void testCookies() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        JerseyClient client = JerseyClientBuilder.createClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        assertEquals("NO-COOKIE", r.request().get(String.class));
+        assertEquals("value", r.request().get(String.class));
+
+        final Apache5Connector connector = (Apache5Connector) client.getConfiguration().getConnector();
+        assertNotNull(connector.getCookieStore().getCookies());
+        assertEquals(1, connector.getCookieStore().getCookies().size());
+        assertEquals("value", connector.getCookieStore().getCookies().get(0).getValue());
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CustomLoggingFilter.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CustomLoggingFilter.java
new file mode 100644
index 0000000..8a32278
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/CustomLoggingFilter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.ClientResponseContext;
+import jakarta.ws.rs.client.ClientResponseFilter;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Custom logging filter.
+ *
+ * @author Santiago Pericas-Geertsen (santiago.pericasgeertsen at oracle.com)
+ */
+public class CustomLoggingFilter implements ContainerRequestFilter, ContainerResponseFilter,
+        ClientRequestFilter, ClientResponseFilter {
+
+    static int preFilterCalled = 0;
+    static int postFilterCalled = 0;
+
+    @Override
+    public void filter(ClientRequestContext context) throws IOException {
+        System.out.println("CustomLoggingFilter.preFilter called");
+        assertEquals(context.getConfiguration().getProperty("foo"), "bar");
+        preFilterCalled++;
+    }
+
+    @Override
+    public void filter(ClientRequestContext context, ClientResponseContext clientResponseContext) throws IOException {
+        System.out.println("CustomLoggingFilter.postFilter called");
+        assertEquals(context.getConfiguration().getProperty("foo"), "bar");
+        postFilterCalled++;
+    }
+
+    @Override
+    public void filter(ContainerRequestContext context) throws IOException {
+        System.out.println("CustomLoggingFilter.preFilter called");
+        assertEquals(context.getProperty("foo"), "bar");
+        preFilterCalled++;
+    }
+
+    @Override
+    public void filter(ContainerRequestContext context, ContainerResponseContext containerResponseContext) throws IOException {
+        System.out.println("CustomLoggingFilter.postFilter called");
+        assertEquals(context.getProperty("foo"), "bar");
+        postFilterCalled++;
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/DisableContentEncodingTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/DisableContentEncodingTest.java
new file mode 100644
index 0000000..f9d725a
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/DisableContentEncodingTest.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+
+import org.apache.hc.client5.http.config.RequestConfig;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Ondrej Kosatka
+ */
+public class DisableContentEncodingTest extends JerseyTest {
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(Resource.class);
+    }
+
+    @Path("/")
+    public static class Resource {
+
+        @GET
+        public String get(@HeaderParam("Accept-Encoding") String enc) {
+            return enc;
+        }
+    }
+
+    @Test
+    public void testDisabledByRequestConfig() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        final RequestConfig requestConfig = RequestConfig.custom().setContentCompressionEnabled(false).build();
+        cc.property(Apache5ClientProperties.REQUEST_CONFIG, requestConfig);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        String enc = r.request().get().readEntity(String.class);
+        assertEquals("", enc);
+    }
+
+    @Test
+    public void testEnabledByRequestConfig() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        final RequestConfig requestConfig = RequestConfig.custom().setContentCompressionEnabled(true).build();
+        cc.property(Apache5ClientProperties.REQUEST_CONFIG, requestConfig);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        String enc = r.request().get().readEntity(String.class);
+        assertEquals("gzip, x-gzip, deflate", enc);
+    }
+
+    @Test
+    public void testDefaultEncoding() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        String enc = r.request().get().readEntity(String.class);
+        assertEquals("gzip, x-gzip, deflate", enc);
+    }
+
+    @Test
+    public void testDefaultEncodingOverridden() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        String enc = r.request().acceptEncoding("gzip").get().readEntity(String.class);
+        assertEquals("gzip", enc);
+    }
+
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/FollowRedirectsTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/FollowRedirectsTest.java
new file mode 100644
index 0000000..ab1f655
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/FollowRedirectsTest.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+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.Application;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.UriBuilder;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.ClientResponse;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Apache connector follow redirect tests.
+ *
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ * @author Marek Potociar
+ */
+public class FollowRedirectsTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(TimeoutTest.class.getName());
+
+    @Path("/test")
+    public static class RedirectResource {
+        @GET
+        public String get() {
+            return "GET";
+        }
+
+        @GET
+        @Path("redirect")
+        public Response redirect() {
+            return Response.seeOther(UriBuilder.fromResource(RedirectResource.class).build()).build();
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(RedirectResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    private static class RedirectTestFilter implements ClientResponseFilter {
+        public static final String RESOLVED_URI_HEADER = "resolved-uri";
+
+        @Override
+        public void filter(ClientRequestContext requestContext, ClientResponseContext responseContext) throws IOException {
+            if (responseContext instanceof ClientResponse) {
+                ClientResponse clientResponse = (ClientResponse) responseContext;
+                responseContext.getHeaders().putSingle(RESOLVED_URI_HEADER, clientResponse.getResolvedRequestUri().toString());
+            }
+        }
+    }
+
+    @Test
+    public void testDoFollow() {
+        Response r = target("test/redirect").register(RedirectTestFilter.class).request().get();
+        assertEquals(200, r.getStatus());
+        assertEquals("GET", r.readEntity(String.class));
+        assertEquals(
+                UriBuilder.fromUri(getBaseUri()).path(RedirectResource.class).build().toString(),
+                r.getHeaderString(RedirectTestFilter.RESOLVED_URI_HEADER));
+    }
+
+    @Test
+    public void testDontFollow() {
+        WebTarget t = target("test/redirect");
+        t.property(ClientProperties.FOLLOW_REDIRECTS, false);
+        assertEquals(303, t.request().get().getStatus());
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/GZIPContentEncodingTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/GZIPContentEncodingTest.java
new file mode 100644
index 0000000..2ed3541
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/GZIPContentEncodingTest.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.util.Arrays;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class GZIPContentEncodingTest extends JerseyTest {
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(Resource.class);
+    }
+
+    @Path("/")
+    public static class Resource {
+
+        @POST
+        public byte[] post(byte[] content) {
+            return content;
+        }
+    }
+
+    @Test
+    public void testPost() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = client.target(getBaseUri());
+
+        byte[] content = new byte[1024 * 1024];
+        assertTrue(Arrays.equals(content,
+                r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE)).readEntity(byte[].class)));
+
+        Response cr = r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPostChunked() {
+        ClientConfig cc = new ClientConfig(GZipEncoder.class);
+        cc.property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri());
+
+        byte[] content = new byte[1024 * 1024];
+        assertTrue(Arrays.equals(content,
+                r.request().post(Entity.entity(content, MediaType.APPLICATION_OCTET_STREAM_TYPE)).readEntity(byte[].class)));
+
+        Response cr = r.request().post(Entity.text("POST"));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HelloWorldTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HelloWorldTest.java
new file mode 100644
index 0000000..3407cbe
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HelloWorldTest.java
@@ -0,0 +1,400 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.InternalServerErrorException;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.InvocationCallback;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+import org.apache.hc.client5.http.HttpRoute;
+import org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager;
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.apache.hc.client5.http.io.ConnectionEndpoint;
+import org.apache.hc.client5.http.io.HttpClientConnectionManager;
+import org.apache.hc.client5.http.io.LeaseRequest;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.util.TimeValue;
+import org.apache.hc.core5.util.Timeout;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Assert;
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Jakub Podlesak
+ */
+public class HelloWorldTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(HelloWorldTest.class.getName());
+    private static final String ROOT_PATH = "helloworld";
+
+    @Path("helloworld")
+    public static class HelloWorldResource {
+
+        public static final String CLICHED_MESSAGE = "Hello World!";
+
+        @GET
+        @Produces("text/plain")
+        public String getHello() {
+            return CLICHED_MESSAGE;
+        }
+
+        @GET
+        @Produces("text/plain")
+        @Path("error")
+        public Response getError() {
+            return Response.serverError().entity("Error.").build();
+        }
+
+        @GET
+        @Produces("text/plain")
+        @Path("error2")
+        public Response getError2() {
+            return Response.serverError().entity("Error2.").build();
+        }
+
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(HelloWorldResource.class);
+        config.register(new LoggingFeature(LOGGER, Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY,
+                LoggingFeature.DEFAULT_MAX_ENTITY_SIZE));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void testConnection() {
+        Response response = target().path(ROOT_PATH).request("text/plain").get();
+        assertEquals(200, response.getStatus());
+    }
+
+    @Test
+    public void testClientStringResponse() {
+        String s = target().path(ROOT_PATH).request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+    }
+
+    @Test
+    public void testConnectionPoolSharingEnabled() throws Exception {
+        _testConnectionPoolSharing(true);
+    }
+
+    @Test
+    public void testConnectionPoolSharingDisabled() throws Exception {
+        _testConnectionPoolSharing(false);
+    }
+
+    public void _testConnectionPoolSharing(final boolean sharingEnabled) throws Exception {
+
+        final HttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+
+        final ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, connectionManager);
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER_SHARED, sharingEnabled);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+
+        final Client clientOne = ClientBuilder.newClient(cc);
+        WebTarget target = clientOne.target(getBaseUri()).path(ROOT_PATH);
+        target.request().get();
+        clientOne.close();
+
+        final boolean exceptionExpected = !sharingEnabled;
+
+        final Client clientTwo = ClientBuilder.newClient(cc);
+        target = clientTwo.target(getBaseUri()).path(ROOT_PATH);
+        try {
+            target.request().get();
+            if (exceptionExpected) {
+                Assert.fail("Exception expected");
+            }
+        } catch (Exception e) {
+            if (!exceptionExpected) {
+                Assert.fail("Exception not expected");
+            }
+        } finally {
+            clientTwo.close();
+        }
+
+        if (sharingEnabled) {
+            connectionManager.close();
+        }
+    }
+
+    @Test
+    public void testAsyncClientRequests() throws InterruptedException {
+        HttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+        ClientConfig cc = new ClientConfig();
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, connectionManager);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget target = client.target(getBaseUri());
+        final int REQUESTS = 20;
+        final CountDownLatch latch = new CountDownLatch(REQUESTS);
+        final long tic = System.currentTimeMillis();
+        final Map<Integer, String> results = new ConcurrentHashMap<Integer, String>();
+        for (int i = 0; i < REQUESTS; i++) {
+            final int id = i;
+            target.path(ROOT_PATH).request().async().get(new InvocationCallback<Response>() {
+                @Override
+                public void completed(Response response) {
+                    try {
+                        final String result = response.readEntity(String.class);
+                        results.put(id, result);
+                    } finally {
+                        latch.countDown();
+                    }
+                }
+
+                @Override
+                public void failed(Throwable error) {
+                    Logger.getLogger(HelloWorldTest.class.getName()).log(Level.SEVERE, "Failed on throwable", error);
+                    results.put(id, "error: " + error.getMessage());
+                    latch.countDown();
+                }
+            });
+        }
+        assertTrue(latch.await(10 * getAsyncTimeoutMultiplier(), TimeUnit.SECONDS));
+        final long toc = System.currentTimeMillis();
+        Logger.getLogger(HelloWorldTest.class.getName()).info("Executed in: " + (toc - tic));
+
+        StringBuilder resultInfo = new StringBuilder("Results:\n");
+        for (int i = 0; i < REQUESTS; i++) {
+            String result = results.get(i);
+            resultInfo.append(i).append(": ").append(result).append('\n');
+        }
+        Logger.getLogger(HelloWorldTest.class.getName()).info(resultInfo.toString());
+
+        for (int i = 0; i < REQUESTS; i++) {
+            String result = results.get(i);
+            assertEquals(HelloWorldResource.CLICHED_MESSAGE, result);
+        }
+    }
+
+    @Test
+    public void testHead() {
+        Response response = target().path(ROOT_PATH).request().head();
+        assertEquals(200, response.getStatus());
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType());
+    }
+
+    @Test
+    public void testFooBarOptions() {
+        Response response = target().path(ROOT_PATH).request().header("Accept", "foo/bar").options();
+        assertEquals(200, response.getStatus());
+        final String allowHeader = response.getHeaderString("Allow");
+        _checkAllowContent(allowHeader);
+        assertEquals("foo/bar", response.getMediaType().toString());
+        assertEquals(0, response.getLength());
+    }
+
+    @Test
+    public void testTextPlainOptions() {
+        Response response = target().path(ROOT_PATH).request().header("Accept", MediaType.TEXT_PLAIN).options();
+        assertEquals(200, response.getStatus());
+        final String allowHeader = response.getHeaderString("Allow");
+        _checkAllowContent(allowHeader);
+        assertEquals(MediaType.TEXT_PLAIN_TYPE, response.getMediaType());
+        final String responseBody = response.readEntity(String.class);
+        _checkAllowContent(responseBody);
+    }
+
+    private void _checkAllowContent(final String content) {
+        assertTrue(content.contains("GET"));
+        assertTrue(content.contains("HEAD"));
+        assertTrue(content.contains("OPTIONS"));
+    }
+
+    @Test
+    public void testMissingResourceNotFound() {
+        Response response;
+
+        response = target().path(ROOT_PATH + "arbitrary").request().get();
+        assertEquals(404, response.getStatus());
+        response.close();
+
+        response = target().path(ROOT_PATH).path("arbitrary").request().get();
+        assertEquals(404, response.getStatus());
+        response.close();
+    }
+
+    @Test
+    public void testLoggingFilterClientClass() {
+        Client client = client();
+        client.register(CustomLoggingFilter.class).property("foo", "bar");
+        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+        String s = target().path(ROOT_PATH).request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+        assertEquals(1, CustomLoggingFilter.preFilterCalled);
+        assertEquals(1, CustomLoggingFilter.postFilterCalled);
+    }
+
+    @Test
+    public void testLoggingFilterClientInstance() {
+        Client client = client();
+        client.register(new CustomLoggingFilter()).property("foo", "bar");
+        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+        String s = target().path(ROOT_PATH).request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+        assertEquals(1, CustomLoggingFilter.preFilterCalled);
+        assertEquals(1, CustomLoggingFilter.postFilterCalled);
+    }
+
+    @Test
+    public void testLoggingFilterTargetClass() {
+        WebTarget target = target().path(ROOT_PATH);
+        target.register(CustomLoggingFilter.class).property("foo", "bar");
+        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+        String s = target.request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+        assertEquals(1, CustomLoggingFilter.preFilterCalled);
+        assertEquals(1, CustomLoggingFilter.postFilterCalled);
+    }
+
+    @Test
+    public void testLoggingFilterTargetInstance() {
+        WebTarget target = target().path(ROOT_PATH);
+        target.register(new CustomLoggingFilter()).property("foo", "bar");
+        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+        String s = target.request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+        assertEquals(1, CustomLoggingFilter.preFilterCalled);
+        assertEquals(1, CustomLoggingFilter.postFilterCalled);
+    }
+
+    @Test
+    public void testConfigurationUpdate() {
+        Client client1 = client();
+        client1.register(CustomLoggingFilter.class).property("foo", "bar");
+
+        Client client = ClientBuilder.newClient(client1.getConfiguration());
+        CustomLoggingFilter.preFilterCalled = CustomLoggingFilter.postFilterCalled = 0;
+        String s = client.target(getBaseUri()).path(ROOT_PATH).request().get(String.class);
+        assertEquals(HelloWorldResource.CLICHED_MESSAGE, s);
+        assertEquals(1, CustomLoggingFilter.preFilterCalled);
+        assertEquals(1, CustomLoggingFilter.postFilterCalled);
+    }
+
+    /**
+     * JERSEY-2157 reproducer.
+     * <p>
+     * The test ensures that entities of the error responses which cause
+     * WebApplicationException being thrown by a JAX-RS client are buffered
+     * and that the underlying input connections are automatically released
+     * in such case.
+     */
+    @Test
+    public void testConnectionClosingOnExceptionsForErrorResponses() {
+        final BasicHttpClientConnectionManager cm = new BasicHttpClientConnectionManager();
+        final AtomicInteger connectionCounter = new AtomicInteger(0);
+
+        final ClientConfig config = new ClientConfig().property(Apache5ClientProperties.CONNECTION_MANAGER,
+                new HttpClientConnectionManager() {
+                    @Override
+                    public LeaseRequest lease(String id, HttpRoute route, Timeout requestTimeout, Object state) {
+                        connectionCounter.incrementAndGet();
+                        return cm.lease(id, route, requestTimeout, state);
+                    }
+
+                    @Override
+                    public void release(ConnectionEndpoint endpoint, Object newState, TimeValue validDuration) {
+                        connectionCounter.decrementAndGet();
+                        cm.release(endpoint, newState, validDuration);
+                    }
+
+                    @Override
+                    public void connect(
+                            ConnectionEndpoint endpoint,
+                            TimeValue connectTimeout,
+                            HttpContext context
+                    ) throws IOException {
+                        cm.connect(endpoint, connectTimeout, context);
+                    }
+
+                    @Override
+                    public void upgrade(ConnectionEndpoint endpoint, HttpContext context) throws IOException {
+                        cm.upgrade(endpoint, context);
+                    }
+
+                    @Override
+                    public void close(CloseMode closeMode) {
+                        cm.close(closeMode);
+                    }
+
+                    @Override
+                    public void close() throws IOException {
+                        cm.close();
+                    }
+                });
+        config.connectorProvider(new Apache5ConnectorProvider());
+
+        final Client client = ClientBuilder.newClient(config);
+        final WebTarget rootTarget = client.target(getBaseUri()).path(ROOT_PATH);
+
+        // Test that connection is getting closed properly for error responses.
+        try {
+            final String response = rootTarget.path("error").request().get(String.class);
+            fail("Exception expected. Received: " + response);
+        } catch (InternalServerErrorException isee) {
+            // do nothing - connection should be closed properly by now
+        }
+
+        // Fail if the previous connection has not been closed automatically.
+        assertEquals(0, connectionCounter.get());
+
+        try {
+            final String response = rootTarget.path("error2").request().get(String.class);
+            fail("Exception expected. Received: " + response);
+        } catch (InternalServerErrorException isee) {
+            assertEquals("Received unexpected data.", "Error2.", isee.getResponse().readEntity(String.class));
+            // Test buffering:
+            // second read would fail if entity was not buffered
+            assertEquals("Unexpected data in the entity buffer.", "Error2.", isee.getResponse().readEntity(String.class));
+        }
+
+        assertEquals(0, connectionCounter.get());
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpEntityTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpEntityTest.java
new file mode 100644
index 0000000..7b32627
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpEntityTest.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import org.apache.hc.core5.http.ContentType;
+import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
+import org.apache.hc.core5.http.io.entity.InputStreamEntity;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Assert;
+import org.junit.Test;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import java.io.ByteArrayInputStream;
+import java.util.logging.Logger;
+
+public class HttpEntityTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(HttpEntityTest.class.getName());
+    private static final String ECHO_MESSAGE = "ECHO MESSAGE";
+
+    @Path("/")
+    public static class Resource {
+        @POST
+        public String echo(String message) {
+            return message;
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(Resource.class)
+                .register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void testInputStreamEntity() {
+        ByteArrayInputStream bais = new ByteArrayInputStream(ECHO_MESSAGE.getBytes());
+        InputStreamEntity entity = new InputStreamEntity(bais, ContentType.TEXT_PLAIN);
+
+        try (Response response = target().request().post(Entity.entity(entity, MediaType.APPLICATION_OCTET_STREAM))) {
+            Assert.assertEquals(200, response.getStatus());
+            Assert.assertEquals(ECHO_MESSAGE, response.readEntity(String.class));
+        }
+    }
+
+    @Test
+    public void testByteArrayEntity() {
+        ByteArrayEntity entity = new ByteArrayEntity(ECHO_MESSAGE.getBytes(), ContentType.TEXT_PLAIN);
+
+        try (Response response = target().request().post(Entity.entity(entity, MediaType.APPLICATION_OCTET_STREAM))) {
+            Assert.assertEquals(200, response.getStatus());
+            Assert.assertEquals(ECHO_MESSAGE, response.readEntity(String.class));
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpHeadersTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpHeadersTest.java
new file mode 100644
index 0000000..8a2e91e
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpHeadersTest.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.HeaderParam;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.MultivaluedMap;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.ext.MessageBodyWriter;
+import jakarta.ws.rs.ext.Provider;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.glassfish.jersey.test.TestProperties;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class HttpHeadersTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(HttpHeadersTest.class.getName());
+
+    @Path("/test")
+    public static class HttpMethodResource {
+
+        @POST
+        public String post(
+                @HeaderParam("Transfer-Encoding") String transferEncoding,
+                @HeaderParam("X-CLIENT") String xClient,
+                @HeaderParam("X-WRITER") String xWriter,
+                String entity) {
+            assertEquals("client", xClient);
+            if (transferEncoding == null || !transferEncoding.equals("chunked")) {
+                assertEquals("writer", xWriter);
+            }
+            return entity;
+        }
+    }
+
+    @Provider
+    @Produces("text/plain")
+    public static class HeaderWriter implements MessageBodyWriter<String> {
+
+        public boolean isWriteable(Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            return type == String.class;
+        }
+
+        public long getSize(String t, Class<?> type, Type genericType, Annotation[] annotations, MediaType mediaType) {
+            return -1;
+        }
+
+        public void writeTo(String t,
+                            Class<?> type,
+                            Type genericType,
+                            Annotation[] annotations,
+                            MediaType mediaType,
+                            MultivaluedMap<String, Object> httpHeaders,
+                            OutputStream entityStream) throws IOException, WebApplicationException {
+            httpHeaders.add("X-WRITER", "writer");
+            entityStream.write(t.getBytes());
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        enable(TestProperties.LOG_TRAFFIC);
+        enable(TestProperties.DUMP_ENTITY);
+
+        ResourceConfig config = new ResourceConfig(HttpMethodResource.class, HeaderWriter.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.property(ClientProperties.READ_TIMEOUT, 1000).connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void testPost() {
+        WebTarget r = target("test");
+
+        Response cr = r.request().header("X-CLIENT", "client").post(Entity.text("POST"));
+        assertEquals(200, cr.getStatus());
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPostChunked() {
+        WebTarget r = target("test");
+
+        Response cr = r.request().header("X-CLIENT", "client").post(Entity.text("POST"));
+        assertEquals(200, cr.getStatus());
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodTest.java
new file mode 100644
index 0000000..e5dee0e
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodTest.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import jakarta.ws.rs.ClientErrorException;
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.HttpMethod;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.PUT;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class HttpMethodTest extends JerseyTest {
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(HttpMethodResource.class, ErrorResource.class);
+    }
+
+    protected Client createClient() {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        return ClientBuilder.newClient(cc);
+    }
+
+    protected Client createPoolingClient() {
+        ClientConfig cc = new ClientConfig();
+        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
+        connectionManager.setMaxTotal(100);
+        connectionManager.setDefaultMaxPerRoute(100);
+        cc.property(Apache5ClientProperties.CONNECTION_MANAGER, connectionManager);
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        return ClientBuilder.newClient(cc);
+    }
+
+    private WebTarget getWebTarget(final Client client) {
+        return client.target(getBaseUri()).path("test");
+    }
+
+    private WebTarget getWebTarget() {
+        return getWebTarget(createClient());
+    }
+
+    @Target({ElementType.METHOD})
+    @Retention(RetentionPolicy.RUNTIME)
+    @HttpMethod("PATCH")
+    public @interface PATCH {
+    }
+
+    @Path("/test")
+    public static class HttpMethodResource {
+        @GET
+        public String get() {
+            return "GET";
+        }
+
+        @POST
+        public String post(String entity) {
+            return entity;
+        }
+
+        @PUT
+        public String put(String entity) {
+            return entity;
+        }
+
+        @DELETE
+        public String delete() {
+            return "DELETE";
+        }
+
+        @DELETE
+        @Path("withentity")
+        public String delete(String entity) {
+            return entity;
+        }
+
+        @POST
+        @Path("noproduce")
+        public void postNoProduce(String entity) {
+        }
+
+        @POST
+        @Path("noconsumeproduce")
+        public void postNoConsumeProduce() {
+        }
+
+        @PATCH
+        public String patch(String entity) {
+            return entity;
+        }
+    }
+
+    @Test
+    public void testHead() {
+        WebTarget r = getWebTarget();
+        Response cr = r.request().head();
+        assertFalse(cr.hasEntity());
+    }
+
+    @Test
+    public void testOptions() {
+        WebTarget r = getWebTarget();
+        Response cr = r.request().options();
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testOptionsWithEntity() {
+        WebTarget r = getWebTarget();
+        Response response = r.request().build("OPTIONS", Entity.text("OPTIONS")).invoke();
+        assertEquals(200, response.getStatus());
+        response.close();
+    }
+
+    @Test
+    public void testGet() {
+        WebTarget r = getWebTarget();
+        assertEquals("GET", r.request().get(String.class));
+
+        Response cr = r.request().get();
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPost() {
+        WebTarget r = getWebTarget();
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+
+        Response cr = r.request().post(Entity.text("POST"));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPostChunked() {
+        ClientConfig cc = new ClientConfig()
+                .property(ClientProperties.CHUNKED_ENCODING_SIZE, 1024)
+                .connectorProvider(new Apache5ConnectorProvider());
+        Client client = ClientBuilder.newClient(cc);
+        WebTarget r = getWebTarget(client);
+
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+
+        Response cr = r.request().post(Entity.text("POST"));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPostVoid() {
+        WebTarget r = getWebTarget(createPoolingClient());
+
+        for (int i = 0; i < 100; i++) {
+            r.request().post(Entity.text("POST"));
+        }
+    }
+
+    @Test
+    public void testPostNoProduce() {
+        WebTarget r = getWebTarget();
+        assertEquals(204, r.path("noproduce").request().post(Entity.text("POST")).getStatus());
+
+        Response cr = r.path("noproduce").request().post(Entity.text("POST"));
+        assertFalse(cr.hasEntity());
+        cr.close();
+    }
+
+
+    @Test
+    public void testPostNoConsumeProduce() {
+        WebTarget r = getWebTarget();
+        assertEquals(204, r.path("noconsumeproduce").request().post(null).getStatus());
+
+        Response cr = r.path("noconsumeproduce").request().post(Entity.text("POST"));
+        assertFalse(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPut() {
+        WebTarget r = getWebTarget();
+        assertEquals("PUT", r.request().put(Entity.text("PUT"), String.class));
+
+        Response cr = r.request().put(Entity.text("PUT"));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testDelete() {
+        WebTarget r = getWebTarget();
+        assertEquals("DELETE", r.request().delete(String.class));
+
+        Response cr = r.request().delete();
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testPatch() {
+        WebTarget r = getWebTarget();
+        assertEquals("PATCH", r.request().method("PATCH", Entity.text("PATCH"), String.class));
+
+        Response cr = r.request().method("PATCH", Entity.text("PATCH"));
+        assertTrue(cr.hasEntity());
+        cr.close();
+    }
+
+    @Test
+    public void testAll() {
+        WebTarget r = getWebTarget();
+
+        assertEquals("GET", r.request().get(String.class));
+
+        assertEquals("POST", r.request().post(Entity.text("POST"), String.class));
+
+        assertEquals(204, r.path("noproduce").request().post(Entity.text("POST")).getStatus());
+
+        assertEquals(204, r.path("noconsumeproduce").request().post(null).getStatus());
+
+        assertEquals("PUT", r.request().post(Entity.text("PUT"), String.class));
+
+        assertEquals("DELETE", r.request().delete(String.class));
+    }
+
+
+    @Path("/error")
+    public static class ErrorResource {
+        @POST
+        public Response post(String entity) {
+            return Response.serverError().build();
+        }
+
+        @Path("entity")
+        @POST
+        public Response postWithEntity(String entity) {
+            return Response.serverError().entity("error").build();
+        }
+    }
+
+    @Test
+    public void testPostError() {
+        WebTarget r = createClient().target(getBaseUri()).path("error");
+
+        for (int i = 0; i < 100; i++) {
+            try {
+                final Response post = r.request().post(Entity.text("POST"));
+                post.close();
+            } catch (ClientErrorException ex) {
+            }
+        }
+    }
+
+    @Test
+    public void testPostErrorWithEntity() {
+        WebTarget r = createPoolingClient().target(getBaseUri()).path("error/entity");
+
+        for (int i = 0; i < 100; i++) {
+            try {
+                r.request().post(Entity.text("POST"));
+            } catch (ClientErrorException ex) {
+                String s = ex.getResponse().readEntity(String.class);
+                assertEquals("error", s);
+            }
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodWithClientFilterTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodWithClientFilterTest.java
new file mode 100644
index 0000000..03d182d
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/HttpMethodWithClientFilterTest.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class HttpMethodWithClientFilterTest extends HttpMethodTest {
+
+    @Override
+    protected Client createClient() {
+        ClientConfig cc = new ClientConfig()
+                .register(LoggingFeature.class)
+                .connectorProvider(new Apache5ConnectorProvider());
+        return ClientBuilder.newClient(cc);
+    }
+
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/LargeDataTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/LargeDataTest.java
new file mode 100644
index 0000000..bd8d992
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/LargeDataTest.java
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.ServerErrorException;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+import jakarta.ws.rs.core.StreamingOutput;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * The LargeDataTest reproduces a problem when bytes of large data sent are incorrectly sent.
+ * As a result, the request body is different than what was sent by the client.
+ * <p>
+ * In order to be able to inspect the request body, the generated data is a sequence of numbers
+ * delimited with new lines. Such as
+ * <pre><code>
+ *     1
+ *     2
+ *     3
+ *
+ *     ...
+ *
+ *     57234
+ *     57235
+ *     57236
+ *
+ *     ...
+ * </code></pre>
+ * It is also possible to send the data to netcat: {@code nc -l 8080} and verify the problem is
+ * on the client side.
+ *
+ * @author Stepan Vavra
+ * @author Marek Potociar
+ */
+public class LargeDataTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(LargeDataTest.class.getName());
+    private static final int LONG_DATA_SIZE = 1_000_000;  // for large set around 5GB, try e.g.: 536_870_912;
+    private static volatile Throwable exception;
+
+    private static StreamingOutput longData(long sequence) {
+        return out -> {
+            long offset = 0;
+            while (offset < sequence) {
+                out.write(Long.toString(offset).getBytes());
+                out.write('\n');
+                offset++;
+            }
+        };
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(HttpMethodResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.HEADERS_ONLY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void postWithLargeData() throws Throwable {
+        WebTarget webTarget = target("test");
+
+        Response response = webTarget.request().post(Entity.entity(longData(LONG_DATA_SIZE), MediaType.TEXT_PLAIN_TYPE));
+
+        try {
+            if (exception != null) {
+
+                // the reason to throw the exception is that IntelliJ gives you an option to compare the expected with the actual
+                throw exception;
+            }
+
+            Assert.assertEquals("Unexpected error: " + response.getStatus(),
+                    Status.Family.SUCCESSFUL,
+                    response.getStatusInfo().getFamily());
+        } finally {
+            response.close();
+        }
+    }
+
+    @Path("/test")
+    public static class HttpMethodResource {
+
+        @POST
+        public Response post(InputStream content) {
+            try {
+
+                longData(LONG_DATA_SIZE).write(new OutputStream() {
+
+                    private long position = 0;
+//                    private long mbRead = 0;
+
+                    @Override
+                    public void write(final int generated) throws IOException {
+                        int received = content.read();
+
+                        if (received != generated) {
+                            throw new IOException("Bytes don't match at position " + position
+                                    + ": received=" + received
+                                    + ", generated=" + generated);
+                        }
+
+                        position++;
+//                        if (position % (1024 * 1024) == 0) {
+//                            mbRead++;
+//                            System.out.println("MB read: " + mbRead);
+//                        }
+                    }
+                });
+            } catch (IOException e) {
+                exception = e;
+                throw new ServerErrorException(e.getMessage(), 500, e);
+            }
+
+            return Response.ok().build();
+        }
+
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/ManagedClientTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/ManagedClientTest.java
new file mode 100644
index 0000000..f1ed320
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/ManagedClientTest.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.ClientRequestContext;
+import jakarta.ws.rs.client.ClientRequestFilter;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.DynamicFeature;
+import jakarta.ws.rs.container.ResourceInfo;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ClientBinding;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.Uri;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Jersey programmatic managed client test
+ *
+ * @author Marek Potociar
+ */
+public class ManagedClientTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(ManagedClientTest.class.getName());
+
+    /**
+     * Managed client configuration for client A.
+     *
+     * @author Marek Potociar (marek.potociar at oracle.com)
+     */
+    @ClientBinding(configClass = MyClientAConfig.class)
+    @Documented
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD, ElementType.PARAMETER})
+    public static @interface ClientA {
+    }
+
+    /**
+     * Managed client configuration for client B.
+     *
+     * @author Marek Potociar (marek.potociar at oracle.com)
+     */
+    @ClientBinding(configClass = MyClientBConfig.class)
+    @Documented
+    @Retention(RetentionPolicy.RUNTIME)
+    @Target({ElementType.FIELD, ElementType.PARAMETER})
+    public @interface ClientB {
+    }
+
+    /**
+     * Dynamic feature that appends a properly configured {@link CustomHeaderFilter} instance
+     * to every method that is annotated with {@link Require &#64;Require} internal feature
+     * annotation.
+     *
+     * @author Marek Potociar
+     */
+    public static class CustomHeaderFeature implements DynamicFeature {
+
+        /**
+         * A method annotation to be placed on those resource methods to which a validating
+         * {@link CustomHeaderFilter} instance should be added.
+         */
+        @Retention(RetentionPolicy.RUNTIME)
+        @Documented
+        @Target(ElementType.METHOD)
+        public static @interface Require {
+
+            /**
+             * Expected custom header name to be validated by the {@link CustomHeaderFilter}.
+             */
+            public String headerName();
+
+            /**
+             * Expected custom header value to be validated by the {@link CustomHeaderFilter}.
+             */
+            public String headerValue();
+        }
+
+        @Override
+        public void configure(ResourceInfo resourceInfo, FeatureContext context) {
+            final Require va = resourceInfo.getResourceMethod().getAnnotation(Require.class);
+            if (va != null) {
+                context.register(new CustomHeaderFilter(va.headerName(), va.headerValue()));
+            }
+        }
+    }
+
+    /**
+     * A filter for appending and validating custom headers.
+     * <p>
+     * On the client side, appends a new custom request header with a configured name and value to each outgoing request.
+     * </p>
+     * <p>
+     * On the server side, validates that each request has a custom header with a configured name and value.
+     * If the validation fails a HTTP 403 response is returned.
+     * </p>
+     *
+     * @author Marek Potociar (marek.potociar at oracle.com)
+     */
+    public static class CustomHeaderFilter implements ContainerRequestFilter, ClientRequestFilter {
+
+        private final String headerName;
+        private final String headerValue;
+
+        public CustomHeaderFilter(String headerName, String headerValue) {
+            if (headerName == null || headerValue == null) {
+                throw new IllegalArgumentException("Header name and value must not be null.");
+            }
+            this.headerName = headerName;
+            this.headerValue = headerValue;
+        }
+
+        @Override
+        public void filter(ContainerRequestContext ctx) throws IOException { // validate
+            if (!headerValue.equals(ctx.getHeaderString(headerName))) {
+                ctx.abortWith(Response.status(Response.Status.FORBIDDEN)
+                        .type(MediaType.TEXT_PLAIN)
+                        .entity(String
+                                .format("Expected header '%s' not present or value not equal to '%s'", headerName, headerValue))
+                        .build());
+            }
+        }
+
+        @Override
+        public void filter(ClientRequestContext ctx) throws IOException { // append
+            ctx.getHeaders().putSingle(headerName, headerValue);
+        }
+    }
+
+    /**
+     * Internal resource accessed from the managed client resource.
+     *
+     * @author Marek Potociar (marek.potociar at oracle.com)
+     */
+    @Path("internal")
+    public static class InternalResource {
+
+        @GET
+        @Path("a")
+        @CustomHeaderFeature.Require(headerName = "custom-header", headerValue = "a")
+        public String getA() {
+            return "a";
+        }
+
+        @GET
+        @Path("b")
+        @CustomHeaderFeature.Require(headerName = "custom-header", headerValue = "b")
+        public String getB() {
+            return "b";
+        }
+    }
+
+    /**
+     * A resource that uses managed clients to retrieve values of internal
+     * resources 'A' and 'B', which are protected by a {@link CustomHeaderFilter}
+     * and require a specific custom header in a request to be set to a specific value.
+     * <p>
+     * Properly configured managed clients have a {@code CustomHeaderFilter} instance
+     * configured to insert the {@link CustomHeaderFeature.Require required} custom header
+     * with a proper value into the outgoing client requests.
+     * </p>
+     *
+     * @author Marek Potociar (marek.potociar at oracle.com)
+     */
+    @Path("public")
+    public static class PublicResource {
+
+        @Uri("a")
+        @ClientA // resolves to <base>/internal/a
+        private WebTarget targetA;
+
+        @GET
+        @Produces("text/plain")
+        @Path("a")
+        public String getTargetA() {
+            return targetA.request(MediaType.TEXT_PLAIN).get(String.class);
+        }
+
+        @GET
+        @Produces("text/plain")
+        @Path("b")
+        public Response getTargetB(@Uri("internal/b") @ClientB WebTarget targetB) {
+            return targetB.request(MediaType.TEXT_PLAIN).get();
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(PublicResource.class, InternalResource.class, CustomHeaderFeature.class)
+                .property(ClientA.class.getName() + ".baseUri", this.getBaseUri().toString() + "internal");
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    public static class MyClientAConfig extends ClientConfig {
+
+        public MyClientAConfig() {
+            this.register(new CustomHeaderFilter("custom-header", "a"));
+        }
+    }
+
+    public static class MyClientBConfig extends ClientConfig {
+
+        public MyClientBConfig() {
+            this.register(new CustomHeaderFilter("custom-header", "b"));
+        }
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    /**
+     * Test that a connection via managed clients works properly.
+     *
+     * @throws Exception in case of test failure.
+     */
+    @Test
+    public void testManagedClient() throws Exception {
+        final WebTarget resource = target().path("public").path("{name}");
+        Response response;
+
+        response = resource.resolveTemplate("name", "a").request(MediaType.TEXT_PLAIN).get();
+        assertEquals(200, response.getStatus());
+        assertEquals("a", response.readEntity(String.class));
+
+        response = resource.resolveTemplate("name", "b").request(MediaType.TEXT_PLAIN).get();
+        assertEquals(200, response.getStatus());
+        assertEquals("b", response.readEntity(String.class));
+    }
+
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/NoEntityTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/NoEntityTest.java
new file mode 100644
index 0000000..e42eb53
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/NoEntityTest.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+import jakarta.ws.rs.core.Response.Status;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+
+/**
+ * @author Paul Sandoz
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class NoEntityTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(NoEntityTest.class.getName());
+
+    @Path("/test")
+    public static class HttpMethodResource {
+        @GET
+        public Response get() {
+            return Response.status(Status.CONFLICT).build();
+        }
+
+        @POST
+        public void post(String entity) {
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(HttpMethodResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void testGet() {
+        WebTarget r = target("test");
+
+        for (int i = 0; i < 5; i++) {
+            Response cr = r.request().get();
+            cr.close();
+        }
+    }
+
+    @Test
+    public void testGetWithClose() {
+        WebTarget r = target("test");
+        for (int i = 0; i < 5; i++) {
+            Response cr = r.request().get();
+            cr.close();
+        }
+    }
+
+    @Test
+    public void testPost() {
+        WebTarget r = target("test");
+        for (int i = 0; i < 5; i++) {
+            Response cr = r.request().post(null);
+        }
+    }
+
+    @Test
+    public void testPostWithClose() {
+        WebTarget r = target("test");
+        for (int i = 0; i < 5; i++) {
+            Response cr = r.request().post(null);
+            cr.close();
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/RetryStrategyTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/RetryStrategyTest.java
new file mode 100644
index 0000000..59ccdbc
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/RetryStrategyTest.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.POST;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+
+import org.apache.hc.client5.http.HttpRequestRetryStrategy;
+import org.apache.hc.core5.http.HttpRequest;
+import org.apache.hc.core5.http.HttpResponse;
+import org.apache.hc.core5.http.protocol.HttpContext;
+import org.apache.hc.core5.util.TimeValue;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.client.RequestEntityProcessing;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+public class RetryStrategyTest extends JerseyTest {
+    private static final int READ_TIMEOUT_MS = 100;
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(RetryHandlerResource.class);
+    }
+
+    @Path("/")
+    public static class RetryHandlerResource {
+        private static volatile int postRequestNumber = 0;
+        private static volatile int getRequestNumber = 0;
+
+        // Cause a timeout on the first GET and POST request
+        @GET
+        public String get(@Context HttpHeaders h) {
+            if (getRequestNumber++ == 0) {
+                try {
+                    Thread.sleep(READ_TIMEOUT_MS * 10);
+                } catch (InterruptedException ex) {
+                    // ignore
+                }
+            }
+            return "GET";
+        }
+
+        @POST
+        public String post(@Context HttpHeaders h, String e) {
+            if (postRequestNumber++ == 0) {
+                try {
+                    Thread.sleep(READ_TIMEOUT_MS * 10);
+                } catch (InterruptedException ex) {
+                    // ignore
+                }
+            }
+            return "POST";
+        }
+    }
+
+    @Test
+    public void testRetryGet() throws IOException {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        cc.property(Apache5ClientProperties.RETRY_STRATEGY,
+                new HttpRequestRetryStrategy() {
+                    @Override
+                    public boolean retryRequest(HttpRequest request, IOException exception, int execCount, HttpContext context) {
+                        return true;
+                    }
+
+                    @Override
+                    public boolean retryRequest(HttpResponse response, int execCount, HttpContext context) {
+                        return true;
+                    }
+
+                    @Override
+                    public TimeValue getRetryInterval(HttpResponse response, int execCount, HttpContext context) {
+                        return TimeValue.ofMilliseconds(200);
+                    }
+                });
+        cc.property(ClientProperties.READ_TIMEOUT, READ_TIMEOUT_MS);
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri());
+        assertEquals("GET", r.request().get(String.class));
+    }
+
+    @Test
+    public void testRetryPost() throws IOException {
+        ClientConfig cc = new ClientConfig();
+        cc.connectorProvider(new Apache5ConnectorProvider());
+        cc.property(Apache5ClientProperties.RETRY_STRATEGY,
+                new HttpRequestRetryStrategy() {
+                    @Override
+                    public boolean retryRequest(HttpRequest request, IOException exception, int execCount, HttpContext context) {
+                        return true;
+                    }
+
+                    @Override
+                    public boolean retryRequest(HttpResponse response, int execCount, HttpContext context) {
+                        return true;
+                    }
+
+                    @Override
+                    public TimeValue getRetryInterval(HttpResponse response, int execCount, HttpContext context) {
+                        return TimeValue.ofMilliseconds(200);
+                    }
+                });
+        cc.property(ClientProperties.READ_TIMEOUT, READ_TIMEOUT_MS);
+        Client client = ClientBuilder.newClient(cc);
+
+        WebTarget r = client.target(getBaseUri());
+        assertEquals("POST", r.request()
+                              .property(ClientProperties.REQUEST_ENTITY_PROCESSING, RequestEntityProcessing.BUFFERED)
+                              .post(Entity.text("POST"), String.class));
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/SpecialHeaderTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/SpecialHeaderTest.java
new file mode 100644
index 0000000..2171132
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/SpecialHeaderTest.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.HttpHeaders;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.message.GZipEncoder;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Assert;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ *
+ * @author Miroslav Fuksa
+ */
+public class SpecialHeaderTest extends JerseyTest {
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(MyResource.class, GZipEncoder.class, LoggingFeature.class);
+    }
+
+    @Path("resource")
+    public static class MyResource {
+        @GET
+        @Produces("text/plain")
+        @Path("encoded")
+        public Response getEncoded() {
+            return Response.ok("get").header(HttpHeaders.CONTENT_ENCODING, "gzip").build();
+        }
+
+        @GET
+        @Produces("text/plain")
+        @Path("non-encoded")
+        public Response getNormal() {
+            return Response.ok("get").build();
+        }
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+
+    @Test
+    @Ignore("Apache connector does not provide information about encoding for gzip and deflate encoding")
+    public void testEncoded() {
+        final Response response = target().path("resource/encoded").request("text/plain").get();
+        Assert.assertEquals(200, response.getStatus());
+        Assert.assertEquals("get", response.readEntity(String.class));
+        Assert.assertEquals("gzip", response.getHeaderString(HttpHeaders.CONTENT_ENCODING));
+        Assert.assertEquals("text/plain", response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+        Assert.assertEquals(3, response.getHeaderString(HttpHeaders.CONTENT_LENGTH));
+    }
+
+    @Test
+    public void testNonEncoded() {
+        final Response response = target().path("resource/non-encoded").request("text/plain").get();
+        Assert.assertEquals(200, response.getStatus());
+        Assert.assertEquals("get", response.readEntity(String.class));
+        Assert.assertNull(response.getHeaderString(HttpHeaders.CONTENT_ENCODING));
+        Assert.assertEquals("text/plain", response.getHeaderString(HttpHeaders.CONTENT_TYPE));
+        Assert.assertEquals("3", response.getHeaderString(HttpHeaders.CONTENT_LENGTH));
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/StreamingTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/StreamingTest.java
new file mode 100644
index 0000000..4d69723
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/StreamingTest.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.Invocation;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Response;
+import jakarta.inject.Singleton;
+
+import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.server.ChunkedOutput;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Petr Janouch
+ */
+public class StreamingTest extends JerseyTest {
+    private PoolingHttpClientConnectionManager connectionManager;
+
+    /**
+     * Test that a data stream can be terminated from the client side.
+     */
+    @Test
+    public void clientCloseNoTimeoutTest() throws IOException {
+        clientCloseTest(-1);
+    }
+
+    @Test
+    public void clientCloseWithTimeOutTest() throws IOException {
+        clientCloseTest(1_000);
+    }
+
+    /**
+     * Tests that closing a response after completely reading the entity reuses the connection
+     */
+    @Test
+    public void reuseConnectionTest() throws IOException {
+        Response response = target().path("/streamingEndpoint/get").request().get();
+        InputStream is = response.readEntity(InputStream.class);
+        byte[] buf = new byte[8192];
+        is.read(buf);
+        is.close();
+        response.close();
+
+        assertEquals(1, connectionManager.getTotalStats().getAvailable());
+        assertEquals(0, connectionManager.getTotalStats().getLeased());
+    }
+
+    /**
+     * Tests that closing a request without reading the entity does not throw an exception.
+     */
+    @Test
+    public void clientCloseThrowsNoExceptionTest() throws IOException {
+        Response response = target().path("/streamingEndpoint/get").request().get();
+        response.close();
+    }
+
+    @Override
+    protected void configureClient(ClientConfig config) {
+        connectionManager = new PoolingHttpClientConnectionManager();
+        config.property(Apache5ClientProperties.CONNECTION_MANAGER, connectionManager);
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(StreamingEndpoint.class);
+    }
+
+    /**
+     * Test that a data stream can be terminated from the client side.
+     */
+    private void clientCloseTest(int readTimeout) throws IOException {
+        // start streaming
+        AtomicInteger counter = new AtomicInteger(0);
+        Invocation.Builder builder = target().path("/streamingEndpoint").request();
+        if (readTimeout > -1) {
+            counter.set(1);
+            builder.property(ClientProperties.READ_TIMEOUT, readTimeout);
+            builder.property(Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY,
+                    (Apache5ConnectionClosingStrategy) (config, request, response, stream) -> {
+                try {
+                    stream.close();
+                } catch (Exception e) {
+                    // timeout, no chunk ending
+                } finally {
+                    counter.set(0);
+                    response.close();
+                }
+            });
+        }
+        InputStream inputStream = builder.get(InputStream.class);
+
+        WebTarget sendTarget = target().path("/streamingEndpoint/send");
+        // trigger sending 'A' to the stream; OK is sent if everything on the server was OK
+        assertEquals("OK", sendTarget.request().get().readEntity(String.class));
+        // check 'A' has been sent
+        assertEquals('A', inputStream.read());
+        // closing the stream should tear down the connection
+        inputStream.close();
+        // trigger sending another 'A' to the stream; it should fail
+        // (indicating that the streaming has been terminated on the server)
+        assertEquals("NOK", sendTarget.request().get().readEntity(String.class));
+        assertEquals(0, counter.get());
+    }
+
+    @Singleton
+    @Path("streamingEndpoint")
+    public static class StreamingEndpoint {
+
+        private final ChunkedOutput<String> output = new ChunkedOutput<>(String.class);
+
+        @GET
+        @Path("send")
+        public String sendEvent() {
+            try {
+                output.write("A");
+            } catch (IOException e) {
+                return "NOK";
+            }
+
+            return "OK";
+        }
+
+        @GET
+        @Produces(MediaType.TEXT_PLAIN)
+        public ChunkedOutput<String> get() {
+            return output;
+        }
+
+        @GET
+        @Path("get")
+        @Produces(MediaType.TEXT_PLAIN)
+        public String getString() {
+            return "OK";
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TimeoutTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TimeoutTest.java
new file mode 100644
index 0000000..f6b2d52
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TimeoutTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.net.SocketTimeoutException;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.ProcessingException;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.client.ClientProperties;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.fail;
+
+/**
+ * @author Martin Matula
+ * @author Arul Dhesiaseelan (aruld at acm.org)
+ */
+public class TimeoutTest extends JerseyTest {
+    private static final Logger LOGGER = Logger.getLogger(TimeoutTest.class.getName());
+
+    @Path("/test")
+    public static class TimeoutResource {
+        @GET
+        public String get() {
+            return "GET";
+        }
+
+        @GET
+        @Path("timeout")
+        public String getTimeout() {
+            try {
+                Thread.sleep(2000);
+            } catch (final InterruptedException e) {
+                e.printStackTrace();
+            }
+            return "GET";
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        final ResourceConfig config = new ResourceConfig(TimeoutResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        return config;
+    }
+
+    @Override
+    protected void configureClient(final ClientConfig config) {
+        config.property(ClientProperties.READ_TIMEOUT, 1000);
+        config.connectorProvider(new Apache5ConnectorProvider());
+    }
+
+    @Test
+    public void testFast() {
+        final Response r = target("test").request().get();
+        assertEquals(200, r.getStatus());
+        assertEquals("GET", r.readEntity(String.class));
+    }
+
+    @Test
+    public void testSlow() {
+        try {
+            target("test/timeout").request().get();
+            fail("Timeout expected.");
+        } catch (final ProcessingException e) {
+            assertThat("Unexpected processing exception cause",
+                    e.getCause(), instanceOf(SocketTimeoutException.class));
+        }
+    }
+
+    @Test
+    public void testPerRequestTimeout() {
+        final Response r = target("test/timeout").request()
+                .property(ClientProperties.READ_TIMEOUT, 3000).get();
+        assertEquals(200, r.getStatus());
+        assertEquals("GET", r.readEntity(String.class));
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TraceSupportTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TraceSupportTest.java
new file mode 100644
index 0000000..4b85c23
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/TraceSupportTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Logger;
+
+import jakarta.ws.rs.HttpMethod;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.Produces;
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.Entity;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.MediaType;
+import jakarta.ws.rs.core.Request;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.client.ClientConfig;
+import org.glassfish.jersey.logging.LoggingFeature;
+import org.glassfish.jersey.process.Inflector;
+import org.glassfish.jersey.server.ContainerRequest;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.server.model.Resource;
+import org.glassfish.jersey.test.JerseyTest;
+
+import org.junit.Test;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * This very basic resource showcases support of a HTTP TRACE method,
+ * not directly supported by JAX-RS API.
+ *
+ * @author Marek Potociar
+ */
+public class TraceSupportTest extends JerseyTest {
+
+    private static final Logger LOGGER = Logger.getLogger(TraceSupportTest.class.getName());
+
+    /**
+     * Programmatic tracing root resource path.
+     */
+    public static final String ROOT_PATH_PROGRAMMATIC = "tracing/programmatic";
+
+    /**
+     * Annotated class-based tracing root resource path.
+     */
+    public static final String ROOT_PATH_ANNOTATED = "tracing/annotated";
+
+    @HttpMethod(TRACE.NAME)
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    public @interface TRACE {
+        public static final String NAME = "TRACE";
+    }
+
+    @Path(ROOT_PATH_ANNOTATED)
+    public static class TracingResource {
+
+        @TRACE
+        @Produces("text/plain")
+        public String trace(Request request) {
+            return stringify((ContainerRequest) request);
+        }
+    }
+
+    @Override
+    protected Application configure() {
+        ResourceConfig config = new ResourceConfig(TracingResource.class);
+        config.register(new LoggingFeature(LOGGER, LoggingFeature.Verbosity.PAYLOAD_ANY));
+        final Resource.Builder resourceBuilder = Resource.builder(ROOT_PATH_PROGRAMMATIC);
+        resourceBuilder.addMethod(TRACE.NAME).handledBy(new Inflector<ContainerRequestContext, Response>() {
+
+            @Override
+            public Response apply(ContainerRequestContext request) {
+                if (request == null) {
+                    return Response.noContent().build();
+                } else {
+                    return Response.ok(stringify((ContainerRequest) request), MediaType.TEXT_PLAIN).build();
+                }
+            }
+        });
+
+        return config.registerResources(resourceBuilder.build());
+
+    }
+
+    private String[] expectedFragmentsProgrammatic = new String[]{
+            "TRACE http://localhost:" + this.getPort() + "/tracing/programmatic"
+    };
+    private String[] expectedFragmentsAnnotated = new String[]{
+            "TRACE http://localhost:" + this.getPort() + "/tracing/annotated"
+    };
+
+    private WebTarget prepareTarget(String path) {
+        final WebTarget target = target();
+        target.register(LoggingFeature.class);
+        return target.path(path);
+    }
+
+    @Test
+    public void testProgrammaticApp() throws Exception {
+        Response response = prepareTarget(ROOT_PATH_PROGRAMMATIC).request("text/plain").method(TRACE.NAME);
+
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        String responseEntity = response.readEntity(String.class);
+        for (String expectedFragment : expectedFragmentsProgrammatic) {
+            assertTrue("Expected fragment '" + expectedFragment + "' not found in response:\n" + responseEntity,
+                    // toLowerCase - http header field names are case insensitive
+                    responseEntity.contains(expectedFragment));
+        }
+    }
+
+    @Test
+    public void testAnnotatedApp() throws Exception {
+        Response response = prepareTarget(ROOT_PATH_ANNOTATED).request("text/plain").method(TRACE.NAME);
+
+        assertEquals(Response.Status.OK.getStatusCode(), response.getStatusInfo().getStatusCode());
+
+        String responseEntity = response.readEntity(String.class);
+        for (String expectedFragment : expectedFragmentsAnnotated) {
+            assertTrue("Expected fragment '" + expectedFragment + "' not found in response:\n" + responseEntity,
+                    // toLowerCase - http header field names are case insensitive
+                    responseEntity.contains(expectedFragment));
+        }
+    }
+
+    @Test
+    public void testTraceWithEntity() throws Exception {
+        _testTraceWithEntity(false, false);
+    }
+
+    @Test
+    public void testAsyncTraceWithEntity() throws Exception {
+        _testTraceWithEntity(true, false);
+    }
+
+    @Test
+    public void testTraceWithEntityApacheConnector() throws Exception {
+        _testTraceWithEntity(false, true);
+    }
+
+    @Test
+    public void testAsyncTraceWithEntityApacheConnector() throws Exception {
+        _testTraceWithEntity(true, true);
+    }
+
+    private void _testTraceWithEntity(final boolean isAsync, final boolean useApacheConnection) throws Exception {
+        try {
+            WebTarget target = useApacheConnection ? getApacheClient().target(target().getUri()) : target();
+            target = target.path(ROOT_PATH_ANNOTATED);
+
+            final Entity<String> entity = Entity.entity("trace", MediaType.WILDCARD_TYPE);
+
+            Response response;
+            if (!isAsync) {
+                response = target.request().method(TRACE.NAME, entity);
+            } else {
+                response = target.request().async().method(TRACE.NAME, entity).get();
+            }
+
+            fail("A TRACE request MUST NOT include an entity. (response=" + response + ")");
+        } catch (Exception e) {
+            // OK
+        }
+    }
+
+    private Client getApacheClient() {
+        return ClientBuilder.newClient(new ClientConfig().connectorProvider(new Apache5ConnectorProvider()));
+    }
+
+
+    public static String stringify(ContainerRequest request) {
+        StringBuilder buffer = new StringBuilder();
+
+        printRequestLine(buffer, request);
+        printPrefixedHeaders(buffer, request.getHeaders());
+
+        if (request.hasEntity()) {
+            buffer.append(request.readEntity(String.class)).append("\n");
+        }
+
+        return buffer.toString();
+    }
+
+    private static void printRequestLine(StringBuilder buffer, ContainerRequest request) {
+        buffer.append(request.getMethod()).append(" ").append(request.getUriInfo().getRequestUri().toASCIIString()).append("\n");
+    }
+
+    private static void printPrefixedHeaders(StringBuilder buffer, Map<String, List<String>> headers) {
+        for (Map.Entry<String, List<String>> e : headers.entrySet()) {
+            List<String> val = e.getValue();
+            String header = e.getKey();
+
+            if (val.size() == 1) {
+                buffer.append(header).append(": ").append(val.get(0)).append("\n");
+            } else {
+                StringBuilder sb = new StringBuilder();
+                boolean add = false;
+                for (String s : val) {
+                    if (add) {
+                        sb.append(',');
+                    }
+                    add = true;
+                    sb.append(s);
+                }
+                buffer.append(header).append(": ").append(sb.toString()).append("\n");
+            }
+        }
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingCookieStoreAccessTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingCookieStoreAccessTest.java
new file mode 100644
index 0000000..6f0938b
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingCookieStoreAccessTest.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+
+import org.apache.hc.client5.http.cookie.CookieStore;
+import org.glassfish.jersey.client.ClientConfig;
+
+import org.junit.Test;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+/**
+ * Test of access to the underlying CookieStore instance used by the connector.
+ *
+ * @author Maksim Mukosey (mmukosey at gmail.com)
+ */
+public class UnderlyingCookieStoreAccessTest {
+
+    @Test
+    public void testCookieStoreInstanceAccess() {
+        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new Apache5ConnectorProvider()));
+        final CookieStore csOnClient = Apache5ConnectorProvider.getCookieStore(client);
+        // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
+        // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
+        // connector provider's static getCookieStore method above.
+        final WebTarget target = client.target("http://localhost/");
+        final CookieStore csOnTarget = Apache5ConnectorProvider.getCookieStore(target);
+
+        assertNotNull("CookieStore instance set on JerseyClient should not be null.", csOnClient);
+        assertNotNull("CookieStore instance set on JerseyWebTarget should not be null.", csOnTarget);
+        assertSame("CookieStore instance set on JerseyClient should be the same instance as the one set on JerseyWebTarget"
+                + "(provided the target instance has not been further configured).", csOnClient, csOnTarget);
+    }
+}
diff --git a/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingHttpClientAccessTest.java b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingHttpClientAccessTest.java
new file mode 100644
index 0000000..6b5fc6f
--- /dev/null
+++ b/connectors/apache5-connector/src/test/java/org/glassfish/jersey/apache5/connector/UnderlyingHttpClientAccessTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.apache5.connector;
+
+import jakarta.ws.rs.client.Client;
+import jakarta.ws.rs.client.ClientBuilder;
+import jakarta.ws.rs.client.WebTarget;
+
+import org.apache.hc.client5.http.classic.HttpClient;
+import org.glassfish.jersey.client.ClientConfig;
+
+import org.junit.Test;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+/**
+ * Test of access to the underlying HTTP client instance used by the connector.
+ *
+ * @author Marek Potociar
+ */
+public class UnderlyingHttpClientAccessTest {
+
+    /**
+     * Verifier of JERSEY-2424 fix.
+     */
+    @Test
+    public void testHttpClientInstanceAccess() {
+        final Client client = ClientBuilder.newClient(new ClientConfig().connectorProvider(new Apache5ConnectorProvider()));
+        final HttpClient hcOnClient = Apache5ConnectorProvider.getHttpClient(client);
+        // important: the web target instance in this test must be only created AFTER the client has been pre-initialized
+        // (see org.glassfish.jersey.client.Initializable.preInitialize method). This is here achieved by calling the
+        // connector provider's static getHttpClient method above.
+        final WebTarget target = client.target("http://localhost/");
+        final HttpClient hcOnTarget = Apache5ConnectorProvider.getHttpClient(target);
+
+        assertNotNull("HTTP client instance set on JerseyClient should not be null.", hcOnClient);
+        assertNotNull("HTTP client instance set on JerseyWebTarget should not be null.", hcOnTarget);
+        assertSame("HTTP client instance set on JerseyClient should be the same instance as the one set on JerseyWebTarget"
+                        + "(provided the target instance has not been further configured).",
+                hcOnClient, hcOnTarget
+        );
+    }
+}
diff --git a/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties b/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
index 7b06288..fb56d5c 100644
--- a/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
+++ b/connectors/helidon-connector/src/main/resources/org/glassfish/jersey/helidon/connector/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2020, 2022 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
@@ -14,4 +14,4 @@
 # SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 #
 
-not.supported=Helidon connector is not supported on JDK version less than 11.
\ No newline at end of file
+not.supported=Helidon connector is not supported on JDK version less than 17.
\ No newline at end of file
diff --git a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/JdkConnectorProperties.java b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/JdkConnectorProperties.java
index 190232f..9e7acdd 100644
--- a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/JdkConnectorProperties.java
+++ b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/JdkConnectorProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 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
@@ -60,7 +60,7 @@
      * Value is expected to be positive {@link Integer}. Default value is {@value #DEFAULT_MAX_REDIRECTS}.
      * <p/>
      * HTTP redirection must be enabled by property {@link org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS},
-     * otherwise {@code MAX_HEADER_SIZE} is not applied.
+     * otherwise {@code MAX_REDIRECTS} is not applied.
      *
      * @see org.glassfish.jersey.client.ClientProperties#FOLLOW_REDIRECTS
      * @see org.glassfish.jersey.jdk.connector.internal.RedirectException
@@ -70,14 +70,14 @@
     /**
      * To set the cookie policy of this cookie manager.
      * <p/>
-     * The default value is ACCEPT_ORIGINAL_SERVER.
+     * The default value is {@link CookiePolicy#ACCEPT_ORIGINAL_SERVER}.
      *
      * @see java.net.CookieManager
      */
     public static final String COOKIE_POLICY = "jersey.config.client.JdkConnectorProvider.cookiePolicy";
 
     /**
-     * A maximal number of open connection to each destination. A destination is determined by the following triple:
+     * A maximum number of open connections per each destination. A destination is determined by the following triple:
      * <ul>
      * <li>host</li>
      * <li>port</li>
diff --git a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/RedirectException.java b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/RedirectException.java
index 65aec26..0e8e672 100644
--- a/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/RedirectException.java
+++ b/connectors/jdk-connector/src/main/java/org/glassfish/jersey/jdk/connector/internal/RedirectException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -25,7 +25,7 @@
  * <ul>
  * <li>
  * the chained redirection count exceeds the value of
- * {@link org.glassfish.jersey.client.JdkConnectorProvider#MAX_REDIRECTS}
+ * {@link org.glassfish.jersey.jdk.connector.JdkConnectorProperties#MAX_REDIRECTS}
  * </li>
  * <li>
  * or an infinite redirection loop is detected
diff --git a/connectors/jetty-connector/pom.xml b/connectors/jetty-connector/pom.xml
index a98019c..e7038d3 100644
--- a/connectors/jetty-connector/pom.xml
+++ b/connectors/jetty-connector/pom.xml
@@ -71,11 +71,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>jakarta.xml.bind</groupId>
             <artifactId>jakarta.xml.bind-api</artifactId>
             <scope>test</scope>
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyClientProperties.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyClientProperties.java
index 7b860c3..ef2c8be 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyClientProperties.java
+++ b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyClientProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -70,7 +70,7 @@
      * that is stored in a truststore.
      * <p/>
      * The value MUST be an instance of {@link java.lang.Boolean}.
-     * If the property is absent the default value is {@code true}
+     * If the property is absent the default value is {@code true}.
      */
     public static final String ENABLE_SSL_HOSTNAME_VERIFICATION =
             "jersey.config.jetty.client.enableSslHostnameVerification";
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
index ef1585c..655a203 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnector.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -95,8 +95,10 @@
  * <li>{@link ClientProperties#PROXY_USERNAME}</li>
  * <li>{@link ClientProperties#PROXY_PASSWORD}</li>
  * <li>{@link ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
  * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
- * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>
+ * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
  * </ul>
  * <p/>
  * This transport supports both synchronous and asynchronous processing of client requests.
diff --git a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
index 933ad39..dfd3b79 100644
--- a/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty-connector/src/main/java/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -42,8 +42,10 @@
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_USERNAME}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
  * <li>{@link org.glassfish.jersey.client.ClientProperties#PROXY_PASSWORD}</li>
+ * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>*
+ * <li>{@link JettyClientProperties#ENABLE_SSL_HOSTNAME_VERIFICATION}</li>
  * <li>{@link JettyClientProperties#PREEMPTIVE_BASIC_AUTHENTICATION}</li>
- * <li>{@link JettyClientProperties#DISABLE_COOKIES}</li>
+ * <li>{@link JettyClientProperties#SYNC_LISTENER_RESPONSE_MAX_SIZE}</li>
  * </ul>
  * </p>
  * <p>
diff --git a/connectors/netty-connector/pom.xml b/connectors/netty-connector/pom.xml
index 58277d7..b7d5da7 100644
--- a/connectors/netty-connector/pom.xml
+++ b/connectors/netty-connector/pom.xml
@@ -49,11 +49,6 @@
             <version>${project.version}</version>
             <scope>test</scope>
         </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <scope>test</scope>
-        </dependency>
     </dependencies>
 
     <build>
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
index 17e55a9..bf34699 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyClientProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2022 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
@@ -53,4 +53,19 @@
      *  </p>
      */
     public static final String MAX_CONNECTIONS = "jersey.config.client.maxConnections";
+
+    /**
+     * <p>
+     *     Sets the endpoint identification algorithm to HTTPS.
+     * </p>
+     * <p>
+     *     The default value is {@code true} (for HTTPS uri scheme).
+     * </p>
+     * <p>
+     *     The name of the configuration property is <tt>{@value}</tt>.
+     * </p>
+     * @since 2.35
+     * @see javax.net.ssl.SSLParameters#setEndpointIdentificationAlgorithm(String)
+     */
+    public static final String ENABLE_SSL_HOSTNAME_VERIFICATION = "jersey.config.client.tls.enableHostnameVerification";
 }
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
index 8ad40ab..3e931f0 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/NettyConnector.java
@@ -32,6 +32,9 @@
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.core.Configuration;
@@ -58,8 +61,11 @@
 import io.netty.handler.codec.http.HttpUtil;
 import io.netty.handler.codec.http.HttpVersion;
 import io.netty.handler.proxy.HttpProxyHandler;
+import io.netty.handler.ssl.ApplicationProtocolConfig;
 import io.netty.handler.ssl.ClientAuth;
+import io.netty.handler.ssl.IdentityCipherSuiteFilter;
 import io.netty.handler.ssl.JdkSslContext;
+import io.netty.handler.ssl.SslHandler;
 import io.netty.handler.stream.ChunkedWriteHandler;
 import io.netty.handler.timeout.IdleState;
 import io.netty.handler.timeout.IdleStateEvent;
@@ -216,15 +222,9 @@
                     protected void initChannel(SocketChannel ch) throws Exception {
                      ChannelPipeline p = ch.pipeline();
 
-                     // Enable HTTPS if necessary.
-                     if ("https".equals(requestUri.getScheme())) {
-                         // making client authentication optional for now; it could be extracted to configurable property
-                         JdkSslContext jdkSslContext = new JdkSslContext(client.getSslContext(), true, ClientAuth.NONE);
-                         p.addLast(jdkSslContext.newHandler(ch.alloc()));
-                     }
+                     Configuration config = jerseyRequest.getConfiguration();
 
                      // http proxy
-                     Configuration config = jerseyRequest.getConfiguration();
                      final Object proxyUri = config.getProperties().get(ClientProperties.PROXY_URI);
                      if (proxyUri != null) {
                          final URI u = getProxyUri(proxyUri);
@@ -234,9 +234,37 @@
                          final String password = ClientProperties.getValue(
                                  config.getProperties(), ClientProperties.PROXY_PASSWORD, String.class);
 
-                         p.addLast(new HttpProxyHandler(new InetSocketAddress(u.getHost(),
-                                                                              u.getPort() == -1 ? 8080 : u.getPort()),
-                                                        userName, password));
+                         InetSocketAddress proxyAddr = new InetSocketAddress(u.getHost(),
+                                                                             u.getPort() == -1 ? 8080 : u.getPort());
+                         p.addLast(userName == null ? new HttpProxyHandler(proxyAddr)
+                                                    : new HttpProxyHandler(proxyAddr, userName, password));
+                     }
+
+                     // Enable HTTPS if necessary.
+                     if ("https".equals(requestUri.getScheme())) {
+                         // making client authentication optional for now; it could be extracted to configurable property
+                         JdkSslContext jdkSslContext = new JdkSslContext(
+                                 client.getSslContext(),
+                                 true,
+                                 (Iterable) null,
+                                 IdentityCipherSuiteFilter.INSTANCE,
+                                 (ApplicationProtocolConfig) null,
+                                 ClientAuth.NONE,
+                                 (String[]) null, /* enable default protocols */
+                                 false /* true if the first write request shouldn't be encrypted */
+                         );
+                         int port = requestUri.getPort();
+                         SslHandler sslHandler = jdkSslContext.newHandler(ch.alloc(), requestUri.getHost(),
+                                                                          port <= 0 ? 443 : port, executorService);
+                         if (ClientProperties.getValue(config.getProperties(),
+                                                       NettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION, true)) {
+                            SSLEngine sslEngine = sslHandler.engine();
+                            SSLParameters sslParameters = sslEngine.getSSLParameters();
+                            sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
+                            sslEngine.setSSLParameters(sslParameters);
+                         }
+
+                         p.addLast(sslHandler);
                      }
 
                      p.addLast(new HttpClientCodec());
diff --git a/connectors/pom.xml b/connectors/pom.xml
index d472f4b..ade8b73 100644
--- a/connectors/pom.xml
+++ b/connectors/pom.xml
@@ -35,6 +35,7 @@
 
     <modules>
         <module>apache-connector</module>
+        <module>apache5-connector</module>
         <module>grizzly-connector</module>
         <module>helidon-connector</module>
         <module>jdk-connector</module>
@@ -67,7 +68,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/containers/grizzly2-http/pom.xml b/containers/grizzly2-http/pom.xml
index 8173ba3..bddcf00 100644
--- a/containers/grizzly2-http/pom.xml
+++ b/containers/grizzly2-http/pom.xml
@@ -52,7 +52,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/containers/jdk-http/pom.xml b/containers/jdk-http/pom.xml
index 7b1d28d..4fb6f49 100644
--- a/containers/jdk-http/pom.xml
+++ b/containers/jdk-http/pom.xml
@@ -34,13 +34,14 @@
 
     <dependencies>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
+            <groupId>commons-io</groupId>
+            <artifactId>commons-io</artifactId>
             <scope>test</scope>
+            <version>${commons.io.version}</version>
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
index a1fc7b3..3dae9c4 100644
--- a/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
+++ b/containers/jdk-http/src/test/java/org/glassfish/jersey/jdkhttp/JdkHttpsServerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -30,13 +30,12 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLHandshakeException;
 
+import org.apache.commons.io.IOUtils;
 import org.glassfish.jersey.SslConfigurator;
 import org.glassfish.jersey.server.ResourceConfig;
 
 import org.junit.Test;
 
-import com.google.common.io.ByteStreams;
-
 import com.sun.net.httpserver.HttpServer;
 import com.sun.net.httpserver.HttpsConfigurator;
 import com.sun.net.httpserver.HttpsServer;
@@ -179,9 +178,9 @@
 
 
         final SslConfigurator sslConfigClient = SslConfigurator.newInstance()
-                .trustStoreBytes(ByteStreams.toByteArray(trustStore))
+                .trustStoreBytes(IOUtils.toByteArray(trustStore))
                 .trustStorePassword(TRUSTSTORE_CLIENT_PWD)
-                .keyStoreBytes(ByteStreams.toByteArray(keyStore))
+                .keyStoreBytes(IOUtils.toByteArray(keyStore))
                 .keyPassword(KEYSTORE_CLIENT_PWD);
 
         return sslConfigClient.createSSLContext();
@@ -192,9 +191,9 @@
         final InputStream keyStore = JdkHttpsServerTest.class.getResourceAsStream(KEYSTORE_SERVER_FILE);
 
         final SslConfigurator sslConfigServer = SslConfigurator.newInstance()
-                .keyStoreBytes(ByteStreams.toByteArray(keyStore))
+                .keyStoreBytes(IOUtils.toByteArray(keyStore))
                 .keyPassword(KEYSTORE_SERVER_PWD)
-                .trustStoreBytes(ByteStreams.toByteArray(trustStore))
+                .trustStoreBytes(IOUtils.toByteArray(trustStore))
                 .trustStorePassword(TRUSTSTORE_SERVER_PWD);
 
         return sslConfigServer.createSSLContext();
diff --git a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
index 81205c0..bb39876 100644
--- a/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
+++ b/containers/jersey-servlet-core/src/main/java/org/glassfish/jersey/servlet/internal/ResponseWriter.java
@@ -233,6 +233,7 @@
             }
         } finally {
             requestTimeoutHandler.close();
+            responseContext.completeExceptionally(error);
             rethrow(error);
         }
     }
diff --git a/containers/jetty-http/pom.xml b/containers/jetty-http/pom.xml
index 180b821..48523f2 100644
--- a/containers/jetty-http/pom.xml
+++ b/containers/jetty-http/pom.xml
@@ -63,7 +63,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/containers/netty-http/pom.xml b/containers/netty-http/pom.xml
index ff8d536..894c547 100644
--- a/containers/netty-http/pom.xml
+++ b/containers/netty-http/pom.xml
@@ -44,7 +44,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/containers/simple-http/pom.xml b/containers/simple-http/pom.xml
index af27e4a..f9a3206 100644
--- a/containers/simple-http/pom.xml
+++ b/containers/simple-http/pom.xml
@@ -51,7 +51,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/core-client/pom.xml b/core-client/pom.xml
index 9f9c825..2b6a03a 100644
--- a/core-client/pom.xml
+++ b/core-client/pom.xml
@@ -134,7 +134,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/core-common/pom.xml b/core-common/pom.xml
index 1a8fa0f..6c4716c 100644
--- a/core-common/pom.xml
+++ b/core-common/pom.xml
@@ -223,7 +223,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/core-common/src/main/java/org/glassfish/jersey/internal/OsgiRegistry.java b/core-common/src/main/java/org/glassfish/jersey/internal/OsgiRegistry.java
index b5305c3..cb7545f 100644
--- a/core-common/src/main/java/org/glassfish/jersey/internal/OsgiRegistry.java
+++ b/core-common/src/main/java/org/glassfish/jersey/internal/OsgiRegistry.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 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
@@ -115,7 +115,7 @@
                 final ClassLoader loader,
                 final boolean ignoreOnClassNotFound) {
 
-            final List<Class<?>> providerClasses = locateAllProviders(serviceName);
+            final List<Class<?>> providerClasses = locateAllProviders(serviceClass);
             if (!providerClasses.isEmpty()) {
                 return new Iterator<T>() {
 
@@ -153,7 +153,7 @@
         @Override
         public <T> Iterator<Class<T>> createClassIterator(
                 final Class<T> service, final String serviceName, final ClassLoader loader, final boolean ignoreOnClassNotFound) {
-            final List<Class<?>> providerClasses = locateAllProviders(serviceName);
+            final List<Class<?>> providerClasses = locateAllProviders(service);
             if (!providerClasses.isEmpty()) {
                 return new Iterator<Class<T>>() {
 
@@ -552,14 +552,22 @@
         }
     }
 
-    private List<Class<?>> locateAllProviders(final String serviceName) {
+    private List<Class<?>> locateAllProviders(final Class<?> serviceClass) {
         lock.readLock().lock();
         try {
             final List<Class<?>> result = new LinkedList<Class<?>>();
             for (final Map<String, Callable<List<Class<?>>>> value : factories.values()) {
-                if (value.containsKey(serviceName)) {
+                if (value.containsKey(serviceClass.getName())) {
                     try {
-                        result.addAll(value.get(serviceName).call());
+                        for (final Class<?> clazz : value.get(serviceClass.getName()).call()) {
+                            if (serviceClass.isAssignableFrom(clazz)) {
+                                result.add(clazz);
+                            } else if (LOGGER.isLoggable(Level.FINER)) {
+                                LOGGER.log(Level.FINER,
+                                    "Ignoring provider class " + clazz.getName() + " because it is not assignable to "
+                                    + " service class " + serviceClass.getName());
+                            }
+                        }
                     } catch (final Exception ex) {
                         // ignore
                     }
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java b/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
index 00a1968..7a797a0 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/ClientLoggingFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -64,6 +64,7 @@
      *                      logging filter will print (and buffer in memory) only the specified number of bytes
      *                      and print "...more..." string at the end. Negative values are interpreted as zero.
      *  separator      delimiter for particular log lines. Default is Linux new line delimiter
+     *  redactHeaders  a collection of HTTP headers to be redacted when logging.
      */
     public ClientLoggingFilter(LoggingFeature.LoggingFeatureBuilder builder) {
         super(builder);
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeature.java b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeature.java
index f0c3ffd..a9a39ba 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeature.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeature.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -16,6 +16,8 @@
 
 package org.glassfish.jersey.logging;
 
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Map;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -23,6 +25,7 @@
 import jakarta.ws.rs.RuntimeType;
 import jakarta.ws.rs.core.Feature;
 import jakarta.ws.rs.core.FeatureContext;
+import jakarta.ws.rs.core.HttpHeaders;
 
 import org.glassfish.jersey.CommonProperties;
 
@@ -41,6 +44,7 @@
  * <li>{@link #LOGGING_FEATURE_VERBOSITY}</li>
  * <li>{@link #LOGGING_FEATURE_MAX_ENTITY_SIZE}</li>
  * <li>{@link #LOGGING_FEATURE_SEPARATOR}</li>
+ * <li>{@link #LOGGING_FEATURE_REDACT_HEADERS}</li>
  * </ul>
  * <p>
  * If any of the configuration value is not set, following default values are applied:
@@ -49,6 +53,8 @@
  * <li>logger level: {@link Level#FINE}</li>
  * <li>verbosity: {@link Verbosity#PAYLOAD_TEXT}</li>
  * <li>maximum entity size: {@value #DEFAULT_MAX_ENTITY_SIZE}</li>
+ * <li>line separator: {@link #DEFAULT_SEPARATOR}</li>
+ * <li>redact headers: {@value #DEFAULT_REDACT_HEADERS}</li>
  * </ul>
  * <p>
  * Server configurable properties:
@@ -58,6 +64,7 @@
  * <li>{@link #LOGGING_FEATURE_VERBOSITY_SERVER}</li>
  * <li>{@link #LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER}</li>
  * <li>{@link #LOGGING_FEATURE_SEPARATOR_SERVER}</li>
+ * <li>{@link #LOGGING_FEATURE_REDACT_HEADERS_SERVER}</li>
  * </ul>
  * Client configurable properties:
  * <ul>
@@ -66,6 +73,7 @@
  * <li>{@link #LOGGING_FEATURE_VERBOSITY_CLIENT}</li>
  * <li>{@link #LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT}</li>
  * <li>{@link #LOGGING_FEATURE_SEPARATOR_CLIENT}</li>
+ * <li>{@link #LOGGING_FEATURE_REDACT_HEADERS_CLIENT}</li>
  * </ul>
  *
  * @author Ondrej Kosatka
@@ -93,12 +101,17 @@
      * Default separator for entity logging.
      */
     public static final String DEFAULT_SEPARATOR = "\n";
+    /**
+     * Default headers to be redacted. If multiple, separate each header with a semicolon.
+     */
+    public static final String DEFAULT_REDACT_HEADERS = HttpHeaders.AUTHORIZATION;
 
     private static final String LOGGER_NAME_POSTFIX = ".logger.name";
     private static final String LOGGER_LEVEL_POSTFIX = ".logger.level";
     private static final String VERBOSITY_POSTFIX = ".verbosity";
     private static final String MAX_ENTITY_POSTFIX = ".entity.maxSize";
     private static final String SEPARATOR_POSTFIX = ".separator";
+    private static final String REDACT_HEADERS_POSTFIX = ".headers.redact";
     private static final String LOGGING_FEATURE_COMMON_PREFIX = "jersey.config.logging";
     /**
      * Common logger name property.
@@ -120,6 +133,10 @@
      * Common property for configuring logging separator.
      */
     public static final String LOGGING_FEATURE_SEPARATOR = LOGGING_FEATURE_COMMON_PREFIX + SEPARATOR_POSTFIX;
+    /**
+     * Common property for configuring headers to be redacted. The headers are semicolon-separated.
+     */
+    public static final String LOGGING_FEATURE_REDACT_HEADERS = LOGGING_FEATURE_COMMON_PREFIX + REDACT_HEADERS_POSTFIX;
 
     private static final String LOGGING_FEATURE_SERVER_PREFIX = "jersey.config.server.logging";
     /**
@@ -142,6 +159,11 @@
      * Server property for configuring separator.
      */
     public static final String LOGGING_FEATURE_SEPARATOR_SERVER = LOGGING_FEATURE_SERVER_PREFIX + SEPARATOR_POSTFIX;
+    /**
+     * Server property for configuring headers to be redacted. The headers are semicolon-separated.
+     */
+    public static final String LOGGING_FEATURE_REDACT_HEADERS_SERVER =
+            LOGGING_FEATURE_SERVER_PREFIX + REDACT_HEADERS_POSTFIX;
 
     private static final String LOGGING_FEATURE_CLIENT_PREFIX = "jersey.config.client.logging";
     /**
@@ -164,6 +186,11 @@
      * Client property for logging separator.
      */
     public static final String LOGGING_FEATURE_SEPARATOR_CLIENT = LOGGING_FEATURE_CLIENT_PREFIX + SEPARATOR_POSTFIX;
+    /**
+     * Client property for configuring headers to be redacted. The headers are semicolon-separated.
+     */
+    public static final String LOGGING_FEATURE_REDACT_HEADERS_CLIENT =
+            LOGGING_FEATURE_CLIENT_PREFIX + REDACT_HEADERS_POSTFIX;
 
     private final LoggingFeatureBuilder builder;
 
@@ -222,7 +249,6 @@
                 .level(level)
                 .verbosity(verbosity)
                 .maxEntitySize(maxEntitySize)
-                .separator(DEFAULT_SEPARATOR)
         );
 
     }
@@ -269,7 +295,7 @@
     private static LoggingFeatureBuilder configureBuilderParameters(LoggingFeatureBuilder builder,
                                                    FeatureContext context, RuntimeType runtimeType) {
 
-        final Map properties = context.getConfiguration().getProperties();
+        final Map<String, ?> properties = context.getConfiguration().getProperties();
         //get values from properties (if any)
         final String filterLoggerName = CommonProperties.getValue(
                 properties,
@@ -283,14 +309,14 @@
                 properties,
                 runtimeType == RuntimeType.SERVER ? LOGGING_FEATURE_LOGGER_LEVEL_SERVER : LOGGING_FEATURE_LOGGER_LEVEL_CLIENT,
                 CommonProperties.getValue(
-                        context.getConfiguration().getProperties(),
+                        properties,
                         LOGGING_FEATURE_LOGGER_LEVEL,
                         DEFAULT_LOGGER_LEVEL));
         final String filterSeparator = CommonProperties.getValue(
                 properties,
                 runtimeType == RuntimeType.SERVER ? LOGGING_FEATURE_SEPARATOR_SERVER : LOGGING_FEATURE_SEPARATOR_CLIENT,
                 CommonProperties.getValue(
-                        context.getConfiguration().getProperties(),
+                        properties,
                         LOGGING_FEATURE_SEPARATOR,
                         DEFAULT_SEPARATOR));
         final Verbosity filterVerbosity = CommonProperties.getValue(
@@ -310,6 +336,14 @@
                         LOGGING_FEATURE_MAX_ENTITY_SIZE,
                         DEFAULT_MAX_ENTITY_SIZE
                 ));
+        final String redactHeaders = CommonProperties.getValue(
+                properties,
+                runtimeType == RuntimeType.SERVER
+                        ? LOGGING_FEATURE_REDACT_HEADERS_SERVER : LOGGING_FEATURE_REDACT_HEADERS_CLIENT,
+                CommonProperties.getValue(
+                        properties,
+                        LOGGING_FEATURE_REDACT_HEADERS,
+                        DEFAULT_REDACT_HEADERS));
 
         final Level loggerLevel = Level.parse(filterLevel);
 
@@ -319,6 +353,8 @@
         builder.maxEntitySize = builder.maxEntitySize == null ? filterMaxEntitySize : builder.maxEntitySize;
         builder.level = builder.level == null ? loggerLevel : builder.level;
         builder.separator = builder.separator == null ? filterSeparator : builder.separator;
+        builder.redactHeaders = builder.redactHeaders == null
+                ? Arrays.asList(redactHeaders.split(";")) : builder.redactHeaders;
 
         return builder;
     }
@@ -376,6 +412,7 @@
         Integer maxEntitySize;
         Level level;
         String separator;
+        Collection<String> redactHeaders;
 
         public LoggingFeatureBuilder() {
 
@@ -400,9 +437,13 @@
             this.separator = separator;
             return this;
         }
+        public LoggingFeatureBuilder redactHeaders(Collection<String> redactHeaders) {
+            this.redactHeaders = redactHeaders;
+            return this;
+        }
 
         public LoggingFeature build() {
             return new LoggingFeature(this);
         }
     }
-}
\ No newline at end of file
+}
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeatureAutoDiscoverable.java b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeatureAutoDiscoverable.java
index ddf0473..d35a06b 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeatureAutoDiscoverable.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingFeatureAutoDiscoverable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -34,6 +34,9 @@
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE;
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT;
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER;
+import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS;
+import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT;
+import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER;
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR;
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT;
 import static org.glassfish.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_SERVER;
@@ -75,7 +78,8 @@
                 || properties.containsKey(LOGGING_FEATURE_LOGGER_LEVEL)
                 || properties.containsKey(LOGGING_FEATURE_VERBOSITY)
                 || properties.containsKey(LOGGING_FEATURE_MAX_ENTITY_SIZE)
-                || properties.containsKey(LOGGING_FEATURE_SEPARATOR);
+                || properties.containsKey(LOGGING_FEATURE_SEPARATOR)
+                || properties.containsKey(LOGGING_FEATURE_REDACT_HEADERS);
     }
 
     private boolean clientConfigured(Map properties) {
@@ -83,7 +87,8 @@
                 || properties.containsKey(LOGGING_FEATURE_LOGGER_LEVEL_CLIENT)
                 || properties.containsKey(LOGGING_FEATURE_VERBOSITY_CLIENT)
                 || properties.containsKey(LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT)
-                || properties.containsKey(LOGGING_FEATURE_SEPARATOR_CLIENT);
+                || properties.containsKey(LOGGING_FEATURE_SEPARATOR_CLIENT)
+                || properties.containsKey(LOGGING_FEATURE_REDACT_HEADERS_CLIENT);
     }
 
     private boolean serverConfigured(Map properties) {
@@ -91,6 +96,7 @@
                 || properties.containsKey(LOGGING_FEATURE_LOGGER_LEVEL_SERVER)
                 || properties.containsKey(LOGGING_FEATURE_VERBOSITY_SERVER)
                 || properties.containsKey(LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER)
-                || properties.containsKey(LOGGING_FEATURE_SEPARATOR_SERVER);
+                || properties.containsKey(LOGGING_FEATURE_SEPARATOR_SERVER)
+                || properties.containsKey(LOGGING_FEATURE_REDACT_HEADERS_SERVER);
     }
 }
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
index 550c20d..2c1f36d 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/LoggingInterceptor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -24,15 +24,21 @@
 import java.io.OutputStream;
 import java.net.URI;
 import java.nio.charset.Charset;
+import java.util.Collection;
 import java.util.Comparator;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.TreeSet;
 import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.BiConsumer;
+import java.util.function.Predicate;
 import java.util.logging.Level;
 import java.util.logging.Logger;
+import java.util.stream.Collectors;
 
 import jakarta.ws.rs.WebApplicationException;
 import jakarta.ws.rs.core.MediaType;
@@ -40,6 +46,7 @@
 import jakarta.ws.rs.ext.WriterInterceptor;
 import jakarta.ws.rs.ext.WriterInterceptorContext;
 
+import org.glassfish.jersey.internal.guava.Predicates;
 import org.glassfish.jersey.logging.LoggingFeature.Verbosity;
 import org.glassfish.jersey.message.MessageUtils;
 
@@ -104,6 +111,7 @@
     final Verbosity verbosity;
     final int maxEntitySize;
     final String separator;
+    final Predicate<String> redactHeaderPredicate;
 
     /**
      * Creates a logging filter using builder instance with custom logger and entity logging turned on,
@@ -117,6 +125,7 @@
      *                      logging filter will print (and buffer in memory) only the specified number of bytes
      *                      and print "...more..." string at the end. Negative values are interpreted as zero.
      *  separator      delimiter for particular log lines. Default is Linux new line delimiter
+     *  redactHeaders  a collection of HTTP headers to be redacted when logging.
      */
 
     LoggingInterceptor(LoggingFeature.LoggingFeatureBuilder builder) {
@@ -125,6 +134,9 @@
         this.verbosity = builder.verbosity;
         this.maxEntitySize = Math.max(0, builder.maxEntitySize);
         this.separator = builder.separator;
+        this.redactHeaderPredicate = builder.redactHeaders != null && !builder.redactHeaders.isEmpty()
+                ? new RedactHeaderPredicate(builder.redactHeaders)
+                : header -> false;
     }
 
     /**
@@ -169,20 +181,28 @@
             final List<?> val = headerEntry.getValue();
             final String header = headerEntry.getKey();
 
-            if (val.size() == 1) {
-                prefixId(b, id).append(prefix).append(header).append(": ").append(val.get(0)).append(separator);
-            } else {
-                final StringBuilder sb = new StringBuilder();
+            prefixId(b, id).append(prefix).append(header).append(": ");
+            getValuesAppender(header, val).accept(b, val);
+            b.append(separator);
+        }
+    }
+
+    private BiConsumer<StringBuilder, List<?>> getValuesAppender(String header, List<?> values) {
+        if (redactHeaderPredicate.test(header)) {
+            return (b, v) -> b.append("[redacted]");
+        } else if (values.size() == 1) {
+            return (b, v) -> b.append(v.get(0));
+        } else {
+            return (b, v) -> {
                 boolean add = false;
-                for (final Object s : val) {
+                for (final Object s : v) {
                     if (add) {
-                        sb.append(',');
+                        b.append(',');
                     }
                     add = true;
-                    sb.append(s);
+                    b.append(s);
                 }
-                prefixId(b, id).append(prefix).append(header).append(": ").append(sb.toString()).append(separator);
-            }
+            };
         }
     }
 
@@ -305,11 +325,31 @@
             if ((off | len | ba.length - (len + off) | off + len) < 0) {
                 throw new IndexOutOfBoundsException();
             }
-            if ((baos.size() + len) <= maxEntitySize) {
+            if (baos.size() <= maxEntitySize) {
                 baos.write(ba, off, len);
             }
             out.write(ba, off, len);
         }
     }
 
+    private static final class RedactHeaderPredicate implements Predicate<String> {
+        private final Set<String> headersToRedact;
+
+        RedactHeaderPredicate(Collection<String> headersToRedact) {
+            this.headersToRedact = headersToRedact.stream()
+                    .filter(Objects::nonNull)
+                    .filter(Predicates.not(String::isEmpty))
+                    .map(RedactHeaderPredicate::normalize)
+                    .collect(Collectors.toSet());
+        }
+
+        @Override
+        public boolean test(String header) {
+            return headersToRedact.contains(normalize(header));
+        }
+
+        private static String normalize(String input) {
+            return input.trim().toLowerCase(Locale.ROOT);
+        }
+    }
 }
diff --git a/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java b/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
index 8f7fc5f..7430859 100644
--- a/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
+++ b/core-common/src/main/java/org/glassfish/jersey/logging/ServerLoggingFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -64,6 +64,7 @@
      *                      logging filter will print (and buffer in memory) only the specified number of bytes
      *                      and print "...more..." string at the end. Negative values are interpreted as zero.
      *  separator      delimiter for particular log lines. Default is Linux new line delimiter
+     *  redactHeaders  a collection of HTTP headers to be redacted when logging.
      */
     public ServerLoggingFilter(final LoggingFeature.LoggingFeatureBuilder builder) {
         super(builder);
diff --git a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
index 59ec988..7e70d3b 100644
--- a/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
+++ b/core-common/src/main/java/org/glassfish/jersey/message/internal/InboundMessageContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 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
@@ -754,6 +754,9 @@
      * @return context message body workers.
      */
     public MessageBodyWorkers getWorkers() {
+        if (workers == null) {
+            throw new ProcessingException(LocalizationMessages.RESPONSE_CLOSED());
+        }
         return workers;
     }
 
@@ -948,6 +951,7 @@
      */
     public void close() {
         entityContent.close(true);
+        setWorkers(null);
     }
 
     /**
diff --git a/core-server/pom.xml b/core-server/pom.xml
index de48191..b72ee2f 100644
--- a/core-server/pom.xml
+++ b/core-server/pom.xml
@@ -226,7 +226,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java b/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java
index c45b3bb..0c7020d 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/ContainerResponse.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 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
@@ -388,6 +388,7 @@
             closed = true;
             messageContext.close();
             requestContext.getResponseWriter().commit();
+            requestContext.setWorkers(null);
         }
     }
 
diff --git a/core-server/src/main/java/org/glassfish/jersey/server/model/internal/AbstractJavaResourceMethodDispatcher.java b/core-server/src/main/java/org/glassfish/jersey/server/model/internal/AbstractJavaResourceMethodDispatcher.java
index dfc7c21..0a3d6a3 100644
--- a/core-server/src/main/java/org/glassfish/jersey/server/model/internal/AbstractJavaResourceMethodDispatcher.java
+++ b/core-server/src/main/java/org/glassfish/jersey/server/model/internal/AbstractJavaResourceMethodDispatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2022 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
@@ -25,13 +25,15 @@
 import java.util.concurrent.CompletionStage;
 import java.util.concurrent.ExecutionException;
 
+import jakarta.validation.ValidationException;
 import jakarta.ws.rs.ProcessingException;
 import jakarta.ws.rs.WebApplicationException;
+import jakarta.ws.rs.client.ResponseProcessingException;
 import jakarta.ws.rs.core.Response;
 import jakarta.ws.rs.core.SecurityContext;
 
-import jakarta.validation.ValidationException;
-
+import org.glassfish.jersey.message.internal.OutboundJaxrsResponse;
+import org.glassfish.jersey.message.internal.OutboundMessageContext;
 import org.glassfish.jersey.message.internal.TracingLogger;
 import org.glassfish.jersey.server.ContainerRequest;
 import org.glassfish.jersey.server.SubjectSecurityContext;
@@ -77,6 +79,14 @@
         Response response = null;
         try {
             response = doDispatch(resource, request);
+            if (response instanceof OutboundJaxrsResponse) {
+                OutboundJaxrsResponse responseImpl = (OutboundJaxrsResponse) response;
+                OutboundMessageContext context = responseImpl.getContext();
+                if (context.isCommitted()) {
+                    // Response was already committed. This response is being reused more than 1 time.
+                    throw new ResponseProcessingException(response, LocalizationMessages.ERROR_RESPONSE_ALREADY_COMMITED());
+                }
+            }
         } finally {
             TracingLogger.getInstance(request).log(ServerTraceEvent.DISPATCH_RESPONSE, response);
         }
diff --git a/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties b/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
index 7c18301..7a482f2 100644
--- a/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
+++ b/core-server/src/main/resources/org/glassfish/jersey/server/internal/localization.properties
@@ -72,6 +72,7 @@
 error.request.abort.in.response.phase=The request cannot be aborted as it is already in the response processing phase.
 error.request.set.entity.stream.in.response.phase=The entity stream cannot be set in the request as it is already in the response processing phase.
 error.request.set.security.context.in.response.phase=The security context cannot be set in the request as it is already in the response processing phase.
+error.response.already.commited=The response entity was already committed. The Response entity is being reused more than once.
 error.scanning.class.not.found=A class file of the class name, {0}, is identified but the class could not be found.
 error.sub.resource.locator.more.resources=Sub resource locator returned {0} in the resource model. Exactly one resource must be returned.
 error.suspending.chunked.output.response=Attempt to suspend a client connection associated with a chunked output has failed in the underlying container.
diff --git a/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java b/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
index d152789..bdf4ef5 100644
--- a/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
+++ b/core-server/src/test/java/org/glassfish/jersey/server/RequestContextBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2022 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
@@ -80,31 +80,33 @@
         public void setWorkers(final MessageBodyWorkers workers) {
             super.setWorkers(workers);
             final byte[] entityBytes;
-            if (entity != null) {
-                final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
-                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                OutputStream stream = null;
-                try {
-                    stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
-                            new Annotation[0], getMediaType(),
-                            myMap,
-                            propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
-                } catch (final IOException | WebApplicationException ex) {
-                    Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
-                } finally {
-                    if (stream != null) {
-                        try {
-                            stream.close();
-                        } catch (final IOException e) {
-                            // ignore
+            if (workers != null) {
+                if (entity != null) {
+                    final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    OutputStream stream = null;
+                    try {
+                        stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
+                                new Annotation[0], getMediaType(),
+                                myMap,
+                                propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
+                    } catch (final IOException | WebApplicationException ex) {
+                        Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
+                    } finally {
+                        if (stream != null) {
+                            try {
+                                stream.close();
+                            } catch (final IOException e) {
+                                // ignore
+                            }
                         }
                     }
+                    entityBytes = baos.toByteArray();
+                } else {
+                    entityBytes = new byte[0];
                 }
-                entityBytes = baos.toByteArray();
-            } else {
-                entityBytes = new byte[0];
+                setEntityStream(new ByteArrayInputStream(entityBytes));
             }
-            setEntityStream(new ByteArrayInputStream(entityBytes));
         }
     }
 
diff --git a/docs/src/main/docbook/appendix-properties.xml b/docs/src/main/docbook/appendix-properties.xml
index 22cf276..a3232c6 100644
--- a/docs/src/main/docbook/appendix-properties.xml
+++ b/docs/src/main/docbook/appendix-properties.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!--
 
-    Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 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
@@ -206,6 +206,17 @@
                             See <link linkend="logging.xml">logging</link> chapter for more information.
                         </entry>
                     </row>
+                    <row>
+                        <entry>&jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS;
+                        </entry>
+                        <entry>
+                            <literal>jersey.config.logging.headers.redact</literal>
+                        </entry>
+                        <entry>
+                            The HTTP headers (semicolon separated) to be redacted when logging.
+                            See <link linkend="logging_chapter">logging</link> chapter for more information.
+                        </entry>
+                    </row>
                 </tbody>
             </tgroup>
         </table>
@@ -704,6 +715,17 @@
                             See <link linkend="logging.xml">logging</link> chapter for more information.
                         </entry>
                     </row>
+                    <row>
+                        <entry>&jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER;
+                        </entry>
+                        <entry>
+                            <literal>jersey.config.server.logging.headers.redact</literal>
+                        </entry>
+                        <entry>
+                            The HTTP headers (semicolon separated) to be redacted when logging.
+                            See <link linkend="logging_chapter">logging</link> chapter for more information.
+                        </entry>
+                    </row>
                 </tbody>
             </tgroup>
         </table>
@@ -921,7 +943,11 @@
                         <entry>
                             <para>
                                 URI of a HTTP proxy the client connector should use. Default value is not set.
-                                <emphasis>Currently supported with &jersey.apache.ApacheConnectorProvider; and
+                                <emphasis>Currently supported with &jersey.apache.ApacheConnectorProvider;,
+                                    &jersey.apache5.Apache5ConnectorProvider;,
+                                    &jersey.grizzly.GrizzlyConnectorProvider;,
+                                    &jersey.helidon.HelidonConnectorProvider;,
+                                    &jersey.netty.NettyConnectorProvider;, and
                                     &jersey.jetty.JettyConnectorProvider; only.</emphasis>
                             </para>
                         </entry>
@@ -1084,6 +1110,741 @@
                             See <link linkend="logging_chapter">logging</link> chapter for more information.
                         </entry>
                     </row>
+                    <row>
+                        <entry>&jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT;
+                        </entry>
+                        <entry>
+                            <literal>jersey.config.client.logging.headers.redact</literal>
+                        </entry>
+                        <entry>
+                            The HTTP headers (semicolon separated) to be redacted when logging.
+                            See <link linkend="logging_chapter">logging</link> chapter for more information.
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-apache">
+        <title>Apache HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.apache.ApacheClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Apache HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.CONNECTION_CLOSING_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache.client.connectionClosingStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Strategy that closes the Apache Connection.
+                                Accepts an instance of &jersey.apache.ApacheConnectionClosingStrategy;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.CONNECTION_MANAGER;</entry>
+                        <entry><literal>jersey.config.apache.client.connectionManager</literal></entry>
+                        <entry>
+                            <para>
+                                Connection Manager which will be used to create
+                                <literal>org.apache.http.client.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.conn.HttpClientConnectionManager</literal>
+                            </para>
+                            <para>
+                                If the property is absent a default Connection Manager will be used
+                                <literal>org.apache.http.impl.conn.BasicHttpClientConnectionManager</literal>.
+                                If you want to use this client in multi-threaded environment, be sure you override default value with
+                                <literal>org.apache.http.impl.conn.PoolingHttpClientConnectionManager</literal> instance.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.CONNECTION_MANAGER_SHARED;</entry>
+                        <entry><literal>jersey.config.apache.client.connectionManagerShared</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.true; indicates that configured connection manager should be shared
+                                among multiple Jersey client runtime instances. It means that closing
+                                a particular client runtime instance does not shut down the underlying
+                                connection manager automatically. In such case, the connection manager life-cycle
+                                should be fully managed by the application code. To release all allocated resources,
+                                caller code should especially ensure
+                                <literal>org.apache.http.conn.HttpClientConnectionManager#shutdown()</literal> gets
+                                invoked eventually.
+                            </para>
+                            <para>
+                                This property may only be set prior to constructing Apache connector using
+                                &jersey.apache.ApacheConnectorProvider;
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.CREDENTIALS_PROVIDER;</entry>
+                        <entry><literal>jersey.config.apache.client.credentialsProvider</literal></entry>
+                        <entry>
+                            <para>
+                                The credential provider that should be used to retrieve
+                                credentials from a user. Credentials needed for proxy authentication
+                                are stored here as well.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.client.CredentialsProvider</literal>.
+                            </para>
+                            <para>
+                                If the property is absent a default provider will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.DISABLE_COOKIES;</entry>
+                        <entry><literal>jersey.config.apache.client.handleCookies</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client should handle cookies
+                                automatically using HttpClient's default cookie policy. A value
+                                of &lit.true; will cause the client to ignore all cookies.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.KEEPALIVE_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache.client.keepAliveStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Apache <literal>ConnectionKeepAliveStrategy</literal> for the
+                                <literal>org.apache.http.client.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.conn.ConnectionKeepAliveStrategy</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default keepalive strategy of the Apache HTTP library will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION;</entry>
+                        <entry><literal>jersey.config.apache.client.preemptiveBasicAuthentication</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.true; indicates that a client should send an
+                                authentication request even before the server gives a 401
+                                response.
+                            </para>
+                            <para>
+                                This property may only be set prior to constructing Apache connector using
+                                &jersey.apache.ApacheConnectorProvider;.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.REQUEST_CONFIG;</entry>
+                        <entry><literal>jersey.config.apache.client.requestConfig</literal></entry>
+                        <entry>
+                            <para>
+                                Request configuration for the <literal>org.apache.http.client.HttpClient</literal>.
+                                Http parameters which will be used to create <literal>org.apache.http.client.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.client.config.RequestConfig</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default request configuration will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.RETRY_HANDLER;</entry>
+                        <entry><literal>jersey.config.apache.client.retryHandler</literal></entry>
+                        <entry>
+                            <para>
+                                Apache <literal>HttpRequestRetryHandler</literal> which will be used to create
+                                <literal>org.apache.http.client.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.client.HttpRequestRetryHandler</literal>.
+                            </para>
+                            <para>
+                                If the property is absent a default retry handler will be used
+                                (<literal>org.apache.http.impl.client.DefaultHttpRequestRetryHandler</literal>).
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.REUSE_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache.client.reuseStrategy</literal></entry>
+                        <entry>
+                            <para>
+                               Apache <literal>ConnectionReuseStrategy</literal> for the
+                                <literal>org.apache.http.client.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.http.ConnectionReuseStrategy</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default reuse strategy of the Apache HTTP library will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache.ApacheClientProperties.USE_SYSTEM_PROPERTIES;</entry>
+                        <entry><literal>jersey.config.apache.client.useSystemProperties</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client will use default Apache &lit.jersey.client.Connector;
+                                params. A value of &lit.true; will cause the client to take into account the system properties
+                                <literal>https.protocols</literal>, <literal>https.cipherSuites</literal>,
+                                <literal>http.keepAlive</literal>, <literal>http.maxConnections</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of &lit.jdk6.Boolean;
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-apache5">
+        <title>Apache 5 HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.apache5.Apache5ClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Apache 5 HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache5.client.connectionClosingStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Strategy that closes the Apache Connection.
+                                Accepts an instance of &jersey.apache5.Apache5ConnectionClosingStrategy;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.CONNECTION_MANAGER;</entry>
+                        <entry><literal>jersey.config.apache5.client.connectionManager</literal></entry>
+                        <entry>
+                            <para>
+                                Connection Manager which will be used to create
+                                <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.client5.http.io.HttpClientConnectionManager</literal>
+                            </para>
+                            <para>
+                                If the property is absent a default Connection Manager will be used
+                                <literal>org.apache.hc.client5.http.impl.io.BasicHttpClientConnectionManager</literal>.
+                                If you want to use this client in multi-threaded environment, be sure you override default value with
+                                <literal>org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager</literal> instance.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.CONNECTION_MANAGER_SHARED;</entry>
+                        <entry><literal>jersey.config.apache5.client.connectionManagerShared</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.true; indicates that configured connection manager should be shared
+                                among multiple Jersey client runtime instances. It means that closing
+                                a particular client runtime instance does not shut down the underlying
+                                connection manager automatically. In such case, the connection manager life-cycle
+                                should be fully managed by the application code. To release all allocated resources,
+                                caller code should especially ensure
+                                <literal>org.apache.hc.client5.http.io.HttpClientConnectionManager#close()</literal> gets
+                                invoked eventually.
+                            </para>
+                            <para>
+                                This property may only be set prior to constructing Apache connector using
+                                &jersey.apache5.Apache5ConnectorProvider;
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.CREDENTIALS_PROVIDER;</entry>
+                        <entry><literal>jersey.config.apache5.client.credentialsProvider</literal></entry>
+                        <entry>
+                            <para>
+                                The credential provider that should be used to retrieve
+                                credentials from a user. Credentials needed for proxy authentication
+                                are stored here as well.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.client5.http.auth.CredentialsProvider</literal>.
+                            </para>
+                            <para>
+                                If the property is absent a default provider will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.DISABLE_COOKIES;</entry>
+                        <entry><literal>jersey.config.apache5.client.handleCookies</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client should handle cookies
+                                automatically using HttpClient's default cookie policy. A value
+                                of &lit.true; will cause the client to ignore all cookies.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.KEEPALIVE_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache5.client.keepAliveStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Apache <literal>ConnectionKeepAliveStrategy</literal> for the
+                                <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.client5.http.ConnectionKeepAliveStrategy</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default keepalive strategy of the Apache HTTP library will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION;</entry>
+                        <entry><literal>jersey.config.apache5.client.preemptiveBasicAuthentication</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.true; indicates that a client should send an
+                                authentication request even before the server gives a 401
+                                response.
+                            </para>
+                            <para>
+                                This property may only be set prior to constructing Apache connector using
+                                &jersey.apache5.Apache5ConnectorProvider;.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>java.lang.Boolean</literal>.
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.REQUEST_CONFIG;</entry>
+                        <entry><literal>jersey.config.apache5.client.requestConfig</literal></entry>
+                        <entry>
+                            <para>
+                                Request configuration for the <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                                Http parameters which will be used to create <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.client5.http.config.RequestConfig</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default request configuration will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.RETRY_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache5.client.retryStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Apache <literal>HttpRequestRetryStrategy</literal> which will be used to create
+                                <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.client5.http.HttpRequestRetryStrategy</literal>.
+                            </para>
+                            <para>
+                                If the property is absent a default retry handler will be used
+                                (<literal>org.apache.hc.client5.http.impl.DefaultHttpRequestRetryStrategy</literal>).
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.REUSE_STRATEGY;</entry>
+                        <entry><literal>jersey.config.apache5.client.reuseStrategy</literal></entry>
+                        <entry>
+                            <para>
+                                Apache <literal>ConnectionReuseStrategy</literal> for the
+                                <literal>org.apache.hc.client5.http.classic.HttpClient</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.apache.hc.core5.http.ConnectionReuseStrategy</literal>.
+                            </para>
+                            <para>
+                                If the property is absent the default reuse strategy of the Apache HTTP library will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.apache5.Apache5ClientProperties.USE_SYSTEM_PROPERTIES;</entry>
+                        <entry><literal>jersey.config.apache5.client.useSystemProperties</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client will use default Apache &lit.jersey.client.Connector;
+                                params. A value of &lit.true; will cause the client to take into account the system properties
+                                <literal>https.protocols</literal>, <literal>https.cipherSuites</literal>,
+                                <literal>http.keepAlive</literal>, <literal>http.maxConnections</literal>.
+                            </para>
+                            <para>
+                                The value MUST be an instance of &lit.jdk6.Boolean;
+                            </para>
+                            <para>
+                                The default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-helidon">
+        <title>Helidon HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.helidon.HelidonClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Helidon HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.helidon.HelidonClientProperties.CONFIG;</entry>
+                        <entry><literal>jersey.connector.helidon.config</literal></entry>
+                        <entry>
+                            <para>
+                                A Helidon <literal>io.helidon.Config</literal> instance that is passed to
+                                <literal>io.helidon.webclient.WebClient.Builder#config(Config)</literal> if available.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-jdk">
+        <title>JDK HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.jdk.JdkClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Jdk HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.CONTAINER_IDLE_TIMEOUT;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.containerIdleTimeout</literal></entry>
+                        <entry>
+                            <para>
+                                Container idle timeout in milliseconds <literal>Integer</literal> value).
+                            </para>
+                            <para>
+                                The default value is <literal>java.net.CookiePolicy#ACCEPT_ORIGINAL_SERVER</literal>.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.COOKIE_POLICY;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.cookiePolicy</literal></entry>
+                        <entry>
+                            <para>
+                                To set the cookie policy of this cookie manager.
+                            </para>
+                            <para>
+                                When the timeout elapses, the shared thread pool will be destroyed.
+                            </para>
+                            <para>
+                                The default value is &jersey.jdk.JdkClientProperties.DEFAULT_CONNECTION_CLOSE_WAIT;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.CONNECTION_IDLE_TIMEOUT;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.connectionIdleTimeout</literal></entry>
+                        <entry>
+                            <para>
+                                An amount of time in milliseconds (<literal>Integer</literal> value) during which an idle
+                                connection will be kept open.
+                            </para>
+                            <para>
+                                The default value is &jersey.jdk.JdkClientProperties.DEFAULT_CONNECTION_IDLE_TIMEOUT;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.MAX_CONNECTIONS_PER_DESTINATION;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.maxConnectionsPerDestination</literal></entry>
+                        <entry>
+                            <para>
+                                A maximum number of open connections per each destination. A destination is determined by the
+                                following triple: <literal>host</literal>, <literal>port</literal>,
+                                <literal>protocol (HTTP/HTTPS)</literal>.
+                            </para>
+                            <para>
+                                The default value is &jersey.jdk.JdkClientProperties.DEFAULT_MAX_CONNECTIONS_PER_DESTINATION;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.MAX_HEADER_SIZE;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.maxHeaderSize</literal></entry>
+                        <entry>
+                            <para>
+                                A configurable property of HTTP parser. It defines the maximal acceptable size of HTTP response
+                                initial line, each header and chunk header.
+                            </para>
+                            <para>
+                                The default value is &jersey.jdk.JdkClientProperties.DEFAULT_MAX_HEADER_SIZE;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.MAX_REDIRECTS;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.maxRedirects</literal></entry>
+                        <entry>
+                            <para>
+                                The maximal number of redirects during single request.
+                            </para>
+                            <para>
+                                Value is expected to be positive <literal>Integer</literal>. The default value is
+                                &jersey.jdk.JdkClientProperties.DEFAULT_MAX_REDIRECTS;.
+                            </para>
+                            <para>
+                                HTTP redirection must be enabled by property &jersey.client.ClientProperties.FOLLOW_REDIRECTS;,
+                                otherwise &jersey.jdk.JdkClientProperties.MAX_REDIRECTS; is not applied.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jdk.JdkClientProperties.WORKER_THREAD_POOL_CONFIG;</entry>
+                        <entry><literal>jersey.config.client.JdkConnectorProvider.workerThreadPoolConfig</literal></entry>
+                        <entry>
+                            <para>
+                                Configuration of the connector thread pool.
+                            </para>
+                            <para>
+                                An instance of <literal>org.glassfish.jersey.jdk.connector.internal.ThreadPoolConfig</literal>
+                                is expected.
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-jetty">
+        <title>Jetty HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.jetty.JettyClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Jetty HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.jetty.JettyClientProperties.DISABLE_COOKIES;</entry>
+                        <entry><literal>jersey.config.jetty.client.disableCookies</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client should handle cookies
+                                automatically using HttpClient's default cookie policy. A value
+                                of &lit.false; will cause the client to ignore all cookies.
+                            </para>
+                            <para>
+                                The value MUST be an instance of &lit.jdk6.Boolean;.
+                                If the property is absent the default value is &lit.false;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION;</entry>
+                        <entry><literal>jersey.config.jetty.client.disableCookies</literal></entry>
+                        <entry>
+                            <para>
+                                A value of &lit.false; indicates the client disable a hostname verification
+                                during SSL Handshake. A client will ignore CN value defined in a certificate
+                                that is stored in a truststore.
+                            </para>
+                            <para>
+                                The value MUST be an instance of &lit.jdk6.Boolean;.
+                                If the property is absent the default value is &lit.true;.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jetty.JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION;</entry>
+                        <entry><literal>jersey.config.jetty.client.preemptiveBasicAuthentication</literal></entry>
+                        <entry>
+                            <para>
+                                The credential provider that should be used to retrieve
+                                credentials from a user.
+                            </para>
+                            <para>
+                                If an <literal>org.eclipse.jetty.client.api.Authentication</literal> mechanism is found,
+                                it is then used for the given request, returning an
+                                <literal>org.eclipse.jetty.client.api.Authentication.Result</literal>,
+                                which is then stored in the <literal>org.eclipse.jetty.client.api.AuthenticationStore</literal>
+                                so that subsequent requests can be preemptively authenticated.
+                            </para>
+                            <para>
+                                The value MUST be an instance of <literal>org.eclipse.jetty.client.util.BasicAuthentication</literal>.
+                                If the property is absent a default provider will be used.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.jetty.JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE;</entry>
+                        <entry><literal>jersey.config.jetty.client.syncListenerResponseMaxSize</literal></entry>
+                        <entry>
+                            <para>
+                                Overrides the default Jetty synchronous listener response max buffer size.
+                                In practise, this allows you to read larger responses.
+                                Size in bytes.
+                            </para>
+                            <para>
+                                If the property is absent, the value is such as specified by Jetty (currently 2MiB).
+                            </para>
+                        </entry>
+                    </row>
+                </tbody>
+            </tgroup>
+        </table>
+    </section>
+    <section xml:id="appendix-properties-client-netty">
+        <title>Netty HTTP client configuration properties</title>
+
+        <para>
+            List of client configuration properties that can be found in &jersey.netty.NettyClientProperties; class.
+        </para>
+
+        <table>
+            <title>List of Netty HTTP client configuration properties</title>
+            <tgroup cols="3">
+                <thead>
+                    <row>
+                        <entry>Constant</entry>
+                        <entry>Value</entry>
+                        <entry>Description</entry>
+                    </row>
+                </thead>
+                <tbody>
+                    <row>
+                        <entry>&jersey.netty.NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT;</entry>
+                        <entry><literal>jersey.config.client.idleConnectionPruneTimeout</literal></entry>
+                        <entry>
+                            <para>
+                                This property determines the number of seconds the idle connections are kept in the pool before pruned.
+                                The default is 60. Specify 0 to disable.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.netty.NettyClientProperties.MAX_CONNECTIONS;</entry>
+                        <entry><literal>jersey.config.client.maxConnections</literal></entry>
+                        <entry>
+                            <para>
+                                This property determines the maximum number of idle connections that will be simultaneously kept
+                                alive, per destination. The default is 5.
+                            </para>
+                            <para>
+                                This property is a Jersey alternative to System property <literal>http.maxConnections</literal>.
+                                The Jersey property takes precedence over the system property.
+                            </para>
+                        </entry>
+                    </row>
+                    <row>
+                        <entry>&jersey.netty.NettyClientProperties.MAX_CONNECTIONS_TOTAL;</entry>
+                        <entry><literal>jersey.config.client.maxTotalConnections</literal></entry>
+                        <entry>
+                            <para>
+                                This property determines the maximum number of idle connections that will be simultaneously kept alive
+                                in total, rather than per destination. The default is 60. Specify 0 to disable.
+                            </para>
+                        </entry>
+                    </row>
                 </tbody>
             </tgroup>
         </table>
diff --git a/docs/src/main/docbook/client.xml b/docs/src/main/docbook/client.xml
index 4814b9d..1ba38d2 100644
--- a/docs/src/main/docbook/client.xml
+++ b/docs/src/main/docbook/client.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!--
 
-    Copyright (c) 2010, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2010, 2022 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
@@ -646,6 +646,16 @@
                             <entry><literal>org.glassfish.jersey.connectors:jersey-apache-connector</literal></entry>
                         </row>
                         <row>
+                            <entry>Apache 5 HTTP client</entry>
+                            <entry>&jersey.apache5.Apache5ConnectorProvider;</entry>
+                            <entry><literal>org.glassfish.jersey.connectors:jersey-apache5-connector</literal></entry>
+                        </row>
+                        <row>
+                            <entry>Helidon HTTP client</entry>
+                            <entry>&jersey.helidon.HelidonConnectorProvider;</entry>
+                            <entry><literal>org.glassfish.jersey.connectors:jersey-helidon-connector</literal></entry>
+                        </row>
+                        <row>
                             <entry>Jetty HTTP client</entry>
                             <entry>&jersey.jetty.JettyConnectorProvider;</entry>
                             <entry><literal>org.glassfish.jersey.connectors:jersey-jetty-connector</literal></entry>
@@ -751,6 +761,89 @@
             register &lit.jersey.client.Connector; instances in the Jersey &jersey.client.ClientConfig;. The new
             &lit.jersey.client.ConnectorProvider; SPI must be used instead to configure a custom client-side transport connector.
         </para>
+        <section>
+            <title>Client Connectors Properties</title>
+            <para>
+                For each &jersey.client.Connector; a property file defining properties tweaking the actual
+                &lit.jersey.client.Connector; exists. There are &jersey.client.ClientProperties; properties that apply to the
+                default &jersey.client.HttpUrlConnectorProvider;. Many of the properties are also understood by
+                various <literal>Connectors</literal>. Each of the &lit.jersey.client.ConnectorProvider;
+                defines properties that apply to it.
+            </para>
+            <para>
+                Moreover, each &jersey.client.Connector; supports a list of properties that are unique for the
+                &jersey.client.Connector;. The list of the client connector properties can be found in the
+                <xref linkend="appendix-properties"/>.
+            </para>
+        </section>
+        <section>
+            <title>Applying additional settings to Connectors</title>
+            <para>
+                It is not possible to provide all the settings the underlying HTTP Clients support. For Apache HTTP Client, and
+                for Jetty HTTP Client, it is possible to access directly the HTTP Client classes and invoke setter methods there.
+            </para>
+            <section>
+                <title>Apache HttpClientBuilder Configuration</title>
+                <para>
+                    For Apache Connector, an &jersey.apache.ApacheHttpClientBuilderConfigurator; SPI allows for invoking methods
+                    of <literal>org.apache.http.impl.client.HttpClientBuilder</literal>, such as <literal>setDefaultCredentialsProvider</literal>:
+                    <programlisting language="java" linenumbering="numbered">
+                        org.apache.http.client.CredentialsProvider credentialsProvider = new org.apache.http.impl.client.BasicCredentialsProvider();
+                        credentialsProvider.setCredentials(
+                            org.apache.http.auth.AuthScope.ANY,
+                            new org.apache.http.auth.UsernamePasswordCredentials("name", "password")
+                        );
+                        ApacheHttpClientBuilderConfigurator apacheHttpClientBuilderConfigurator = (httpClientBuilder) -> {
+                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+                        };
+
+                        ClientConfig cc = new ClientConfig();
+                        cc.register(apacheHttpClientBuilderConfigurator);
+                        cc.connectorProvider(new ApacheConnectorProvider());
+                        Client client = ClientBuilder.newClient(cc);
+                        ...
+                    </programlisting>
+                </para>
+            </section>
+            <section>
+                <title>Apache 5 HttpClientBuilder Configuration</title>
+                <para>
+                    For Apache 5 Connector, an &jersey.apache5.Apache5HttpClientBuilderConfigurator; SPI allows for invoking methods
+                    of <literal>org.apache.hc.client5.http.impl.classic.HttpClientBuilder</literal>, such as <literal>setDefaultCredentialsProvider</literal>:
+                    <programlisting language="java" linenumbering="numbered">
+                        org.apache.hc.client5.http.auth.CredentialsStore credentialsProvider = new org.apache.hc.client5.http.impl.auth.BasicCredentialsProvider();
+                        credentialsProvider.setCredentials(
+                            new org.apache.hc.client5.http.auth.AuthScope("localhost", getPort()),
+                            new org.apache.hc.client5.http.auth.UsernamePasswordCredentials("name", "password".toCharArray())
+                        );
+                        Apache5HttpClientBuilderConfigurator apache5HttpClientBuilderConfigurator = (httpClientBuilder) -> {
+                            return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider);
+                        };
+
+                        ClientConfig cc = new ClientConfig();
+                        cc.register(apache5HttpClientBuilderConfigurator);
+                        cc.connectorProvider(new Apache5ConnectorProvider());
+                        Client client = ClientBuilder.newClient(cc);
+                        ...
+                    </programlisting>
+                </para>
+            </section>
+            <section>
+                <title>Jetty HttpClient Configuration</title>
+                <para>
+                    For Jetty Connector, an &jersey.jetty.JettyHttpClientSupplier; SPI allows for providing a configured instance
+                    of <literal>org.eclipse.jetty.client.HttpClient</literal>:
+                    <programlisting language="java" linenumbering="numbered">
+                        HttpClient httpClient = new HttpClient(...);
+                        ClientConfig clientConfig = new ClientConfig()
+                            .connectorProvider(new JettyConnectorProvider())
+                            .register(new JettyHttpClientSupplier(httpClient));
+                        Client client = ClientBuilder.newClient(clientConfig);
+                        ...
+                    </programlisting>
+                </para>
+            </section>
+        </section>
     </section>
 
     <section>
@@ -773,7 +866,7 @@
                     in interceptor (you don't need to register this interceptor). Check the javadoc of the
                     &jersey.client.EncodingFeature; in order to use it.</member>
                 <member>&jersey.client.HttpAuthenticationFeature;: HTTP Authentication Feature
-                    (see <xref linkend="ssl" />
+                    (see <link xlink:href="#authentication">authentication</link>
                     below).</member>
             </simplelist>
 
@@ -919,7 +1012,7 @@
         </para>
 
         <section>
-            <title>Http Authentication Support</title>
+            <title><anchor xml:id="authentication"/>Http Authentication Support</title>
             <para>Jersey supports Basic and Digest HTTP Authentication.</para>
             <important>
                 <para>
diff --git a/docs/src/main/docbook/jersey.ent b/docs/src/main/docbook/jersey.ent
index 144f7fd..4ffb0df 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -302,6 +302,35 @@
 <!ENTITY jee6.jakarta.enterprise.concurrent.ManagedScheduledExecutorService "<link xlink:href='&jee.javadoc.uri;/jakarta.enterprise/concurrent/ManagedScheduledExecutorService.html'>ManagedScheduledExecutorService</link>">
 
 <!ENTITY jersey.apache.ApacheConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheConnectorProvider.html'>ApacheConnectorProvider</link>">
+<!ENTITY jersey.apache.ApacheConnectionClosingStrategy "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheConnectionClosingStrategy.html'>ApacheConnectionClosingStrategy</link>">
+<!ENTITY jersey.apache.ApacheHttpClientBuilderConfigurator "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheHttpClientBuilderConfigurator.html'>ApacheHttpClientBuilderConfigurator</link>">
+<!ENTITY jersey.apache.ApacheClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html'>ApacheClientProperties</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.CONNECTION_CLOSING_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#CONNECTION_CLOSING_STRATEGY'>ApacheClientProperties.CONNECTION_CLOSING_STRATEGY</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.CONNECTION_MANAGER "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#CONNECTION_MANAGER'>ApacheClientProperties.CONNECTION_MANAGER</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.CONNECTION_MANAGER_SHARED "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#CONNECTION_MANAGER_SHARED'>ApacheClientProperties.CONNECTION_MANAGER_SHARED</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.CREDENTIALS_PROVIDER "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#CREDENTIALS_PROVIDER'>ApacheClientProperties.CREDENTIALS_PROVIDER</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#DISABLE_COOKIES'>ApacheClientProperties.DISABLE_COOKIES</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.KEEPALIVE_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#KEEPALIVE_STRATEGY'>ApacheClientProperties.KEEPALIVE_STRATEGY</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>ApacheClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.REQUEST_CONFIG "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#REQUEST_CONFIG'>ApacheClientProperties.REQUEST_CONFIG</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.RETRY_HANDLER "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#RETRY_HANDLER'>ApacheClientProperties.RETRY_HANDLER</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.REUSE_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#REUSE_STRATEGY'>ApacheClientProperties.REUSE_STRATEGY</link>">
+<!ENTITY jersey.apache.ApacheClientProperties.USE_SYSTEM_PROPERTIES "<link xlink:href='&jersey.javadoc.uri.prefix;/apache/connector/ApacheClientProperties.html#USE_SYSTEM_PROPERTIES'>ApacheClientProperties.USE_SYSTEM_PROPERTIES</link>">
+<!ENTITY jersey.apache5.Apache5ConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ConnectorProvider.html'>Apache5ConnectorProvider</link>">
+<!ENTITY jersey.apache5.Apache5ConnectionClosingStrategy "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ConnectionClosingStrategy.html'>Apache5ConnectionClosingStrategy</link>">
+<!ENTITY jersey.apache5.Apache5HttpClientBuilderConfigurator "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5HttpClientBuilderConfigurator.html'>Apache5HttpClientBuilderConfigurator</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html'>Apache5ClientProperties</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#CONNECTION_CLOSING_STRATEGY'>Apache5ClientProperties.CONNECTION_CLOSING_STRATEGY</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.CONNECTION_MANAGER "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#CONNECTION_MANAGER'>Apache5ClientProperties.CONNECTION_MANAGER</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.CONNECTION_MANAGER_SHARED "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#CONNECTION_MANAGER_SHARED'>Apache5ClientProperties.CONNECTION_MANAGER_SHARED</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.CREDENTIALS_PROVIDER "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#CREDENTIALS_PROVIDER'>Apache5ClientProperties.CREDENTIALS_PROVIDER</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#DISABLE_COOKIES'>ApacheC5lientProperties.DISABLE_COOKIES</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.KEEPALIVE_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#KEEPALIVE_STRATEGY'>Apache5ClientProperties.KEEPALIVE_STRATEGY</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>Apache5ClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.REQUEST_CONFIG "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#REQUEST_CONFIG'>Apache5ClientProperties.REQUEST_CONFIG</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.RETRY_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#RETRY_STRATEGY'>Apache5ClientProperties.RETRY_STRATEGY</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.REUSE_STRATEGY "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#REUSE_STRATEGY'>Apache5ClientProperties.REUSE_STRATEGY</link>">
+<!ENTITY jersey.apache5.Apache5ClientProperties.USE_SYSTEM_PROPERTIES "<link xlink:href='&jersey.javadoc.uri.prefix;/apache5/connector/Apache5ClientProperties.html#USE_SYSTEM_PROPERTIES'>Apache5ClientProperties.USE_SYSTEM_PROPERTIES</link>">
 <!ENTITY jersey.client.ChunkParser "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ChunkParser.html'>ChunkParser</link>">
 <!ENTITY jersey.client.ChunkedInput "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ChunkedInput.html'>ChunkedInput</link>">
 <!ENTITY jersey.client.ClientAsyncExecutor "<link xlink:href='&jersey.javadoc.uri.prefix;/client/ClientAsyncExecutor.html'>@ClientAsyncExecutor</link>">
@@ -415,36 +444,62 @@
 <!ENTITY jersey.grizzly.GrizzlyHttpContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/grizzly2/httpserver/GrizzlyHttpContainerProvider.html'>GrizzlyHttpContainerProvider</link>">
 <!ENTITY jersey.grizzly.GrizzlyHttpServerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/grizzly2/httpserver/GrizzlyHttpServerFactory.html'>GrizzlyHttpServerFactory</link>">
 <!ENTITY jersey.grizzly.GrizzlyWebContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/grizzly2/servlet/GrizzlyWebContainerFactory.html'>GrizzlyWebContainerFactory</link>">
+<!ENTITY jersey.helidon.HelidonConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/helidon/connector/HelidonConnectorProvider.html'>HelidonConnectorProvider</link>">
+<!ENTITY jersey.helidon.HelidonClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/helidon/connector/HelidonClientProperties.html'>HelidonClientProperties</link>">
+<!ENTITY jersey.helidon.HelidonClientProperties.CONFIG "<link xlink:href='&jersey.javadoc.uri.prefix;/helidon/connector/HelidonClientProperties.html#CONFIG'>HelidonClientProperties.CONFIG</link>">
+<!ENTITY jersey.jdk.JdkConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProvider.html'>JdkConnectorProvider</link>">
+<!ENTITY jersey.jdk.JdkClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html'>JdkConnectorProperties</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.CONNECTION_IDLE_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#CONNECTION_IDLE_TIMEOUT'>JdkConnectorProperties.CONNECTION_IDLE_TIMEOUT</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.CONTAINER_IDLE_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#CONTAINER_IDLE_TIMEOUT'>JdkConnectorProperties.CONTAINER_IDLE_TIMEOUT</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.COOKIE_POLICY "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#COOKIE_POLICY'>JdkConnectorProperties.COOKIE_POLICY</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.DEFAULT_CONNECTION_CLOSE_WAIT "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#DEFAULT_CONNECTION_CLOSE_WAIT'>JdkConnectorProperties.DEFAULT_CONNECTION_CLOSE_WAIT</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.DEFAULT_CONNECTION_IDLE_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#DEFAULT_CONNECTION_IDLE_TIMEOUT'>JdkConnectorProperties.DEFAULT_CONNECTION_IDLE_TIMEOUT</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.DEFAULT_MAX_CONNECTIONS_PER_DESTINATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#DEFAULT_MAX_CONNECTIONS_PER_DESTINATION'>JdkConnectorProperties.DEFAULT_MAX_CONNECTIONS_PER_DESTINATION</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.DEFAULT_MAX_HEADER_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#DEFAULT_MAX_HEADER_SIZE'>JdkConnectorProperties.DEFAULT_MAX_HEADER_SIZE</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.DEFAULT_MAX_REDIRECTS "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#DEFAULT_MAX_REDIRECTS'>JdkConnectorProperties.DEFAULT_MAX_REDIRECTS</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.MAX_CONNECTIONS_PER_DESTINATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#MAX_CONNECTIONS_PER_DESTINATION'>JdkConnectorProperties.MAX_CONNECTIONS_PER_DESTINATION</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.MAX_HEADER_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#MAX_HEADER_SIZE'>JdkConnectorProperties.MAX_HEADER_SIZE</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.MAX_REDIRECTS "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#MAX_REDIRECTS'>JdkConnectorProperties.MAX_REDIRECTS</link>">
+<!ENTITY jersey.jdk.JdkClientProperties.WORKER_THREAD_POOL_CONFIG "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProperties.html#WORKER_THREAD_POOL_CONFIG'>JdkConnectorProperties.WORKER_THREAD_POOL_CONFIG</link>">
 <!ENTITY jersey.jdkhttp.JdkHttpHandlerContainer "<link xlink:href='&jersey.javadoc.uri.prefix;/jdkhttp/JdkHttpHandlerContainer.html'>JdkHttpHandlerContainer</link>">
 <!ENTITY jersey.jdkhttp.JdkHttpHandlerContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jdkhttp/JdkHttpHandlerContainerProvider.html'>JdkHttpHandlerContainerProvider</link>">
 <!ENTITY jersey.jdkhttp.JdkHttpServerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jdkhttp/JdkHttpServerFactory.html'>JdkHttpServerFactory</link>">
+<!ENTITY jersey.jetty.JettyClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html'>JettyClientProperties</link>" >
+<!ENTITY jersey.jetty.JettyHttpClientSupplier "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyHttpClientSupplier.html'>JettyHttpClientSupplier</link>" >
+<!ENTITY jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#ENABLE_SSL_HOSTNAME_VERIFICATION'>JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION</link>" >
+<!ENTITY jersey.jetty.JettyClientProperties.DISABLE_COOKIES "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#DISABLE_COOKIES'>JettyClientProperties.DISABLE_COOKIES</link>" >
+<!ENTITY jersey.jetty.JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#PREEMPTIVE_BASIC_AUTHENTICATION'>JettyClientProperties.PREEMPTIVE_BASIC_AUTHENTICATION</link>" >
+<!ENTITY jersey.jetty.JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyClientProperties.html#SYNC_LISTENER_RESPONSE_MAX_SIZE'>JettyClientProperties.SYNC_LISTENER_RESPONSE_MAX_SIZE</link>" >
 <!ENTITY jersey.jetty.JettyConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/connector/JettyConnectorProvider.html'>JettyConnectorProvider</link>">
 <!ENTITY jersey.jetty.JettyHttpContainer "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainer.html'>JettyHttpContainer</link>">
 <!ENTITY jersey.jetty.JettyHttpContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerFactory.html'>JettyHttpContainerFactory</link>">
 <!ENTITY jersey.jetty.JettyHttpContainerProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/JettyHttpContainerProvider.html'>JettyHttpContainerProvider</link>">
 <!ENTITY jersey.jetty.JettyWebContainerFactory "<link xlink:href='&jersey.javadoc.uri.prefix;/jetty/servlet/JettyWebContainerFactory.html'>JettyWebContainerFactory</link>">
-<!ENTITY jersey.jetty.JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION "<link xlink:href='&jersey.javadoc.uri.prefix;/client/JettyClientProperties.html#ENABLE_SSL_HOSTNAME_VERIFICATION'>JettyClientProperties.ENABLE_SSL_HOSTNAME_VERIFICATION</link>" >
 <!ENTITY jersey.linking.DeclarativeLinkingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/linking/DeclarativeLinkingFeature.html'>DeclarativeLinkingFeature</link>">
 <!ENTITY jersey.logging.LoggingFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html'>LoggingFeature</link>">
 <!ENTITY jersey.logging.LoggingFeature.DEFAULT_LOGGER_NAME "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_LOGGER_NAME'>LoggingFeature.DEFAULT_LOGGER_NAME</link>">
 <!ENTITY jersey.logging.LoggingFeature.DEFAULT_LOGGER_LEVEL "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_LOGGER_LEVEL'>LoggingFeature.DEFAULT_LOGGER_LEVEL</link>">
 <!ENTITY jersey.logging.LoggingFeature.DEFAULT_VERBOSITY "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_VERBOSITY'>LoggingFeature.DEFAULT_VERBOSITY</link>">
 <!ENTITY jersey.logging.LoggingFeature.DEFAULT_MAX_ENTITY_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_MAX_ENTITY_SIZE'>LoggingFeature.DEFAULT_MAX_ENTITY_SIZE</link>">
+<!ENTITY jersey.logging.LoggingFeature.DEFAULT_REDACT_HEADERS "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#DEFAULT_REDACT_HEADERS'>LoggingFeature.DEFAULT_REDACT_HEADERS</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_NAME'>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_LEVEL'>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_VERBOSITY'>LoggingFeature.LOGGING_FEATURE_VERBOSITY</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_MAX_ENTITY_SIZE'>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_SEPARATOR'>LoggingFeature.LOGGING_FEATURE_SEPARATOR</link>">
+<!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_REDACT_HEADERS'>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_NAME_CLIENT'>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_LEVEL_CLIENT'>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_VERBOSITY_CLIENT'>LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT'>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT'>LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT</link>">
+<!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_REDACT_HEADERS_CLIENT'>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_NAME_SERVER'>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_SERVER</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_LOGGER_LEVEL_SERVER'>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_VERBOSITY_SERVER'>LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER'>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER</link>">
 <!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER'>LoggingFeature.LOGGING_FEATURE_SEPARATOR_SERVER</link>">
+<!ENTITY jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.html#LOGGING_FEATURE_REDACT_HEADERS_SERVER'>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER</link>">
 <!ENTITY jersey.logging.LoggingFeature.Verbosity "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.Verbosity.html'>LoggingFeature.Verbosity</link>">
 <!ENTITY jersey.logging.LoggingFeature.Verbosity.HEADERS_ONLY "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.Verbosity.html#HEADERS_ONLY'>LoggingFeature.Verbosity.HEADERS_ONLY</link>">
 <!ENTITY jersey.logging.LoggingFeature.Verbosity.PAYLOAD_ANY "<link xlink:href='&jersey.javadoc.uri.prefix;/logging/LoggingFeature.Verbosity.html#PAYLOAD_ANY'>LoggingFeature.Verbosity.PAYLOAD_ANY</link>">
@@ -482,9 +537,11 @@
 <!ENTITY jersey.message.filtering.SecurityAnnotations "<link xlink:href='&jersey.javadoc.uri.prefix;/message/filtering/SecurityAnnotations.html'>SecurityAnnotations</link>">
 <!ENTITY jersey.message.filtering.SecurityEntityFilteringFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/message/filtering/SecurityEntityFilteringFeature.html'>SecurityEntityFilteringFeature</link>">
 <!ENTITY jersey.message.filtering.SelectableEntityFilteringFeature "<link xlink:href='&jersey.javadoc.uri.prefix;/message/filtering/SelectableEntityFilteringFeature.html'>SelectableEntityFilteringFeature</link>">
+<!ENTITY jersey.netty.NettyClientProperties "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html'>NettyClientProperties</link>" >
+<!ENTITY jersey.netty.NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#IDLE_CONNECTION_PRUNE_TIMEOUT'>NettyClientProperties.IDLE_CONNECTION_PRUNE_TIMEOUT</link>" >
+<!ENTITY jersey.netty.NettyClientProperties.MAX_CONNECTIONS "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#MAX_CONNECTIONS'>NettyClientProperties.MAX_CONNECTIONS</link>" >
+<!ENTITY jersey.netty.NettyClientProperties.MAX_CONNECTIONS_TOTAL "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyClientProperties.html#MAX_CONNECTIONS_TOTAL'>NettyClientProperties.MAX_CONNECTIONS_TOTAL</link>" >
 <!ENTITY jersey.netty.NettyConnectorProvider "<link xlink:href='&jersey.javadoc.uri.prefix;/netty/connector/NettyConnectorProvider.html'>NettyConnectorProvider</link>">
-<!ENTITY jersey.jdk.JdkConnectorProvider
-        "<link xlink:href='&jersey.javadoc.uri.prefix;/jdk/connector/JdkConnectorProvider.html'>JdkConnectorProvider</link>">
 <!ENTITY jersey.server.ApplicationHandler "<link xlink:href='&jersey.javadoc.uri.prefix;/server/ApplicationHandler.html'>ApplicationHandler</link>">
 <!ENTITY jersey.server.BackgroundScheduler "<link xlink:href='&jersey.javadoc.uri.prefix;/server/BackgroundScheduler.html'>@BackgroundScheduler</link>">
 <!ENTITY jersey.server.BackgroundSchedulerLiteral "<link xlink:href='&jersey.javadoc.uri.prefix;/server/BackgroundSchedulerLiteral.html'>BackgroundSchedulerLiteral</link>">
@@ -918,21 +975,25 @@
 <!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_LOGGER_LEVEL "<literal>LoggingFeature.DEFAULT_LOGGER_LEVEL</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_VERBOSITY "<literal>LoggingFeature.DEFAULT_VERBOSITY</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_MAX_ENTITY_SIZE "<literal>LoggingFeature.DEFAULT_MAX_ENTITY_SIZE</literal>">
+<!ENTITY lit.jersey.logging.LoggingFeature.DEFAULT_REDACT_HEADERS "<literal>LoggingFeature.DEFAULT_REDACT_HEADERS</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY "<literal>LoggingFeature.LOGGING_FEATURE_VERBOSITY</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE "<literal>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR "<literal>LoggingFeature.LOGGING_FEATURE_SEPARATOR</literal>">
+<!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS "<literal>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_CLIENT</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_CLIENT</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_VERBOSITY_CLIENT</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_CLIENT</literal>">
-<!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_SEPARATORE_CLIENT</literal>">
+<!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_SEPARATOR_CLIENT</literal>">
+<!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT "<literal>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_CLIENT</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_NAME_SERVER</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_LOGGER_LEVEL_SERVER</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_VERBOSITY_SERVER</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE_SERVER</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_SEPARATOR_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_SEPARATOR_SERVER</literal>">
+<!ENTITY lit.jersey.logging.LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER "<literal>LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS_SERVER</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.Verbosity "<literal>LoggingFeature.Verbosity</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.Verbosity.HEADERS_ONLY "<literal>LoggingFeature.Verbosity.HEADERS_ONLY</literal>">
 <!ENTITY lit.jersey.logging.LoggingFeature.Verbosity.PAYLOAD_ANY "<literal>LoggingFeature.Verbosity.PAYLOAD_ANY</literal>">
diff --git a/docs/src/main/docbook/logging.xml b/docs/src/main/docbook/logging.xml
index e125d3e..ce853a9 100644
--- a/docs/src/main/docbook/logging.xml
+++ b/docs/src/main/docbook/logging.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0"?>
 <!--
 
-    Copyright (c) 2016, 2021 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2016, 2022 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
@@ -154,6 +154,19 @@
                             <para>Default value &jersey.logging.LoggingFeature.DEFAULT_MAX_ENTITY_SIZE;.
                             </para>
                         </listitem>
+                        <listitem>
+                            <para>
+                                <literal>Redact HTTP headers</literal>
+                            </para>
+                            <para>
+                                HTTP headers with sensitive information can be configured to print "[redacted]" in place of their
+                                real values. This should be a string with the names of the HTTP headers to be redacted, each entry
+                                separated by a semicolon (;). Header names will be compared in a case-insensitive manner and
+                                ignoring initial or trailing whitespaces.
+                            </para>
+                            <para>Default value &jersey.logging.LoggingFeature.DEFAULT_REDACT_HEADERS;.
+                            </para>
+                        </listitem>
                     </itemizedlist>
                 </para>
             </section>
diff --git a/examples/rx-client-webapp/src/main/java/org/glassfish/jersey/examples/rx/agent/ListenableFutureAgentResource.java b/examples/rx-client-webapp/src/main/java/org/glassfish/jersey/examples/rx/agent/ListenableFutureAgentResource.java
index aebcc70..4a18b92 100644
--- a/examples/rx-client-webapp/src/main/java/org/glassfish/jersey/examples/rx/agent/ListenableFutureAgentResource.java
+++ b/examples/rx-client-webapp/src/main/java/org/glassfish/jersey/examples/rx/agent/ListenableFutureAgentResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Distribution License v. 1.0, which is available at
@@ -12,6 +12,8 @@
 
 import java.util.Arrays;
 import java.util.List;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.Path;
@@ -31,8 +33,6 @@
 import org.glassfish.jersey.server.ManagedAsync;
 import org.glassfish.jersey.server.Uri;
 
-import com.google.common.collect.Lists;
-import com.google.common.util.concurrent.AsyncFunction;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
@@ -80,7 +80,7 @@
             public void onFailure(final Throwable t) {
                 async.resume(t);
             }
-        });
+        }, Executors.newSingleThreadExecutor());
     }
 
     private ListenableFuture<AgentResponse> visited(final AgentResponse response) {
@@ -97,11 +97,11 @@
                                                                        });
 
         // ... and set them to the final response.
-        return Futures.transform(visited, (AsyncFunction<List<Destination>, AgentResponse>) destinations -> {
+        return Futures.transform(visited, destinations -> {
             response.setVisited(destinations);
 
-            return Futures.immediateFuture(response);
-        });
+            return response;
+        }, Executors.newSingleThreadExecutor());
     }
 
     private ListenableFuture<AgentResponse> recommended(final AgentResponse response) {
@@ -120,15 +120,14 @@
 
         // ... transform them to Recommendation instances ...
         final ListenableFuture<List<Recommendation>> recommendations = Futures.transform(
-                destinations,
-                (AsyncFunction<List<Destination>, List<Recommendation>>) destinationList -> {
+                destinations, destinationList -> {
                     // Create new array list to avoid multiple remote calls.
-                    final List<Recommendation> recommendationList = Lists.newArrayList(Lists.transform(
-                            destinationList,
-                            destination -> new Recommendation(destination.getDestination(), null, 0)));
+                    final List<Recommendation> recommendationList = destinationList.stream().map(
+                            destination -> new Recommendation(destination.getDestination(), null, 0))
+                            .collect(Collectors.toList());
 
-                    return Futures.immediateFuture(recommendationList);
-                });
+                    return recommendationList;
+                }, Executors.newSingleThreadExecutor());
 
         // ... add forecasts and calculations ...
         final ListenableFuture<List<List<Recommendation>>> filledRecommendations = Futures
@@ -140,47 +139,51 @@
 
         // ... and transform the list into agent response with filled recommendations.
         return Futures
-                .transform(filledRecommendations, (AsyncFunction<List<List<Recommendation>>, AgentResponse>) input -> {
+                .transform(filledRecommendations, input -> {
                     response.setRecommended(input.get(0));
 
-                    return Futures.immediateFuture(response);
-                });
+                    return response;
+                }, Executors.newSingleThreadExecutor());
     }
 
     private ListenableFuture<List<Recommendation>> forecasts(final ListenableFuture<List<Recommendation>> recommendations) {
         forecast.register(RxListenableFutureInvokerProvider.class);
 
         // Fill the list with weather forecast.
-        return Futures.transform(recommendations, (AsyncFunction<List<Recommendation>, List<Recommendation>>) list ->
+        return Futures.transform(recommendations, list ->
                 // For each recommendation ...
-                Futures.successfulAsList(Lists.transform(list, recommendation -> Futures.transform(
+                (List<Recommendation>) Futures.successfulAsList(list.stream().map(recommendation -> Futures.transform(
                         // ... get the weather forecast ...
                         forecast.resolveTemplate("destination", recommendation.getDestination()).request()
                                 .rx(RxListenableFutureInvoker.class)
                                 .get(Forecast.class),
                         // ... and set it to the recommendation.
-                        (AsyncFunction<Forecast, Recommendation>) forecast -> {
+                        forecast -> {
                             recommendation.setForecast(forecast.getForecast());
-                            return Futures.immediateFuture(recommendation);
-                        }))));
+                            return recommendation;
+                        },
+                        Executors.newSingleThreadExecutor())).collect(Collectors.toList())),
+                Executors.newSingleThreadExecutor());
     }
 
     private ListenableFuture<List<Recommendation>> calculations(final ListenableFuture<List<Recommendation>> recommendations) {
         calculation.register(RxListenableFutureInvokerProvider.class);
 
         // Fill the list with price calculations.
-        return Futures.transform(recommendations, (AsyncFunction<List<Recommendation>, List<Recommendation>>) list ->
+        return Futures.transform(recommendations, list ->
                 // For each recommendation ...
-                Futures.successfulAsList(Lists.transform(list, recommendation -> Futures.transform(
+                (List<Recommendation>) Futures.successfulAsList(list.stream().map(recommendation -> Futures.transform(
                         // ... get the price calculation ...
                         calculation.resolveTemplate("from", "Moon")
                                    .resolveTemplate("to", recommendation.getDestination())
                                    .request().rx(RxListenableFutureInvoker.class).get(Calculation.class),
                         // ... and set it to the recommendation.
-                        (AsyncFunction<Calculation, Recommendation>) calculation -> {
+                        calculation -> {
                             recommendation.setPrice(calculation.getPrice());
-                            return Futures.immediateFuture(recommendation);
-                        })))
+                            return recommendation;
+                        },
+                        Executors.newSingleThreadExecutor())).collect(Collectors.toList())),
+                Executors.newSingleThreadExecutor()
         );
     }
 }
diff --git a/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml b/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
index fffcafc..69c0f15 100644
--- a/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
+++ b/ext/cdi/jersey-cdi1x-ban-custom-hk2-binding/pom.xml
@@ -48,7 +48,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
index 63a3eac..6ee748c 100644
--- a/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
+++ b/ext/cdi/jersey-cdi1x/src/main/java/org/glassfish/jersey/ext/cdi1x/internal/CdiComponentProvider.java
@@ -41,6 +41,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
+import jakarta.enterprise.inject.Vetoed;
 import jakarta.enterprise.inject.spi.BeanManager;
 import jakarta.enterprise.inject.spi.BeforeBeanDiscovery;
 import jakarta.inject.Singleton;
@@ -292,6 +293,10 @@
             return false;
         }
 
+        if (clazz.isAnnotationPresent(Vetoed.class)) {
+            return false;
+        }
+
         if (isJerseyOrDependencyType(clazz)) {
             return false;
         }
diff --git a/ext/pom.xml b/ext/pom.xml
index 2c6e150..fa7003a 100644
--- a/ext/pom.xml
+++ b/ext/pom.xml
@@ -51,10 +51,7 @@
         <module>mvc-mustache</module>
         <module>proxy-client</module>
         <module>rx</module>
-        <!-- do not release spring 4 and spring 5 modules with Jersey 3.x
-        <module>spring4</module>
-        <module>spring5</module>
-        -->
+        <module>spring6</module>
         <module>wadl-doclet</module>
         <module>microprofile</module>
     </modules>
diff --git a/ext/rx/pom.xml b/ext/rx/pom.xml
index 3d9a2de..f20bbbd 100644
--- a/ext/rx/pom.xml
+++ b/ext/rx/pom.xml
@@ -50,7 +50,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/ext/rx/rx-client-guava/pom.xml b/ext/rx/rx-client-guava/pom.xml
index e189034..71fe9a9 100644
--- a/ext/rx/rx-client-guava/pom.xml
+++ b/ext/rx/rx-client-guava/pom.xml
@@ -41,6 +41,7 @@
         <dependency>
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
+            <version>${guava.version}</version>
         </dependency>
     </dependencies>
 </project>
diff --git a/ext/spring4/pom.xml b/ext/spring4/pom.xml
deleted file mode 100644
index e436f3d..0000000
--- a/ext/spring4/pom.xml
+++ /dev/null
@@ -1,225 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2012, 2022 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.glassfish.jersey.ext</groupId>
-        <artifactId>project</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>jersey-spring4</artifactId>
-    <name>jersey-spring4</name>
-
-    <packaging>jar</packaging>
-
-    <description>
-        Jersey extension module providing support for Spring 4 integration.
-    </description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.glassfish.jersey.core</groupId>
-            <artifactId>jersey-server</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.inject</groupId>
-            <artifactId>jersey-hk2</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-servlet-core</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>1.2</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.hk2</groupId>
-            <artifactId>hk2</artifactId>
-            <version>${hk2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.hk2</groupId>
-            <artifactId>spring-bridge</artifactId>
-            <version>${hk2.version}</version>
-            <exclusions>
-                <exclusion>  <!-- already pulled in by jersey-server -->
-                    <groupId>jakarta.inject</groupId>
-                    <artifactId>jakarta.inject-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.glassfish.hk2</groupId>
-                    <artifactId>hk2-api</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-beans</artifactId>
-            <version>${spring4.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-core</artifactId>
-            <version>${spring4.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>commons-logging</groupId>
-                    <artifactId>commons-logging</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-web</artifactId>
-            <version>${spring4.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-aop</artifactId>
-            <version>${spring4.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet4.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework</groupId>
-            <artifactId>jersey-test-framework-core</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.aspectj</groupId>
-            <artifactId>aspectjrt</artifactId>
-            <version>1.6.11</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.aspectj</groupId>
-            <artifactId>aspectjweaver</artifactId>
-            <version>1.6.11</version>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.sun.istack</groupId>
-                <artifactId>istack-commons-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>jakartification_exclude_tests</id> <!-- TODO remove after jakartification -->
-            <activation>
-                <jdk>[1.8,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>delayed-strategy-skip-test</id>
-            <activation>
-                <property>
-                    <name>org.glassfish.jersey.injection.manager.strategy</name>
-                    <value>delayed</value>
-                </property>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>ignore.on.jdk16</id>
-            <!-- Spring 4 does not support JDK 16 at the moment, and it is superseded by Spring 5.2-5.3 -->
-            <activation>
-                <jdk>[16,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java b/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
deleted file mode 100644
index 1158fc6..0000000
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring;
-
-import java.lang.reflect.AnnotatedElement;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.logging.Logger;
-
-import jakarta.inject.Singleton;
-
-import org.glassfish.jersey.internal.inject.Injectee;
-import org.glassfish.jersey.internal.inject.InjectionResolver;
-
-import org.springframework.beans.factory.NoSuchBeanDefinitionException;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.beans.factory.config.DependencyDescriptor;
-import org.springframework.context.ApplicationContext;
-import org.springframework.core.MethodParameter;
-
-/**
- * HK2 injection resolver for Spring framework {@link Autowired} annotation injection.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- * @author Vetle Leinonen-Roeim (vetle at roeim.net)
- */
-@Singleton
-public class AutowiredInjectResolver implements InjectionResolver<Autowired> {
-
-    private static final Logger LOGGER = Logger.getLogger(AutowiredInjectResolver.class.getName());
-
-    private volatile ApplicationContext ctx;
-
-    /**
-     * Create a new instance.
-     *
-     * @param ctx Spring application context.
-     */
-    public AutowiredInjectResolver(ApplicationContext ctx) {
-        this.ctx = ctx;
-    }
-
-    @Override
-    public Object resolve(Injectee injectee) {
-        AnnotatedElement parent = injectee.getParent();
-        String beanName = null;
-        if (parent != null) {
-            Qualifier an = parent.getAnnotation(Qualifier.class);
-            if (an != null) {
-                beanName = an.value();
-            }
-        }
-        boolean required = parent != null ? parent.getAnnotation(Autowired.class).required() : false;
-        return getBeanFromSpringContext(beanName, injectee, required);
-    }
-
-    private Object getBeanFromSpringContext(String beanName, Injectee injectee, final boolean required) {
-        try {
-            DependencyDescriptor dependencyDescriptor = createSpringDependencyDescriptor(injectee);
-            Set<String> autowiredBeanNames = new HashSet<>(1);
-            autowiredBeanNames.add(beanName);
-            return ctx.getAutowireCapableBeanFactory().resolveDependency(dependencyDescriptor, null,
-                    autowiredBeanNames, null);
-        } catch (NoSuchBeanDefinitionException e) {
-            if (required) {
-                LOGGER.warning(e.getMessage());
-                throw e;
-            }
-            return null;
-        }
-    }
-
-    private DependencyDescriptor createSpringDependencyDescriptor(final Injectee injectee) {
-        AnnotatedElement annotatedElement = injectee.getParent();
-
-        if (annotatedElement.getClass().isAssignableFrom(Field.class)) {
-            return new DependencyDescriptor((Field) annotatedElement, !injectee.isOptional());
-        } else if (annotatedElement.getClass().isAssignableFrom(Method.class)) {
-            return new DependencyDescriptor(
-                    new MethodParameter((Method) annotatedElement, injectee.getPosition()), !injectee.isOptional());
-        } else {
-            return new DependencyDescriptor(
-                    new MethodParameter((Constructor) annotatedElement, injectee.getPosition()), !injectee.isOptional());
-        }
-    }
-
-    @Override
-    public boolean isConstructorParameterIndicator() {
-        return false;
-    }
-
-    @Override
-    public boolean isMethodParameterIndicator() {
-        return false;
-    }
-
-    @Override
-    public Class<Autowired> getAnnotation() {
-        return Autowired.class;
-    }
-}
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java b/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
deleted file mode 100644
index b33a69d..0000000
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.glassfish.jersey.server.spring;
-
-import java.util.logging.Logger;
-
-import jakarta.servlet.ServletContext;
-import jakarta.servlet.ServletException;
-
-import org.springframework.web.WebApplicationInitializer;
-
-/**
- * Spring WebApplicationInitializer implementation initializes Spring context by
- * adding a Spring ContextLoaderListener to the ServletContext.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class SpringWebApplicationInitializer implements WebApplicationInitializer {
-
-    private static final Logger LOGGER = Logger.getLogger(SpringWebApplicationInitializer.class.getName());
-
-    private static final String PAR_NAME_CTX_CONFIG_LOCATION = "contextConfigLocation";
-
-    @Override
-    public void onStartup(ServletContext sc) throws ServletException {
-        if (sc.getInitParameter(PAR_NAME_CTX_CONFIG_LOCATION) == null) {
-            LOGGER.config(LocalizationMessages.REGISTERING_CTX_LOADER_LISTENER());
-            sc.setInitParameter(PAR_NAME_CTX_CONFIG_LOCATION, "classpath:applicationContext.xml");
-            sc.addListener("org.springframework.web.context.ContextLoaderListener");
-            sc.addListener("org.springframework.web.context.request.RequestContextListener");
-        } else {
-            LOGGER.config(LocalizationMessages.SKIPPING_CTX_LODAER_LISTENER_REGISTRATION());
-        }
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
deleted file mode 100644
index 111361c..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring;
-
-public class NoComponent {
-
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
deleted file mode 100644
index 792d9b8..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring;
-
-public interface TestComponent2 {
-    String result();
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
deleted file mode 100644
index c8c61d0..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class TestComponent2Impl1 implements TestComponent2 {
-    @Override
-    public String result() {
-        return "test ok";
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
deleted file mode 100644
index 4506c7e..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.aspect4j;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-
-public class Aspect4jJerseyConfig extends ResourceConfig {
-
-    public Aspect4jJerseyConfig() {
-        register(RequestContextFilter.class);
-        register(NoComponentResource.class);
-        register(ComponentResource.class);
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
deleted file mode 100644
index df30805..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.fieldinjection;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-
-public class SpringFieldInjectionJerseyTestConfig extends ResourceConfig {
-    public SpringFieldInjectionJerseyTestConfig() {
-        register(RequestContextFilter.class);
-        register(SpringFieldInjectionTestResource.class);
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
deleted file mode 100644
index 28de237..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.glassfish.jersey.server.spring.filter;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class Counter {
-
-    private int count = 0;
-
-    public void inc() {
-        count++;
-    }
-
-    public int getCount() {
-        return count;
-    }
-
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
deleted file mode 100644
index 5a9d3b7..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.methodinjection;
-
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-import org.glassfish.jersey.server.ResourceConfig;
-
-public class SpringMethodInjectionJerseyTestConfig extends ResourceConfig {
-    public SpringMethodInjectionJerseyTestConfig() {
-        register(RequestContextFilter.class);
-        register(SpringMethodInjectionTestResource.class);
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
deleted file mode 100644
index dc3c995..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-import org.springframework.context.annotation.Primary;
-import org.springframework.context.annotation.Profile;
-import org.springframework.stereotype.Component;
-
-@Component
-@Primary
-@Profile("dev")
-public class DevTestService implements TestService {
-
-    @Override
-    public String test() {
-        return "dev";
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
deleted file mode 100644
index 8bccbe3..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import static org.junit.Assert.assertEquals;
-
-public class SpringProfilesTest {
-
-    @Test
-    public void shouldGetDefaultBean() {
-        System.setProperty("spring.profiles.active", "");
-        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
-                "org.glassfish.jersey.server.spring.profiles");
-        assertEquals("default", context.getBean(TestService.class).test());
-    }
-
-    @Test
-    public void shouldGetDevProfileBean() {
-        System.setProperty("spring.profiles.active", "dev");
-        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
-                "org.glassfish.jersey.server.spring.profiles");
-        assertEquals("dev", context.getBean(TestService.class).test());
-    }
-}
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java b/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
deleted file mode 100644
index 045d3e2..0000000
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-public interface TestService {
-
-    String test();
-}
diff --git a/ext/spring5/pom.xml b/ext/spring5/pom.xml
deleted file mode 100644
index 4647434..0000000
--- a/ext/spring5/pom.xml
+++ /dev/null
@@ -1,206 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2012, 2022 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.glassfish.jersey.ext</groupId>
-        <artifactId>project</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>jersey-spring5</artifactId>
-    <name>jersey-spring5</name>
-
-    <packaging>jar</packaging>
-
-    <description>
-        Jersey extension module providing support for Spring 5 integration.
-    </description>
-
-    <dependencies>
-        <dependency>
-            <groupId>org.glassfish.jersey.core</groupId>
-            <artifactId>jersey-server</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.inject</groupId>
-            <artifactId>jersey-hk2</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-servlet-core</artifactId>
-            <version>${project.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <version>1.2</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.hk2</groupId>
-            <artifactId>hk2</artifactId>
-            <version>${hk2.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.hk2</groupId>
-            <artifactId>spring-bridge</artifactId>
-            <version>${hk2.version}</version>
-            <exclusions>
-                <exclusion>  <!-- already pulled in by jersey-server -->
-                    <groupId>jakarta.inject</groupId>
-                    <artifactId>jakarta.inject</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.glassfish.hk2</groupId>
-                    <artifactId>hk2-api</artifactId>
-                </exclusion>
-                <exclusion>
-                    <groupId>org.springframework</groupId>
-                    <artifactId>spring-context</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-beans</artifactId>
-            <version>${spring5.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-core</artifactId>
-            <version>${spring5.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>commons-logging</groupId>
-                    <artifactId>commons-logging</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-context</artifactId>
-            <version>${spring5.version}</version>
-            <exclusions>
-                <exclusion>
-                    <groupId>commons-logging</groupId>
-                    <artifactId>commons-logging</artifactId>
-                </exclusion>
-            </exclusions>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-web</artifactId>
-            <version>${spring5.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.springframework</groupId>
-            <artifactId>spring-aop</artifactId>
-            <version>${spring5.version}</version>
-        </dependency>
-
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet4.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework</groupId>
-            <artifactId>jersey-test-framework-core</artifactId>
-            <version>${project.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.aspectj</groupId>
-            <artifactId>aspectjrt</artifactId>
-            <version>1.6.11</version>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
-            <groupId>org.aspectj</groupId>
-            <artifactId>aspectjweaver</artifactId>
-            <version>1.6.11</version>
-            <scope>test</scope>
-        </dependency>
-
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>com.sun.istack</groupId>
-                <artifactId>istack-commons-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <inherited>true</inherited>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>delayed-strategy-skip-test</id>
-            <activation>
-                <property>
-                    <name>org.glassfish.jersey.injection.manager.strategy</name>
-                    <value>delayed</value>
-                </property>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-surefire-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java
deleted file mode 100644
index e8df940..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java
+++ /dev/null
@@ -1,177 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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 org.glassfish.jersey.server.spring;
-
-import java.util.Set;
-import java.util.function.Supplier;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import jakarta.servlet.ServletContext;
-
-import org.glassfish.jersey.inject.hk2.ImmediateHk2InjectionManager;
-import org.glassfish.jersey.internal.inject.Binding;
-import org.glassfish.jersey.internal.inject.Bindings;
-import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.server.ApplicationHandler;
-import org.glassfish.jersey.server.spi.ComponentProvider;
-
-import org.jvnet.hk2.spring.bridge.api.SpringBridge;
-import org.jvnet.hk2.spring.bridge.api.SpringIntoHK2Bridge;
-
-import org.springframework.aop.framework.Advised;
-import org.springframework.beans.factory.BeanFactoryUtils;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-import org.springframework.core.annotation.AnnotationUtils;
-import org.springframework.stereotype.Component;
-import org.springframework.web.context.support.WebApplicationContextUtils;
-
-/**
- * Custom ComponentProvider class.
- * Responsible for 1) bootstrapping Jersey 2 Spring integration and
- * 2) making Jersey skip JAX-RS Spring component life-cycle management and leave it to us.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class SpringComponentProvider implements ComponentProvider {
-
-    private static final Logger LOGGER = Logger.getLogger(SpringComponentProvider.class.getName());
-    private static final String DEFAULT_CONTEXT_CONFIG_LOCATION = "applicationContext.xml";
-    private static final String PARAM_CONTEXT_CONFIG_LOCATION = "contextConfigLocation";
-    private static final String PARAM_SPRING_CONTEXT = "contextConfig";
-
-    private volatile InjectionManager injectionManager;
-    private volatile ApplicationContext ctx;
-
-    @Override
-    public void initialize(InjectionManager injectionManager) {
-        this.injectionManager = injectionManager;
-
-        if (LOGGER.isLoggable(Level.FINE)) {
-            LOGGER.fine(LocalizationMessages.CTX_LOOKUP_STARTED());
-        }
-
-        ServletContext sc = injectionManager.getInstance(ServletContext.class);
-
-        if (sc != null) {
-            // servlet container
-            ctx = WebApplicationContextUtils.getWebApplicationContext(sc);
-        } else {
-            // non-servlet container
-            ctx = createSpringContext();
-        }
-        if (ctx == null) {
-            LOGGER.severe(LocalizationMessages.CTX_LOOKUP_FAILED());
-            return;
-        }
-        LOGGER.config(LocalizationMessages.CTX_LOOKUP_SUCESSFUL());
-
-        // initialize HK2 spring-bridge
-
-        ImmediateHk2InjectionManager hk2InjectionManager = (ImmediateHk2InjectionManager) injectionManager;
-        SpringBridge.getSpringBridge().initializeSpringBridge(hk2InjectionManager.getServiceLocator());
-        SpringIntoHK2Bridge springBridge = injectionManager.getInstance(SpringIntoHK2Bridge.class);
-        springBridge.bridgeSpringBeanFactory(ctx);
-
-        injectionManager.register(Bindings.injectionResolver(new AutowiredInjectResolver(ctx)));
-        injectionManager.register(Bindings.service(ctx).to(ApplicationContext.class).named("SpringContext"));
-        LOGGER.config(LocalizationMessages.SPRING_COMPONENT_PROVIDER_INITIALIZED());
-    }
-
-    // detect JAX-RS classes that are also Spring @Components.
-    // register these with HK2 ServiceLocator to manage their lifecycle using Spring.
-    @Override
-    public boolean bind(Class<?> component, Set<Class<?>> providerContracts) {
-
-        if (ctx == null) {
-            return false;
-        }
-
-        if (AnnotationUtils.findAnnotation(component, Component.class) != null) {
-            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(ctx, component);
-            if (beanNames == null || beanNames.length != 1) {
-                LOGGER.severe(LocalizationMessages.NONE_OR_MULTIPLE_BEANS_AVAILABLE(component));
-                return false;
-            }
-            String beanName = beanNames[0];
-
-            Binding binding = Bindings.supplier(new SpringManagedBeanFactory(ctx, injectionManager, beanName))
-                    .to(component)
-                    .to(providerContracts);
-            injectionManager.register(binding);
-
-            LOGGER.config(LocalizationMessages.BEAN_REGISTERED(beanNames[0]));
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public void done() {
-    }
-
-    private ApplicationContext createSpringContext() {
-        ApplicationHandler applicationHandler = injectionManager.getInstance(ApplicationHandler.class);
-        ApplicationContext springContext = (ApplicationContext) applicationHandler.getConfiguration()
-                .getProperty(PARAM_SPRING_CONTEXT);
-        if (springContext == null) {
-            String contextConfigLocation = (String) applicationHandler.getConfiguration()
-                    .getProperty(PARAM_CONTEXT_CONFIG_LOCATION);
-            springContext = createXmlSpringConfiguration(contextConfigLocation);
-        }
-        return springContext;
-    }
-
-    private ApplicationContext createXmlSpringConfiguration(String contextConfigLocation) {
-        if (contextConfigLocation == null) {
-            contextConfigLocation = DEFAULT_CONTEXT_CONFIG_LOCATION;
-        }
-        return ctx = new ClassPathXmlApplicationContext(contextConfigLocation, "jersey-spring-applicationContext.xml");
-    }
-
-    private static class SpringManagedBeanFactory implements Supplier {
-
-        private final ApplicationContext ctx;
-        private final InjectionManager injectionManager;
-        private final String beanName;
-
-        private SpringManagedBeanFactory(ApplicationContext ctx, InjectionManager injectionManager, String beanName) {
-            this.ctx = ctx;
-            this.injectionManager = injectionManager;
-            this.beanName = beanName;
-        }
-
-        @Override
-        public Object get() {
-            Object bean = ctx.getBean(beanName);
-            if (bean instanceof Advised) {
-                try {
-                    // Unwrap the bean and inject the values inside of it
-                    Object localBean = ((Advised) bean).getTargetSource().getTarget();
-                    injectionManager.inject(localBean);
-                } catch (Exception e) {
-                    // Ignore and let the injection happen as it normally would.
-                    injectionManager.inject(bean);
-                }
-            } else {
-                injectionManager.inject(bean);
-            }
-            return bean;
-        }
-    }
-}
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
deleted file mode 100644
index 5a06926..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring;
-
-import jakarta.ws.rs.ext.Provider;
-
-import jakarta.inject.Inject;
-
-import org.glassfish.jersey.server.spi.Container;
-import org.glassfish.jersey.server.spi.ContainerLifecycleListener;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ConfigurableApplicationContext;
-
-/**
- * JAX-RS Provider class for processing Jersey 2 Spring integration container life-cycle events.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-@Provider
-public class SpringLifecycleListener implements ContainerLifecycleListener {
-
-    @Inject
-    private ApplicationContext ctx;
-
-    @Override
-    public void onStartup(Container container) {
-    }
-
-    @Override
-    public void onReload(Container container) {
-        if (ctx instanceof ConfigurableApplicationContext) {
-            ((ConfigurableApplicationContext) ctx).refresh();
-        }
-    }
-
-    @Override
-    public void onShutdown(Container container) {
-        if (ctx instanceof ConfigurableApplicationContext) {
-            ((ConfigurableApplicationContext) ctx).close();
-        }
-    }
-}
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/package-info.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/package-info.java
deleted file mode 100644
index 6e7b71a..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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
- */
-
-/**
- * Jersey server-side Spring 5 integration classes.
- * @since 2.29
- */
-package org.glassfish.jersey.server.spring;
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
deleted file mode 100644
index ec22efa..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.scope;
-
-import jakarta.ws.rs.container.ContainerRequestContext;
-
-import org.glassfish.jersey.server.spring.LocalizationMessages;
-import org.springframework.util.StringUtils;
-import org.springframework.web.context.request.AbstractRequestAttributes;
-
-/**
- * JAX-RS based Spring RequestAttributes implementation.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- * @author Marek Potociar
- */
-class JaxrsRequestAttributes extends AbstractRequestAttributes {
-
-    private final ContainerRequestContext requestContext;
-
-    /**
-     * Create a new instance.
-     *
-     * @param requestContext JAX-RS container request context
-     */
-    public JaxrsRequestAttributes(ContainerRequestContext requestContext) {
-        this.requestContext = requestContext;
-    }
-
-    @Override
-    protected void updateAccessedSessionAttributes() {
-        // sessions not supported
-    }
-
-    @Override
-    public Object getAttribute(String name, int scope) {
-        return requestContext.getProperty(name);
-    }
-
-    @Override
-    public void setAttribute(String name, Object value, int scope) {
-        requestContext.setProperty(name, value);
-    }
-
-    @Override
-    public void removeAttribute(String name, int scope) {
-        requestContext.removeProperty(name);
-    }
-
-    @Override
-    public String[] getAttributeNames(int scope) {
-        if (!isRequestActive()) {
-            throw new IllegalStateException(LocalizationMessages.NOT_IN_REQUEST_SCOPE());
-        }
-        return StringUtils.toStringArray(requestContext.getPropertyNames());
-    }
-
-    @Override
-    public void registerDestructionCallback(String name, Runnable callback, int scope) {
-        registerRequestDestructionCallback(name, callback);
-    }
-
-    @Override
-    public Object resolveReference(String key) {
-        if (REFERENCE_REQUEST.equals(key)) {
-            return requestContext;
-        }
-        return null;
-    }
-
-    @Override
-    public String getSessionId() {
-        return null;
-    }
-
-    @Override
-    public Object getSessionMutex() {
-        return null;
-    }
-}
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
deleted file mode 100644
index c32ddbc..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2016, 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 org.glassfish.jersey.server.spring.scope;
-
-import jakarta.ws.rs.container.ContainerRequestContext;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.springframework.web.context.request.ServletRequestAttributes;
-
-/**
- * JAX-RS based Spring RequestAttributes implementation for Servlet-based applications.
- *
- * @author Marek Potociar
- */
-class JaxrsServletRequestAttributes extends ServletRequestAttributes {
-
-    private final ContainerRequestContext requestContext;
-
-    /**
-     * Create a new JAX-RS ServletRequestAttributes instance for the given request.
-     *
-     * @param request        current HTTP request
-     * @param requestContext JAX-RS request context
-     */
-    public JaxrsServletRequestAttributes(final HttpServletRequest request, final ContainerRequestContext requestContext) {
-        super(request);
-        this.requestContext = requestContext;
-    }
-
-    @Override
-    public Object resolveReference(String key) {
-        if (REFERENCE_REQUEST.equals(key)) {
-            return this.requestContext;
-        } else if (REFERENCE_SESSION.equals(key)) {
-            return super.getSession(true);
-        } else {
-            return null;
-        }
-    }
-}
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
deleted file mode 100644
index de87d7e..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.scope;
-
-import java.io.IOException;
-
-import jakarta.ws.rs.container.ContainerRequestContext;
-import jakarta.ws.rs.container.ContainerRequestFilter;
-import jakarta.ws.rs.container.ContainerResponseContext;
-import jakarta.ws.rs.container.ContainerResponseFilter;
-import jakarta.ws.rs.container.PreMatching;
-import jakarta.ws.rs.ext.Provider;
-
-import jakarta.inject.Inject;
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.glassfish.jersey.internal.inject.InjectionManager;
-
-import org.springframework.context.ApplicationContext;
-import org.springframework.web.context.WebApplicationContext;
-import org.springframework.web.context.request.AbstractRequestAttributes;
-import org.springframework.web.context.request.RequestAttributes;
-import org.springframework.web.context.request.RequestContextHolder;
-
-/**
- * Spring filter to provide a bridge between JAX-RS and Spring request attributes.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- * @author Jakub Podlesak
- * @author Marek Potociar
- */
-@Provider
-@PreMatching
-public final class RequestContextFilter implements ContainerRequestFilter, ContainerResponseFilter {
-
-    private static final String REQUEST_ATTRIBUTES_PROPERTY = RequestContextFilter.class.getName() + ".REQUEST_ATTRIBUTES";
-
-    private final SpringAttributeController attributeController;
-
-    private static final SpringAttributeController EMPTY_ATTRIBUTE_CONTROLLER = new SpringAttributeController() {
-        @Override
-        public void setAttributes(final ContainerRequestContext requestContext) {
-        }
-
-        @Override
-        public void resetAttributes(final ContainerRequestContext requestContext) {
-        }
-    };
-
-    private interface SpringAttributeController {
-
-        void setAttributes(final ContainerRequestContext requestContext);
-
-        void resetAttributes(final ContainerRequestContext requestContext);
-    }
-
-    /**
-     * Create a new request context filter instance.
-     *
-     * @param injectionManager injection manager.
-     */
-    @Inject
-    public RequestContextFilter(final InjectionManager injectionManager) {
-        final ApplicationContext appCtx = injectionManager.getInstance(ApplicationContext.class);
-        final boolean isWebApp = appCtx instanceof WebApplicationContext;
-
-        attributeController = appCtx != null ? new SpringAttributeController() {
-
-            @Override
-            public void setAttributes(final ContainerRequestContext requestContext) {
-                final RequestAttributes attributes;
-                if (isWebApp) {
-                    final HttpServletRequest httpRequest = injectionManager.getInstance(HttpServletRequest.class);
-                    attributes = new JaxrsServletRequestAttributes(httpRequest, requestContext);
-                } else {
-                    attributes = new JaxrsRequestAttributes(requestContext);
-                }
-                requestContext.setProperty(REQUEST_ATTRIBUTES_PROPERTY, attributes);
-                RequestContextHolder.setRequestAttributes(attributes);
-            }
-
-            @Override
-            public void resetAttributes(final ContainerRequestContext requestContext) {
-                final AbstractRequestAttributes attributes =
-                        (AbstractRequestAttributes) requestContext.getProperty(REQUEST_ATTRIBUTES_PROPERTY);
-                RequestContextHolder.resetRequestAttributes();
-                attributes.requestCompleted();
-            }
-        } : EMPTY_ATTRIBUTE_CONTROLLER;
-    }
-
-    @Override
-    public void filter(final ContainerRequestContext requestContext) throws IOException {
-        attributeController.setAttributes(requestContext);
-    }
-
-    @Override
-    public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext)
-            throws IOException {
-        attributeController.resetAttributes(requestContext);
-    }
-}
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java b/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
deleted file mode 100644
index 49985aa..0000000
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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
- */
-
-/**
- * Jersey server-side Spring 5 integration injection scopes related classes.
- * @since 2.29
- */
-package org.glassfish.jersey.server.spring.scope;
diff --git a/ext/spring5/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider b/ext/spring5/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider
deleted file mode 100644
index 5aec207..0000000
--- a/ext/spring5/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider
+++ /dev/null
@@ -1 +0,0 @@
-org.glassfish.jersey.server.spring.SpringComponentProvider
diff --git a/ext/spring5/src/main/resources/jersey-spring-applicationContext.xml b/ext/spring5/src/main/resources/jersey-spring-applicationContext.xml
deleted file mode 100644
index fd6f528..0000000
--- a/ext/spring5/src/main/resources/jersey-spring-applicationContext.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2013, 2019 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
-
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-	http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
-
-    <bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
-        <property name="scopes">
-            <map>
-                <entry key="request">
-                    <bean class="org.springframework.web.context.request.RequestScope"/>
-                </entry>
-            </map>
-        </property>
-    </bean>
-</beans>
diff --git a/ext/spring5/src/main/resources/org/glassfish/jersey/server/spring/localization.properties b/ext/spring5/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
deleted file mode 100644
index 83f9220..0000000
--- a/ext/spring5/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
+++ /dev/null
@@ -1,26 +0,0 @@
-#
-# Copyright (c) 2013, 2019 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
-#
-
-no.beans.found.for.type=No beans found. Resolution failed for type {0}.
-ctx.lookup.started=Spring context lookup started.
-ctx.lookup.failed=Spring context lookup failed, skipping spring component provider initialization.
-ctx.lookup.sucessful=Spring context lookup done.
-spring.component.provider.initialized=Spring component provider initialized.
-none.or.multiple.beans.available=None or multiple beans found in Spring context for type {0}, skipping the type.
-bean.registered=Spring managed bean, {0}, registered with HK2.
-registering.ctx.loader.listener=Registering Spring ContextLoaderListener
-skipping.ctx.lodaer.listener.registration=Presuming Spring ContextLoaderListener was manually registered. Skipping context loader registration.
-not.in.request.scope=Cannot ask for request attributes - request is not active anymore!
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
deleted file mode 100644
index ec32676..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2014, 2019 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 org.glassfish.jersey.server.spring;
-
-import org.springframework.context.annotation.ComponentScan;
-import org.springframework.context.annotation.Configuration;
-
-@Configuration
-@ComponentScan(basePackages = "org.glassfish.jersey.server.spring")
-public class SpringTestConfiguration {
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
deleted file mode 100644
index d8d29a3..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 2019 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 org.glassfish.jersey.server.spring;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class TestComponent1 {
-
-    public String result() {
-        return "test ok";
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
deleted file mode 100644
index a4f33f6..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 2019 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 org.glassfish.jersey.server.spring;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class TestComponent2Impl2 implements TestComponent2 {
-    @Override
-    public String result() {
-        return "test ok";
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
deleted file mode 100644
index 52fd0e3..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.aspect4j;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Before;
-import org.junit.Test;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
-
-import static org.junit.Assert.assertEquals;
-
-public class Aspect4JTest extends JerseyTest {
-
-    private ClassPathXmlApplicationContext applicationContext;
-
-    private TestAspect testAspect;
-
-    @Before
-    public void before() {
-        testAspect.reset();
-    }
-
-    @Override
-    protected Application configure() {
-        applicationContext = new ClassPathXmlApplicationContext("jersey-spring-aspect4j-applicationContext.xml");
-        testAspect = applicationContext.getBean(TestAspect.class);
-        return new Aspect4jJerseyConfig()
-                .property("contextConfig", applicationContext);
-    }
-
-    @Test
-    public void methodCallShouldNotBeIntercepted() {
-        target("test1").request().get(String.class);
-        assertEquals(0, testAspect.getInterceptions());
-    }
-
-    @Test
-    public void methodCallShouldBeIntercepted() {
-        target("test2").request().get(String.class);
-        assertEquals(1, applicationContext.getBean(TestAspect.class).getInterceptions());
-    }
-
-    @Test
-    public void JERSEY_3126() {
-        final String result = target("JERSEY-3126").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
deleted file mode 100644
index 9b96e32..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.aspect4j;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.Context;
-import jakarta.ws.rs.core.UriInfo;
-
-import org.glassfish.jersey.server.spring.TestComponent1;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Path("/")
-@Component
-public class ComponentResource {
-
-    @Autowired
-    private TestComponent1 testComponent1;
-    @Context
-    private UriInfo uriInfo;
-
-    @Path("test2")
-    @GET
-    public String test2() {
-        return testComponent1.result();
-    }
-
-    @Path("JERSEY-3126")
-    @GET
-    public String JERSEY_3126() {
-        return uriInfo == null ? "test failed" : "test ok";
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
deleted file mode 100644
index bb5bf8a..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.aspect4j;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-
-import org.glassfish.jersey.server.spring.TestComponent1;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Path("/")
-public class NoComponentResource {
-
-    @Autowired
-    private TestComponent1 testComponent1;
-
-    @Path("test1")
-    @GET
-    public String test1() {
-        return testComponent1.result();
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
deleted file mode 100644
index 4580199..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.aspect4j;
-
-import jakarta.inject.Singleton;
-
-import org.aspectj.lang.JoinPoint;
-import org.aspectj.lang.annotation.Aspect;
-import org.aspectj.lang.annotation.Before;
-
-@Aspect
-@Singleton
-public class TestAspect {
-
-    private int interceptions = 0;
-
-    @Before("execution(* org.glassfish.jersey.server.spring.aspect4j.*.*())")
-    public void intercept(JoinPoint joinPoint) {
-        interceptions++;
-    }
-
-    public int getInterceptions() {
-        return interceptions;
-    }
-
-    public void reset() {
-        interceptions = 0;
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
deleted file mode 100644
index 141d16e..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.fieldinjection;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.server.spring.SpringTestConfiguration;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.junit.Assert.assertEquals;
-
-public class SpringFieldInjectionTest extends JerseyTest {
-
-    @Override
-    protected Application configure() {
-        ApplicationContext context = new AnnotationConfigApplicationContext(SpringTestConfiguration.class);
-        return new SpringFieldInjectionJerseyTestConfig()
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void testInjectionOfSingleBean() {
-        String result = target("test1").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfListOfBeans() {
-        String result = target("test2").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfSetOfBeans() {
-        String result = target("test3").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void JERSEY_2643() {
-        String result = target("JERSEY-2643").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
deleted file mode 100644
index 941e311..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.fieldinjection;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-
-import org.glassfish.jersey.server.spring.NoComponent;
-import org.glassfish.jersey.server.spring.TestComponent1;
-import org.glassfish.jersey.server.spring.TestComponent2;
-import org.springframework.beans.factory.annotation.Autowired;
-
-@Path("/")
-public class SpringFieldInjectionTestResource {
-
-    @Autowired
-    private TestComponent1 testComponent1;
-
-    @Autowired
-    private List<TestComponent2> testComponent2List;
-
-    @Autowired
-    Set<TestComponent2> testComponent2Set;
-
-    @Autowired(required = false)
-    private NoComponent noComponent;
-
-    @Path("test1")
-    @GET
-    public String test1() {
-        return testComponent1.result();
-    }
-
-    @Path("test2")
-    @GET
-    public String test2() {
-        return (testComponent2List.size() == 2 && "test ok".equals(testComponent2List.get(0).result())
-                && "test ok".equals(testComponent2List.get(1).result())) ? "test ok" : "test failed";
-    }
-
-    @Path("test3")
-    @GET
-    public String test3() {
-        Iterator<TestComponent2> iterator = testComponent2Set.iterator();
-        return (testComponent2Set.size() == 2 && "test ok".equals(iterator.next().result())
-                && "test ok".equals(iterator.next().result())) ? "test ok" : "test failed";
-    }
-
-    @Path("JERSEY-2643")
-    @GET
-    public String JERSEY_2643() {
-        return noComponent == null ? "test ok" : "test failed";
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
deleted file mode 100644
index 3c33392..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.filter;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.server.spring.SpringTestConfiguration;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import static org.junit.Assert.assertEquals;
-
-public class FilterTest extends JerseyTest {
-
-    private ApplicationContext context;
-
-    @Override
-    protected Application configure() {
-        context = new AnnotationConfigApplicationContext(SpringTestConfiguration.class);
-        return new JerseyTestConfig()
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void testInjectionOfSingleBean() {
-        target("test1").request().get(String.class);
-        assertEquals(1, context.getBean(Counter.class).getCount());
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
deleted file mode 100644
index c8df018..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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 org.glassfish.jersey.server.spring.filter;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-
-public class JerseyTestConfig extends ResourceConfig {
-
-    public JerseyTestConfig() {
-        register(RequestContextFilter.class);
-        register(TestResource.class);
-        register(TestFilter.class);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
deleted file mode 100644
index 16cfd51..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.filter;
-
-import java.io.IOException;
-import jakarta.inject.Inject;
-import jakarta.inject.Singleton;
-import jakarta.ws.rs.container.ContainerRequestContext;
-import jakarta.ws.rs.container.ContainerRequestFilter;
-
-import org.springframework.stereotype.Component;
-
-@Component
-@Singleton
-public class TestFilter implements ContainerRequestFilter {
-
-    @Inject
-    private Counter counter;
-
-    @Override
-    public void filter(final ContainerRequestContext requestContext) throws IOException {
-        counter.inc();
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
deleted file mode 100644
index 7e624ef..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.filter;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-
-@Path("/")
-public class TestResource {
-
-    @Path("test1")
-    @GET
-    public String test1() {
-        return "Hello, Test!";
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
deleted file mode 100644
index 3f66478..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.methodinjection;
-
-import static org.junit.Assert.assertEquals;
-
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-import org.glassfish.jersey.server.spring.SpringTestConfiguration;
-
-import jakarta.ws.rs.core.Application;
-
-public class SpringMethodInjectionTest extends JerseyTest {
-
-    @Override
-    protected Application configure() {
-        ApplicationContext context = new AnnotationConfigApplicationContext(SpringTestConfiguration.class);
-        return new SpringMethodInjectionJerseyTestConfig()
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void testInjectionOfSingleBean() {
-        String result = target("test1").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfListOfBeans() {
-        String result = target("test2").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfSetOfBeans() {
-        String result = target("test3").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
deleted file mode 100644
index 8a16bbe..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.methodinjection;
-
-import org.glassfish.jersey.server.spring.NoComponent;
-import org.glassfish.jersey.server.spring.TestComponent1;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import java.util.List;
-import java.util.Set;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-
-@Path("/")
-public class SpringMethodInjectionTestResource {
-
-    private TestComponent1 testComponent1;
-    private List<org.glassfish.jersey.server.spring.TestComponent2> testComponent2List;
-    private Set<org.glassfish.jersey.server.spring.TestComponent2> testComponent2Set;
-    private NoComponent noComponent;
-
-    @Autowired
-    public void setTestComponent1(TestComponent1 testComponent1) {
-        this.testComponent1 = testComponent1;
-    }
-
-    @Autowired
-    public void setTestComponent2List(List<org.glassfish.jersey.server.spring.TestComponent2> testComponent2List) {
-        this.testComponent2List = testComponent2List;
-    }
-
-    @Autowired
-    public void setTestComponent2Set(Set<org.glassfish.jersey.server.spring.TestComponent2> testComponent2Set) {
-        this.testComponent2Set = testComponent2Set;
-    }
-
-    @Autowired(required = false)
-    public void setNoComponent(NoComponent noComponent) {
-        this.noComponent = noComponent;
-    }
-
-    @Path("test1")
-    @GET
-    public String test1() {
-        return testComponent1.result();
-    }
-
-    @Path("test2")
-    @GET
-    public String test2() {
-        return (testComponent2List.size() == 2 && "test ok".equals(testComponent2List.get(0).result())
-                && "test ok".equals(testComponent2List.get(1).result())) ? "test ok" : "test failed";
-    }
-
-    @Path("test3")
-    @GET
-    public String test3() {
-        java.util.Iterator<org.glassfish.jersey.server.spring.TestComponent2> iterator = testComponent2Set.iterator();
-        return (testComponent2Set.size() == 2 && "test ok".equals(iterator.next().result())
-                && "test ok".equals(iterator.next().result())) ? "test ok" : "test failed";
-    }
-
-    @Path("JERSEY-2643")
-    @GET
-    public String JERSEY_2643() {
-        return noComponent == null ? "test ok" : "test failed";
-    }
-
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
deleted file mode 100644
index 598618f..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (c) 2014, 2019 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 org.glassfish.jersey.server.spring.parameterinjection;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-
-public class SpringParameterInjectionJerseyTestConfig extends ResourceConfig {
-    public SpringParameterInjectionJerseyTestConfig() {
-        register(RequestContextFilter.class);
-        register(SpringParameterInjectionTestResource.class);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
deleted file mode 100644
index e6b720e..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.parameterinjection;
-
-import org.glassfish.jersey.server.spring.SpringTestConfiguration;
-import org.glassfish.jersey.server.spring.fieldinjection.SpringFieldInjectionJerseyTestConfig;
-import org.glassfish.jersey.test.JerseyTest;
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-import jakarta.ws.rs.core.Application;
-
-import static org.junit.Assert.assertEquals;
-
-public class SpringParameterInjectionTest extends JerseyTest {
-    @Override
-    protected Application configure() {
-        ApplicationContext context = new AnnotationConfigApplicationContext(SpringTestConfiguration.class);
-        return new SpringParameterInjectionJerseyTestConfig()
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void testInjectionOfSingleBean() {
-        String result = target("test1").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfListOfBeans() {
-        String result = target("test2").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-
-    @Test
-    public void testInjectionOfSetOfBeans() {
-        String result = target("test3").request().get(String.class);
-        assertEquals("test ok", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
deleted file mode 100644
index b7c56c9..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.parameterinjection;
-
-import org.glassfish.jersey.server.spring.TestComponent1;
-import org.glassfish.jersey.server.spring.TestComponent2;
-import org.springframework.beans.factory.annotation.Autowired;
-
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-@Path("/")
-public class SpringParameterInjectionTestResource {
-
-    private final TestComponent1 testComponent1;
-    private final List<TestComponent2> testComponent2List;
-    private final Set<TestComponent2> testComponent2Set;
-
-    @Autowired
-    public SpringParameterInjectionTestResource(final TestComponent1 testComponent1,
-                                                final List<TestComponent2> testComponent2List,
-                                                final Set<TestComponent2> testComponent2Set) {
-        this.testComponent1 = testComponent1;
-        this.testComponent2List = testComponent2List;
-        this.testComponent2Set = testComponent2Set;
-    }
-
-    @Path("test1")
-    @GET
-    public String test1() {
-        return testComponent1.result();
-    }
-
-    @Path("test2")
-    @GET
-    public String test2() {
-        return (testComponent2List.size() == 2 && "test ok".equals(testComponent2List.get(0).result())
-                && "test ok".equals(testComponent2List.get(1).result())) ? "test ok" : "test failed";
-    }
-
-    @Path("test3")
-    @GET
-    public String test3() {
-        Iterator<TestComponent2> iterator = testComponent2Set.iterator();
-        return (testComponent2Set.size() == 2 && "test ok".equals(iterator.next().result())
-                && "test ok".equals(iterator.next().result())) ? "test ok" : "test failed";
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
deleted file mode 100644
index 77b497c..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (c) 2014, 2019 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 org.glassfish.jersey.server.spring.profiles;
-
-import org.springframework.stereotype.Component;
-
-@Component
-public class DefaultTestService implements TestService {
-
-    @Override
-    public String test() {
-        return "default";
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
deleted file mode 100644
index 3b1f6a8..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-import org.glassfish.jersey.test.JerseyTest;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-public class SpringDefaultProfileResourceTest extends JerseyTest {
-
-    @Override
-    protected Application configure() {
-        System.setProperty("spring.profiles.active", "");
-        ApplicationContext context = new AnnotationConfigApplicationContext("org.glassfish.jersey.server.spring.profiles");
-        return new ResourceConfig()
-                .register(RequestContextFilter.class)
-                .register(LoggingFeature.class)
-                .packages("org.glassfish.jersey.server.spring.profiles")
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void shouldUseDefaultComponent() {
-        final String result = target("spring-resource").request().get(String.class);
-        Assert.assertEquals("default", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
deleted file mode 100644
index 2d7c5a1..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.logging.LoggingFeature;
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-import org.glassfish.jersey.test.JerseyTest;
-
-import org.junit.Assert;
-import org.junit.Test;
-import org.springframework.context.annotation.AnnotationConfigApplicationContext;
-
-public class SpringDevProfileResourceTest extends JerseyTest {
-
-    @Override
-    protected Application configure() {
-        System.setProperty("spring.profiles.active", "dev");
-        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(
-                "org.glassfish.jersey.server.spring.profiles");
-        return new ResourceConfig()
-                .register(RequestContextFilter.class)
-                .register(LoggingFeature.class)
-                .packages("org.glassfish.jersey.server.spring.profiles")
-                .property("contextConfig", context);
-    }
-
-    @Test
-    public void shouldUseDevProfileBean() {
-        final String result = target("spring-resource").request().get(String.class);
-        Assert.assertEquals("dev", result);
-    }
-}
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java b/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
deleted file mode 100644
index e05de3d..0000000
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (c) 2014, 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 org.glassfish.jersey.server.spring.profiles;
-
-import jakarta.inject.Singleton;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.Produces;
-import jakarta.ws.rs.core.MediaType;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-
-
-@Singleton
-@Path("spring-resource")
-@Service
-public class SpringRequestResource {
-
-    @Autowired
-    private TestService testService;
-
-    @GET
-    @Produces(MediaType.TEXT_PLAIN)
-    public String getGoodbye() {
-        return testService.test();
-    }
-
-}
diff --git a/ext/spring5/src/test/resources/jersey-spring-aspect4j-applicationContext.xml b/ext/spring5/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
deleted file mode 100644
index 7abafe3..0000000
--- a/ext/spring5/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
+++ /dev/null
@@ -1,33 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2013, 2019 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
-
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans
-    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
-    http://www.springframework.org/schema/aop
-    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
-
-    <aop:aspectj-autoproxy/>
-
-    <context:component-scan base-package="org.glassfish.jersey.server.spring"/>
-
-    <bean id="someAspect" class="org.glassfish.jersey.server.spring.aspect4j.TestAspect"/>
-</beans>
diff --git a/ext/spring6/pom.xml b/ext/spring6/pom.xml
new file mode 100644
index 0000000..2cfbff6
--- /dev/null
+++ b/ext/spring6/pom.xml
@@ -0,0 +1,361 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2012, 2022 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.glassfish.jersey.ext</groupId>
+        <artifactId>project</artifactId>
+        <version>3.1.0-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jersey-spring6</artifactId>
+    <name>jersey-spring6</name>
+
+    <packaging>jar</packaging>
+
+    <description>
+        Jersey extension module providing support for Spring 6 integration.
+    </description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <java.build.outputDirectory>${project.basedir}/target</java.build.outputDirectory>
+        <javaPre17.sourceDirectory>${project.basedir}/src/main/javaPre17</javaPre17.sourceDirectory>
+        <java17.build.outputDirectory>${project.basedir}/target17</java17.build.outputDirectory>
+        <java17.sourceDirectory>${project.basedir}/src/main/java17</java17.sourceDirectory>
+    </properties>
+
+    <repositories>
+        <repository>
+            <name>Spring Repository</name>
+            <id>spring-repository</id>
+            <url>https://repo.spring.io/milestone</url>
+        </repository>
+    </repositories>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.glassfish.jersey.core</groupId>
+            <artifactId>jersey-server</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.inject</groupId>
+            <artifactId>jersey-hk2</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.containers</groupId>
+            <artifactId>jersey-container-servlet-core</artifactId>
+            <version>${project.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
+            <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-logging</groupId>
+            <artifactId>commons-logging</artifactId>
+            <version>1.2</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>hk2</artifactId>
+            <version>${hk2.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.hk2</groupId>
+            <artifactId>spring-bridge</artifactId>
+            <version>${hk2.version}</version>
+            <exclusions>
+                <exclusion>  <!-- already pulled in by jersey-server -->
+                    <groupId>jakarta.inject</groupId>
+                    <artifactId>jakarta.inject</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.glassfish.hk2</groupId>
+                    <artifactId>hk2-api</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.springframework</groupId>
+                    <artifactId>spring-context</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>${spring6.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${spring6.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring6.version}</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+            </exclusions>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>${spring6.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>${spring6.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>jakarta.servlet</groupId>
+            <artifactId>jakarta.servlet-api</artifactId>
+            <version>${servlet6.version}</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.glassfish.jersey.test-framework</groupId>
+            <artifactId>jersey-test-framework-core</artifactId>
+            <version>${project.version}</version>
+            <scope>test</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjrt</artifactId>
+            <version>1.6.11</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.aspectj</groupId>
+            <artifactId>aspectjweaver</artifactId>
+            <version>1.6.11</version>
+            <scope>test</scope>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>com.sun.istack</groupId>
+                <artifactId>istack-commons-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>build-helper-maven-plugin</artifactId>
+                <inherited>true</inherited>
+            </plugin>
+        </plugins>
+    </build>
+
+    <profiles>
+        <profile>
+            <id>SpringExclude</id>
+            <activation>
+                <jdk>[1.8,17)</jdk>
+            </activation>
+            <build>
+                <directory>${java.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${javaPre17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-compiler-plugin</artifactId>
+                        <configuration>
+                            <testExcludes>
+                                <testExclude>org/glassfish/jersey/server/spring/**/*.java</testExclude>
+                            </testExcludes>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>SpringInclude</id>
+            <activation>
+                <jdk>[17,)</jdk>
+            </activation>
+            <build>
+                <directory>${java17.build.outputDirectory}</directory>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <phase>generate-sources</phase>
+                                <goals>
+                                    <goal>add-source</goal>
+                                </goals>
+                                <configuration>
+                                    <sources>
+                                        <source>${java17.sourceDirectory}</source>
+                                    </sources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>copyJDK17FilesToMultiReleaseJar</id>
+            <activation>
+                <file>
+                    <!-- ${java17.build.outputDirectory} does not work here -->
+                    <exists>target17/classes/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.class</exists>
+                </file>
+                <jdk>[1.8,17)</jdk>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.felix</groupId>
+                        <artifactId>maven-bundle-plugin</artifactId>
+                        <inherited>true</inherited>
+                        <extensions>true</extensions>
+                        <configuration>
+                            <instructions>
+                                <Multi-Release>true</Multi-Release>
+                            </instructions>
+                        </configuration>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-resources-plugin</artifactId>
+                        <inherited>true</inherited>
+                        <executions>
+                            <execution>
+                                <id>copy-jdk17-classes</id>
+                                <phase>prepare-package</phase>
+                                <goals>
+                                    <goal>copy-resources</goal>
+                                </goals>
+                                <configuration>
+                                    <outputDirectory>${java.build.outputDirectory}/classes/META-INF/versions/17</outputDirectory>
+                                    <resources>
+                                        <resource>
+                                            <directory>${java17.build.outputDirectory}/classes</directory>
+                                        </resource>
+                                    </resources>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-antrun-plugin</artifactId>
+                        <executions>
+                            <execution>
+                                <id>copy-jdk17-sources</id>
+                                <phase>package</phase>
+                                <configuration>
+                                    <target>
+                                        <property name="sources-jar" value="${java.build.outputDirectory}/${project.artifactId}-${project.version}-sources.jar"/>
+                                        <echo>sources-jar: ${sources-jar}</echo>
+                                        <zip destfile="${sources-jar}" update="true">
+                                            <zipfileset dir="${java17.sourceDirectory}" prefix="META-INF/versions/17"/>
+                                        </zip>
+                                    </target>
+                                </configuration>
+                                <goals>
+                                    <goal>run</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+        <profile>
+            <id>delayed-strategy-skip-test</id>
+            <activation>
+                <property>
+                    <name>org.glassfish.jersey.injection.manager.strategy</name>
+                    <value>delayed</value>
+                </property>
+            </activation>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.maven.plugins</groupId>
+                        <artifactId>maven-surefire-plugin</artifactId>
+                        <configuration>
+                            <skipTests>true</skipTests>
+                        </configuration>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+</project>
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/package-info.java b/ext/spring6/src/main/java/org/glassfish/jersey/server/spring/package-info.java
similarity index 83%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/package-info.java
rename to ext/spring6/src/main/java/org/glassfish/jersey/server/spring/package-info.java
index 0176470..229c054 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/package-info.java
+++ b/ext/spring6/src/main/java/org/glassfish/jersey/server/spring/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -15,7 +15,7 @@
  */
 
 /**
- * Jersey server-side Spring 4 integration classes.
- *
+ * Jersey server-side Spring 6 integration classes.
+ * @since 3.0.5
  */
 package org.glassfish.jersey.server.spring;
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java b/ext/spring6/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
similarity index 83%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
rename to ext/spring6/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
index e15b2c5..d4e3c8e 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
+++ b/ext/spring6/src/main/java/org/glassfish/jersey/server/spring/scope/package-info.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -15,7 +15,7 @@
  */
 
 /**
- * Jersey server-side Spring 4 integration injection scopes related classes.
- *
+ * Jersey server-side Spring 6 integration injection scopes related classes.
+ * @since 3.0.5
  */
 package org.glassfish.jersey.server.spring.scope;
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
similarity index 98%
rename from ext/spring5/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
index 61fc9b1..aca66c9 100644
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringComponentProvider.java
similarity index 97%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringComponentProvider.java
index 07208f5..358f488 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringComponentProvider.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringComponentProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -43,7 +43,7 @@
 
 /**
  * Custom ComponentProvider class.
- * Responsible for 1) bootstrapping Jersey 2 Spring integration and
+ * Responsible for 1) bootstrapping Jersey 3 Spring integration and
  * 2) making Jersey skip JAX-RS Spring component life-cycle management and leave it to us.
  *
  * @author Marko Asplund (marko.asplund at yahoo.com)
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
similarity index 92%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
index 5a06926..b47ba09 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -27,7 +27,7 @@
 import org.springframework.context.ConfigurableApplicationContext;
 
 /**
- * JAX-RS Provider class for processing Jersey 2 Spring integration container life-cycle events.
+ * JAX-RS Provider class for processing Jersey 3 Spring integration container life-cycle events.
  *
  * @author Marko Asplund (marko.asplund at yahoo.com)
  */
diff --git a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
similarity index 96%
rename from ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
index c3bac70..8e21bda 100644
--- a/ext/spring5/src/main/java/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/SpringWebApplicationInitializer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
similarity index 97%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
index ec22efa..35a9e26 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsRequestAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
similarity index 96%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
index a3ac9d1..4c2d0c2 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/JaxrsServletRequestAttributes.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, 2022 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
@@ -13,7 +13,6 @@
  *
  * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
  */
-
 package org.glassfish.jersey.server.spring.scope;
 
 import jakarta.ws.rs.container.ContainerRequestContext;
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
similarity index 98%
rename from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
rename to ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
index de87d7e..a489695 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
+++ b/ext/spring6/src/main/java17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
new file mode 100644
index 0000000..747c607
--- /dev/null
+++ b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/AutowiredInjectResolver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2013, 2022 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 org.glassfish.jersey.server.spring;
+
+import jakarta.inject.Singleton;
+import org.glassfish.jersey.internal.inject.Injectee;
+import org.glassfish.jersey.internal.inject.InjectionResolver;
+
+@Singleton
+public class AutowiredInjectResolver implements InjectionResolver {
+
+    @Override
+    public Object resolve(Injectee injectee) {
+        return null;
+    }
+
+    @Override
+    public boolean isConstructorParameterIndicator() {
+        return false;
+    }
+
+    @Override
+    public boolean isMethodParameterIndicator() {
+        return false;
+    }
+
+    @Override
+    public Class getAnnotation() {
+        return null;
+    }
+}
diff --git a/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringComponentProvider.java b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringComponentProvider.java
new file mode 100644
index 0000000..5f85ffb
--- /dev/null
+++ b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringComponentProvider.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2013, 2022 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 org.glassfish.jersey.server.spring;
+
+import org.glassfish.jersey.internal.inject.InjectionManager;
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.server.spi.ComponentProvider;
+
+import java.util.Set;
+
+/**
+ * Custom ComponentProvider class.
+ * Responsible for 1) bootstrapping Jersey 3 Spring integration and
+ * 2) making Jersey skip JAX-RS Spring component life-cycle management and leave it to us.
+ *
+ * @author Marko Asplund (marko.asplund at yahoo.com)
+ */
+public class SpringComponentProvider implements ComponentProvider {
+
+    @Override
+    public void initialize(InjectionManager injectionManager) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new IllegalStateException(LocalizationMessages.NOT_SUPPORTED());
+        }
+    }
+
+    @Override
+    public boolean bind(Class<?> component, Set<Class<?>> providerContracts) {
+        return false;
+    }
+
+    @Override
+    public void done() {
+
+    }
+}
diff --git a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
similarity index 62%
copy from ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
copy to ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
index 5a06926..15dd493 100644
--- a/ext/spring4/src/main/java/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
+++ b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/SpringLifecycleListener.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -17,41 +17,25 @@
 package org.glassfish.jersey.server.spring;
 
 import jakarta.ws.rs.ext.Provider;
-
-import jakarta.inject.Inject;
-
+import org.glassfish.jersey.internal.util.JdkVersion;
 import org.glassfish.jersey.server.spi.Container;
 import org.glassfish.jersey.server.spi.ContainerLifecycleListener;
 
-import org.springframework.context.ApplicationContext;
-import org.springframework.context.ConfigurableApplicationContext;
-
-/**
- * JAX-RS Provider class for processing Jersey 2 Spring integration container life-cycle events.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
 @Provider
 public class SpringLifecycleListener implements ContainerLifecycleListener {
 
-    @Inject
-    private ApplicationContext ctx;
-
     @Override
     public void onStartup(Container container) {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new IllegalStateException(LocalizationMessages.NOT_SUPPORTED());
+        }
     }
 
     @Override
     public void onReload(Container container) {
-        if (ctx instanceof ConfigurableApplicationContext) {
-            ((ConfigurableApplicationContext) ctx).refresh();
-        }
     }
 
     @Override
     public void onShutdown(Container container) {
-        if (ctx instanceof ConfigurableApplicationContext) {
-            ((ConfigurableApplicationContext) ctx).close();
-        }
     }
 }
diff --git a/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
new file mode 100644
index 0000000..9a41f80
--- /dev/null
+++ b/ext/spring6/src/main/javaPre17/org/glassfish/jersey/server/spring/scope/RequestContextFilter.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2013, 2022 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 org.glassfish.jersey.server.spring.scope;
+
+import jakarta.ws.rs.container.ContainerRequestContext;
+import jakarta.ws.rs.container.ContainerRequestFilter;
+import jakarta.ws.rs.container.ContainerResponseContext;
+import jakarta.ws.rs.container.ContainerResponseFilter;
+import jakarta.ws.rs.container.PreMatching;
+import jakarta.ws.rs.ext.Provider;
+import org.glassfish.jersey.internal.util.JdkVersion;
+import org.glassfish.jersey.server.spring.LocalizationMessages;
+
+import java.io.IOException;
+
+/**
+ * Spring filter to provide a bridge between JAX-RS and Spring request attributes.
+ *
+ * @author Marko Asplund (marko.asplund at yahoo.com)
+ * @author Jakub Podlesak
+ * @author Marek Potociar
+ */
+@Provider
+@PreMatching
+public final class RequestContextFilter implements ContainerRequestFilter, ContainerResponseFilter {
+
+    @Override
+    public void filter(ContainerRequestContext requestContext) throws IOException {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new IllegalStateException(LocalizationMessages.NOT_SUPPORTED());
+        }
+    }
+
+    @Override
+    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
+        if (JdkVersion.getJdkVersion().getMajor() < 17) {
+            throw new IllegalStateException(LocalizationMessages.NOT_SUPPORTED());
+        }
+    }
+}
diff --git a/ext/spring4/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider b/ext/spring6/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider
similarity index 100%
rename from ext/spring4/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider
rename to ext/spring6/src/main/resources/META-INF/services/org.glassfish.jersey.server.spi.ComponentProvider
diff --git a/ext/spring4/src/main/resources/jersey-spring-applicationContext.xml b/ext/spring6/src/main/resources/jersey-spring-applicationContext.xml
similarity index 95%
rename from ext/spring4/src/main/resources/jersey-spring-applicationContext.xml
rename to ext/spring6/src/main/resources/jersey-spring-applicationContext.xml
index 00e4dda..b563fd3 100644
--- a/ext/spring4/src/main/resources/jersey-spring-applicationContext.xml
+++ b/ext/spring6/src/main/resources/jersey-spring-applicationContext.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/main/resources/org/glassfish/jersey/server/spring/localization.properties b/ext/spring6/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
similarity index 90%
rename from ext/spring4/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
rename to ext/spring6/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
index 6fd0a06..333129d 100644
--- a/ext/spring4/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
+++ b/ext/spring6/src/main/resources/org/glassfish/jersey/server/spring/localization.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2013, 2022 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
@@ -20,6 +20,7 @@
 ctx.lookup.sucessful=Spring context lookup done.
 spring.component.provider.initialized=Spring component provider initialized.
 none.or.multiple.beans.available=None or multiple beans found in Spring context for type {0}, skipping the type.
+not.supported=Spring component is not supported on JDK version less than 17.
 bean.registered=Spring managed bean, {0}, registered with HK2.
 registering.ctx.loader.listener=Registering Spring ContextLoaderListener
 skipping.ctx.lodaer.listener.registration=Presuming Spring ContextLoaderListener was manually registered. Skipping context loader registration.
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
similarity index 91%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
index 0afc246..d1d6e7f 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/NoComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
similarity index 93%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
index 5a8123c..cd15638 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/SpringTestConfiguration.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
similarity index 92%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
index 7a065c1..927f33f 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
similarity index 91%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
index 742f421..d12d682 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
similarity index 93%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
index 25078b6..3672d0c 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
similarity index 93%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
index 9900cd4..f6c19ce 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/TestComponent2Impl2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
index 52fd0e3..d360115 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4JTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
similarity index 94%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
index 0f60e3b..f7ef7fc 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/Aspect4jJerseyConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
similarity index 95%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
index 9b96e32..2b1cf67 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/ComponentResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
similarity index 94%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
index bb5bf8a..629ffc1 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/NoComponentResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
similarity index 94%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
index 4580199..fcbe989 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/aspect4j/TestAspect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
similarity index 94%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
index 0eb367b..3e0ba86 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionJerseyTestConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
index 141d16e..c06d2db 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
index 941e311..30bc7a8 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/fieldinjection/SpringFieldInjectionTestResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
similarity index 93%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
index 5c831bf..9c157ce 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/Counter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
similarity index 95%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
index 3c33392..925ae46 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/FilterTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
similarity index 93%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
index 9fb32a8..c3a5cdd 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/JerseyTestConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
similarity index 94%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
index 8205333..a672a10 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestFilter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
similarity index 93%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
index 7e624ef..3fccdaf 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/filter/TestResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
similarity index 94%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
index 7f26bce..02e612e 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionJerseyTestConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
index 3f66478..0b087ce 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
similarity index 97%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
index 8a16bbe..ebbc49c 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/methodinjection/SpringMethodInjectionTestResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
similarity index 94%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
index d67ebd4..254ca2d 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionJerseyTestConfig.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
index e6b720e..8a1bfb5 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
similarity index 97%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
index b7c56c9..8987d72 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/parameterinjection/SpringParameterInjectionTestResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
similarity index 93%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
index 040d053..8c91747 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DefaultTestService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
similarity index 93%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
index 34dcadf..e3dcad9 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/DevTestService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
index 3b1f6a8..559d3dd 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDefaultProfileResourceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
similarity index 96%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
index 2d7c5a1..0fe73d3 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringDevProfileResourceTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
similarity index 95%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
index be0ac47..72fe2b1 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringProfilesTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
similarity index 94%
rename from ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
index e05de3d..067111a 100644
--- a/ext/spring4/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/SpringRequestResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
similarity index 91%
rename from ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
rename to ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
index d5635b5..aa134de 100644
--- a/ext/spring5/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
+++ b/ext/spring6/src/test/java/org/glassfish/jersey/server/spring/profiles/TestService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
diff --git a/ext/spring4/src/test/resources/jersey-spring-aspect4j-applicationContext.xml b/ext/spring6/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
similarity index 95%
rename from ext/spring4/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
rename to ext/spring6/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
index c80c155..a755498 100644
--- a/ext/spring4/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
+++ b/ext/spring6/src/test/resources/jersey-spring-aspect4j-applicationContext.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 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
diff --git a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessor.java b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessor.java
index 3f10dc8..feb1f43 100644
--- a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessor.java
+++ b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 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
@@ -16,6 +16,7 @@
 
 package org.glassfish.jersey.wadl.doclet;
 
+import jdk.javadoc.doclet.DocletEnvironment;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ClassDocType;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.MethodDocType;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ParamDocType;
@@ -60,6 +61,7 @@
      * @param classDocType the {@link ClassDocType} to extend. This will later be processed by the
      *                     {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
      */
+    @Deprecated
     void processClassDoc(TypeElement classDoc, ClassDocType classDocType);
 
     /**
@@ -69,6 +71,7 @@
      * @param methodDocType the related {@link MethodDocType} that will later be processed by the
      *                      {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
      */
+    @Deprecated
     void processMethodDoc(ExecutableElement methodDoc, MethodDocType methodDocType);
 
     /**
@@ -79,6 +82,45 @@
      * @param paramDocType the {@link ParamDocType} to extend. This will later be processed by the
      *                     {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
      */
+    @Deprecated
     void processParamTag(VariableElement parameter, ParamDocType paramDocType);
 
+    /**
+     * Use this method to extend the provided {@link ClassDocType} with the information from
+     * the given {@link TypeElement}.
+     *
+     * @param classDoc     the class javadoc
+     * @param classDocType the {@link ClassDocType} to extend. This will later be processed by the
+     *                     {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
+     * @param docEnv       the doclet environment used to extract info from classDoc
+     */
+    default void processClassDocWithDocEnv(TypeElement classDoc, ClassDocType classDocType, DocletEnvironment docEnv) {
+        processClassDoc(classDoc, classDocType);
+    }
+
+    /**
+     * Process the provided methodDoc and add your custom information to the methodDocType.<br>
+     *
+     * @param methodDoc     the {@link ExecutableElement} representing the docs of your method.
+     * @param methodDocType the related {@link MethodDocType} that will later be processed by the
+     *                      {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
+     * @param docEnv        the doclet environment used to extract info from methodDoc
+     */
+    default void processMethodDocWithDocEnv(ExecutableElement methodDoc, MethodDocType methodDocType, DocletEnvironment docEnv) {
+        processMethodDoc(methodDoc, methodDocType);
+    }
+
+    /**
+     * Use this method to extend the provided {@link ParamDocType} with the information from the
+     * given {@link VariableElement}.
+     *
+     * @param parameter    the parameter (that is documented or not)
+     * @param paramDocType the {@link ParamDocType} to extend. This will later be processed by the
+     *                     {@link org.glassfish.jersey.server.wadl.WadlGenerator}s.
+     * @param docEnv       the Doclet Environment used to extract info from parameter
+     */
+    default void processParamTagWithDocEnv(VariableElement parameter, ParamDocType paramDocType, DocletEnvironment docEnv) {
+        processParamTag(parameter, paramDocType);
+    }
+
 }
diff --git a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessorWrapper.java b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessorWrapper.java
index aa3e28d..03407db 100644
--- a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessorWrapper.java
+++ b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/DocProcessorWrapper.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 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
@@ -20,13 +20,13 @@
 import java.util.Arrays;
 import java.util.List;
 
+import jdk.javadoc.doclet.DocletEnvironment;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ClassDocType;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.MethodDocType;
 import org.glassfish.jersey.server.wadl.internal.generators.resourcedoc.model.ParamDocType;
 
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.element.ExecutableElement;
-import com.sun.source.doctree.ParamTree;
 import javax.lang.model.element.VariableElement;
 
 public class DocProcessorWrapper implements DocProcessor {
@@ -96,4 +96,30 @@
         }
     }
 
+    @Override
+    public void processClassDocWithDocEnv(TypeElement classDoc,
+                                          ClassDocType classDocType,
+                                          DocletEnvironment docEnv) {
+        for (DocProcessor docProcessor : _docProcessors) {
+            docProcessor.processClassDocWithDocEnv(classDoc, classDocType, docEnv);
+        }
+    }
+
+    @Override
+    public void processMethodDocWithDocEnv(ExecutableElement methodDoc,
+                                           MethodDocType methodDocType,
+                                           DocletEnvironment docEnv) {
+        for (DocProcessor docProcessor : _docProcessors) {
+            docProcessor.processMethodDocWithDocEnv(methodDoc, methodDocType, docEnv);
+        }
+    }
+
+    @Override
+    public void processParamTagWithDocEnv(VariableElement parameter,
+                                          ParamDocType paramDocType,
+                                          DocletEnvironment docEnv) {
+        for (DocProcessor docProcessor : _docProcessors) {
+            docProcessor.processParamTagWithDocEnv(parameter, paramDocType, docEnv);
+        }
+    }
 }
diff --git a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/ResourceDoclet.java b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/ResourceDoclet.java
index 944413f..763fb8d 100644
--- a/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/ResourceDoclet.java
+++ b/ext/wadl-doclet/src/main/java12/org/glassfish/jersey/wadl/doclet/ResourceDoclet.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2019, 2022 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
@@ -157,13 +157,15 @@
                     ClassDocType classDocType = new ClassDocType();
                     classDocType.setClassName(element.getQualifiedName().toString());
                     classDocType.setCommentText(getComments(docCommentTree));
-                    docProcessor.processClassDoc(element, classDocType);
+                    docProcessor.processClassDocWithDocEnv(element, classDocType, docEnv);
                     for (ExecutableElement method : ElementFilter.methodsIn(element.getEnclosedElements())) {
                         Map<DocTree.Kind, Map<String, String>> tags = getTags(docTrees.getDocCommentTree(method));
                         MethodTree methodTree = docTrees.getTree(method);
                         MethodDocType methodDocType = new MethodDocType();
-                        methodDocType.setMethodName(methodTree.getName().toString());
-                        methodDocType.setCommentText(getComments(docTrees.getDocCommentTree(method)));
+                        if (methodTree != null) {
+                            methodDocType.setMethodName(methodTree.getName().toString());
+                            methodDocType.setCommentText(getComments(docTrees.getDocCommentTree(method)));
+                        }
                         getTags(docTrees.getDocCommentTree(method));
                         StringBuilder arguments = new StringBuilder("(");
                         Map<String, String> paramTags = tags.get(DocTree.Kind.PARAM);
@@ -172,7 +174,7 @@
                             arguments.append(parameter.asType()).append(COMA);
                             if (paramDocType != null) {
                                 methodDocType.getParamDocs().add(paramDocType);
-                                docProcessor.processParamTag(parameter, paramDocType);
+                                docProcessor.processParamTagWithDocEnv(parameter, paramDocType, docEnv);
                             }
                         }
                         // Remove last comma if there are parameters
@@ -181,7 +183,7 @@
                         }
                         arguments.append(")");
                         methodDocType.setMethodSignature(arguments.toString());
-                        docProcessor.processMethodDoc(method, methodDocType);
+                        docProcessor.processMethodDocWithDocEnv(method, methodDocType, docEnv);
                         methodDocType.setRequestDoc(buildRequestDocType(tags));
                         methodDocType.setResponseDoc(buildResponseDocType(tags));
                         classDocType.getMethodDocs().add(methodDocType);
diff --git a/inject/hk2/pom.xml b/inject/hk2/pom.xml
index 2db8d67..fd0875b 100644
--- a/inject/hk2/pom.xml
+++ b/inject/hk2/pom.xml
@@ -67,7 +67,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/pom.xml b/pom.xml
index f50a744..20535cc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -413,6 +413,8 @@
                     <artifactId>maven-surefire-plugin</artifactId>
                     <version>${surefire.version}</version>
                     <configuration>
+                        <!-- print full stack trace if error -->
+                        <trimStackTrace>false</trimStackTrace>
                         <!-- for convenience reasons, 'argLine' should not be overridden in child poms. if needed, a property should be declared and used here -->
                         <argLine>
                             -Xmx${surefire.maxmem.argline}m -Dfile.encoding=UTF8 ${surefire.security.argline} ${surefire.coverage.argline}
@@ -462,7 +464,7 @@
                                 All Rights Reserved. Use is subject to license terms.]]>
                         </bottom>
                         <links>
-                            <link>https://jakartaee.github.io/rest/apidocs/2.1.6/</link>
+                            <link>https://jakartaee.github.io/rest/apidocs/3.0.0/</link>
                             <link>https://javaee.github.io/hk2/apidocs/</link>
                         </links>
                         <excludePackageNames>
@@ -613,6 +615,8 @@
                     <artifactId>maven-failsafe-plugin</artifactId>
                     <version>3.0.0-M3</version>
                     <configuration>
+                        <!-- print full stack trace if error -->
+                        <trimStackTrace>false</trimStackTrace>
                         <skipTests>${skip.tests}</skipTests>
                         <skipITs>${skip.tests}</skipITs>
                         <argLine>${failsafe.coverage.argline}</argLine>
@@ -1539,11 +1543,11 @@
                 <version>${jakarta.activation.version}</version>
             </dependency>
 
-            <dependency>
+            <!--<dependency>
                 <groupId>com.google.guava</groupId>
                 <artifactId>guava</artifactId>
                 <version>${guava.version}</version>
-            </dependency>
+            </dependency>--> <!-- The latest repackaged guava version is 18.0 -->
 
             <dependency>
                 <groupId>org.glassfish.hk2</groupId>
@@ -1640,6 +1644,11 @@
                 <artifactId>httpclient</artifactId>
                 <version>${httpclient.version}</version>
             </dependency>
+            <dependency>
+                <groupId>org.apache.httpcomponents.client5</groupId>
+                <artifactId>httpclient5</artifactId>
+                <version>${httpclient5.version}</version>
+            </dependency>
 
             <dependency>
                 <groupId>org.eclipse.jetty</groupId>
@@ -1985,7 +1994,7 @@
 
             <dependency>
                 <groupId>org.hamcrest</groupId>
-                <artifactId>hamcrest-library</artifactId>
+                <artifactId>hamcrest</artifactId>
                 <version>${hamcrest.version}</version>
                 <scope>test</scope>
             </dependency>
@@ -2103,6 +2112,7 @@
         <bnd.plugin.version>2.3.6</bnd.plugin.version>
 
         <bouncycastle.version>1.68</bouncycastle.version>
+        <commons.io.version>2.11.0</commons.io.version>
         <commons-lang3.version>3.3.2</commons-lang3.version>
         <checkstyle.mvn.plugin.version>3.1.0</checkstyle.mvn.plugin.version>
         <checkstyle.version>8.28</checkstyle.version>
@@ -2122,10 +2132,13 @@
         <smallrye.config.version>3.0.0-RC1</smallrye.config.version>
 
 
-        <guava.version>18.0</guava.version>
-        <hamcrest.version>1.3</hamcrest.version>
+        <grizzly2.version>2.4.4</grizzly2.version>
+        <guava.version>31.1-jre</guava.version>
+        <hamcrest.version>2.2</hamcrest.version>
+        <!--<helidon.version>1.0.3</helidon.version>-->
         <xmlunit.version>1.6</xmlunit.version>
         <httpclient.version>4.5.13</httpclient.version>
+        <httpclient5.version>5.1.2</httpclient5.version>
         <jackson.version>2.13.0</jackson.version>
         <javassist.version>3.28.0-GA</javassist.version>
         <jboss.logging.version>3.3.0.Final</jboss.logging.version>
@@ -2138,7 +2151,7 @@
         <kryo.version>4.0.1</kryo.version>
         <mockito.version>3.9.0</mockito.version> <!-- CQ 17673 -->
         <mustache.version>0.8.17</mustache.version>
-        <netty.version>4.1.43.Final</netty.version>
+        <netty.version>4.1.75.Final</netty.version>
         <nexus-staging.mvn.plugin.version>1.6.7</nexus-staging.mvn.plugin.version>
         <opentracing.version>0.30.0</opentracing.version>
         <osgi.version>6.0.0</osgi.version>
@@ -2157,15 +2170,15 @@
         <simple.version>6.0.1</simple.version>
         <skip.e2e>false</skip.e2e>
         <slf4j.version>1.7.21</slf4j.version>
-        <spring4.version>4.3.20.RELEASE</spring4.version>
-        <spring5.version>5.1.5.RELEASE</spring5.version>
-        <surefire.version>3.0.0-M5</surefire.version>
+        <spring6.version>6.0.0-M3</spring6.version>
+        <surefire.version>3.0.0-M6</surefire.version>
 
         <!-- Jakartified, eligible for CQ -->
         <weld.version>5.0.0.CR2</weld.version>
+        <weld3.version>3.1.7.SP1</weld3.version>
         <validation.impl.version>8.0.0.Alpha1</validation.impl.version>
         <!-- END of Jakartified, eligible for CQ -->
-        <xerces.version>2.11.0</xerces.version>
+        <xerces.version>2.12.2</xerces.version>
 
         <!-- Graal VM       -->
         <graalvm.version>20.3.2</graalvm.version>
@@ -2207,7 +2220,7 @@
         <jsonp.ri.version>1.1.0</jsonp.ri.version>
         <jsonp.jaxrs.version>1.1.0</jsonp.jaxrs.version>
         <moxy.version>4.0.0-M3</moxy.version>
-        <yasson.version>3.0.0-RC1</yasson.version>
+        <yasson.version>3.0.0-RC2</yasson.version>
         <!-- END of Jakartified -->
 
         <javax.annotation.version>1.3.2</javax.annotation.version> <!--Deprecated, used only for @generated annotation in perf tests -->
diff --git a/test-framework/maven/container-runner-maven-plugin/pom.xml b/test-framework/maven/container-runner-maven-plugin/pom.xml
index 33c7454..1f75a57 100644
--- a/test-framework/maven/container-runner-maven-plugin/pom.xml
+++ b/test-framework/maven/container-runner-maven-plugin/pom.xml
@@ -119,12 +119,6 @@
             <version>${project.version}</version>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>27.0.1-jre</version>
-        </dependency>
-
     </dependencies>
 
     <build>
diff --git a/test-framework/maven/custom-enforcer-rules/pom.xml b/test-framework/maven/custom-enforcer-rules/pom.xml
index a05abc4..909d37d 100644
--- a/test-framework/maven/custom-enforcer-rules/pom.xml
+++ b/test-framework/maven/custom-enforcer-rules/pom.xml
@@ -46,12 +46,7 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <version>2.7</version>
-        </dependency>
-
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
+            <version>${commons.io.version}</version>
         </dependency>
 
         <dependency>
diff --git a/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/PatternNotMatchedInFileRule.java b/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/PatternNotMatchedInFileRule.java
index 8872e15..5906b3e 100644
--- a/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/PatternNotMatchedInFileRule.java
+++ b/test-framework/maven/custom-enforcer-rules/src/main/java/org/glassfish/jersey/test/maven/rule/PatternNotMatchedInFileRule.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -19,18 +19,16 @@
 import java.io.File;
 import java.io.IOException;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.util.Arrays;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import org.apache.maven.enforcer.rule.api.EnforcerRuleException;
 import org.apache.maven.enforcer.rule.api.EnforcerRuleHelper;
 import org.apache.maven.plugins.enforcer.AbstractNonCacheableEnforcerRule;
 
-import com.google.common.io.Files;
-import com.google.common.io.LineProcessor;
-
 /**
  * Maven enforcer rule to enforce that given file does not contain line matching given pattern. When matched, exception is
  * raised.
@@ -67,25 +65,8 @@
         final Pattern patternCompiled = Pattern.compile(pattern);
         try {
 
-            final List<String> lines = Files.readLines(file, Charset.defaultCharset(), new LineProcessor<List<String>>() {
-                private List<String> matchedLines = new LinkedList<>();
-
-                @Override
-                public boolean processLine(final String line) throws IOException {
-                    if (patternCompiled.matcher(line).matches()) {
-                        matchedLines.add(line);
-                        if (maxMatchedLines != 0 && maxMatchedLines <= matchedLines.size()) {
-                            return false;
-                        }
-                    }
-                    return true;
-                }
-
-                @Override
-                public List<String> getResult() {
-                    return matchedLines;
-                }
-            });
+            final List<String> lines = Files.lines(file.toPath(), Charset.defaultCharset())
+                    .filter(line -> patternCompiled.matcher(line).matches()).collect(Collectors.toList());
 
             if (lines.size() > 0) {
                 throw new EnforcerRuleException(
diff --git a/test-framework/memleak-test-common/pom.xml b/test-framework/memleak-test-common/pom.xml
index 802cea4..08b0dac 100644
--- a/test-framework/memleak-test-common/pom.xml
+++ b/test-framework/memleak-test-common/pom.xml
@@ -41,10 +41,6 @@
             <artifactId>junit</artifactId>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
     </dependencies>
 
 </project>
diff --git a/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java b/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
index e19b2c9..d519d3f 100644
--- a/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
+++ b/test-framework/memleak-test-common/src/main/java/org/glassfish/jersey/test/memleak/common/MemoryLeakUtils.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -22,17 +22,15 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.nio.charset.Charset;
+import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.util.Arrays;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import javax.management.MBeanServer;
 
-import com.google.common.io.Files;
-import com.google.common.io.LineProcessor;
-
 /**
  * Utility class for memory leak test infrastructure.
  *
@@ -87,22 +85,8 @@
             return;
         }
 
-        final List<String> lines = Files.readLines(logFile, Charset.defaultCharset(), new LineProcessor<List<String>>() {
-            private List<String> matchedLines = new LinkedList<>();
-
-            @Override
-            public boolean processLine(final String line) throws IOException {
-                if (PATTERN.matcher(line).matches()) {
-                    matchedLines.add(line);
-                }
-                return true;
-            }
-
-            @Override
-            public List<String> getResult() {
-                return matchedLines;
-            }
-        });
+        final List<String> lines = Files.lines(logFile.toPath(), Charset.defaultCharset())
+                .filter(line -> PATTERN.matcher(line).matches()).collect(Collectors.toList());
 
         if (lines.size() > 0) {
             throw new IllegalStateException(
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index 51ce01e..b52fcd7 100644
--- a/tests/e2e-client/pom.xml
+++ b/tests/e2e-client/pom.xml
@@ -119,6 +119,11 @@
         </dependency>
         <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
+            <artifactId>jersey-apache5-connector</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-grizzly-connector</artifactId>
             <scope>test</scope>
         </dependency>
@@ -158,13 +163,6 @@
         </dependency>
 
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${guava.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.glassfish.jersey.test-framework</groupId>
             <artifactId>jersey-test-framework-util</artifactId>
             <scope>test</scope>
@@ -176,7 +174,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/BufferingTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/BufferingTest.java
index 8595463..74f6bf1 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/BufferingTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/BufferingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -29,6 +29,7 @@
 import jakarta.ws.rs.core.UriBuilder;
 
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.ClientProperties;
 import org.glassfish.jersey.client.RequestEntityProcessing;
@@ -74,6 +75,15 @@
     }
 
     @Test
+    public void testApache5Connector() {
+        testWithBuffering(getApache5ConnectorConfig());
+        testWithChunkEncodingWithoutPropertyDefinition(getApache5ConnectorConfig());
+        testWithChunkEncodingWithPropertyDefinition(getApache5ConnectorConfig());
+        testWithChunkEncodingPerRequest(getApache5ConnectorConfig());
+        testDefaultOption(getApache5ConnectorConfig(), RequestEntityProcessing.CHUNKED);
+    }
+
+    @Test
     public void testGrizzlyConnector() {
         testWithBuffering(getGrizzlyConnectorConfig());
         testWithChunkEncodingWithoutPropertyDefinition(getGrizzlyConnectorConfig());
@@ -95,6 +105,10 @@
         return new ClientConfig().connectorProvider(new ApacheConnectorProvider());
     }
 
+    private ClientConfig getApache5ConnectorConfig() {
+        return new ClientConfig().connectorProvider(new Apache5ConnectorProvider());
+    }
+
     private ClientConfig getGrizzlyConnectorConfig() {
         return new ClientConfig().connectorProvider(new GrizzlyConnectorProvider());
     }
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
index 9c04cc5..4a4fabe 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/HttpPatchTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 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
@@ -31,6 +31,7 @@
 import jakarta.ws.rs.core.Response;
 
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
@@ -42,7 +43,6 @@
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
 
-import org.junit.Ignore;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
@@ -63,7 +63,7 @@
                 {GrizzlyConnectorProvider.class},
                 {JettyConnectorProvider.class}, // unstable.
                 {ApacheConnectorProvider.class},
-                {GrizzlyConnectorProvider.class},
+                {Apache5ConnectorProvider.class},
                 {NettyConnectorProvider.class},
                 {JdkConnectorProvider.class},
                 }));
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
index ebacf52..d955ff3 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/RequestHeaderModificationsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
@@ -52,6 +52,7 @@
 import jakarta.annotation.Priority;
 
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
@@ -103,10 +104,12 @@
                 {GrizzlyConnectorProvider.class, false, false}, // change to true when JERSEY-2341 fixed
                 {JettyConnectorProvider.class, false, false}, // change to true when JERSEY-2341 fixed
                 {ApacheConnectorProvider.class, false, false}, // change to true when JERSEY-2341 fixed
+                {Apache5ConnectorProvider.class, false, false}, // change to true when JERSEY-2341 fixed
                 {HttpUrlConnectorProvider.class, true, true},
                 {GrizzlyConnectorProvider.class, false, true}, // change to true when JERSEY-2341 fixed
                 {JettyConnectorProvider.class, false, true}, // change to true when JERSEY-2341 fixed
                 {ApacheConnectorProvider.class, false, true}, // change to true when JERSEY-2341 fixed
+                {Apache5ConnectorProvider.class, false, true}, // change to true when JERSEY-2341 fixed
         }));
     }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
index 8b22485..f26fca9 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/AbstractConnectorServerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -24,6 +24,7 @@
 
 import org.glassfish.jersey.SslConfigurator;
 import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.spi.ConnectorProvider;
 import org.glassfish.jersey.grizzly.connector.GrizzlyConnectorProvider;
@@ -61,7 +62,8 @@
                 {new HttpUrlConnectorProvider()},
                 {new GrizzlyConnectorProvider()},
                 {new JettyConnectorProvider()},
-                {new ApacheConnectorProvider()}
+                {new ApacheConnectorProvider()},
+                {new Apache5ConnectorProvider()}
         }));
     }
 
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorConfigurationTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorConfigurationTest.java
index 1d2428d..801d28c 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorConfigurationTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslConnectorConfigurationTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2022 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
@@ -23,7 +23,6 @@
 
 import javax.net.ssl.SSLContext;
 
-import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
 import org.glassfish.jersey.logging.LoggingFeature;
@@ -78,7 +77,7 @@
     public void testHTTPBasicAuth1() throws Exception {
         final SSLContext sslContext = getSslContext();
 
-        final ClientConfig cc = new ClientConfig().connectorProvider(new ApacheConnectorProvider());
+        final ClientConfig cc = new ClientConfig().connectorProvider(connectorProvider);
         final Client client = ClientBuilder.newBuilder()
                 .withConfig(cc)
                 .sslContext(sslContext)
@@ -101,7 +100,7 @@
     public void testSSLAuth1() throws Exception {
         final SSLContext sslContext = getSslContext();
 
-        final ClientConfig cc = new ClientConfig().connectorProvider(new ApacheConnectorProvider());
+        final ClientConfig cc = new ClientConfig().connectorProvider(connectorProvider);
         final Client client = ClientBuilder.newBuilder()
                 .withConfig(cc)
                 .sslContext(sslContext)
diff --git a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java
index 3a24930..f687407 100644
--- a/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java
+++ b/tests/e2e-client/src/test/java/org/glassfish/jersey/tests/e2e/client/connector/ssl/SslHttpUrlConnectorTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -38,6 +38,8 @@
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
 
+import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
+import org.glassfish.jersey.apache5.connector.Apache5ConnectorProvider;
 import org.glassfish.jersey.client.ClientConfig;
 import org.glassfish.jersey.client.HttpUrlConnectorProvider;
 import org.glassfish.jersey.client.authentication.HttpAuthenticationFeature;
@@ -94,9 +96,16 @@
      */
     @Test
     public void testConcurrentRequestsWithCustomSSLContext() throws Exception {
+        if (HttpUrlConnectorProvider.class.isInstance(connectorProvider)
+                || (ApacheConnectorProvider.class.isInstance(connectorProvider))
+                || (Apache5ConnectorProvider.class.isInstance(connectorProvider))) {
+            return;
+        }
         final SSLContext sslContext = getSslContext();
 
+        final ClientConfig cc = new ClientConfig().connectorProvider(connectorProvider);
         final Client client = ClientBuilder.newBuilder()
+            .withConfig(cc)
             .sslContext(sslContext)
             .register(HttpAuthenticationFeature.basic("user", "password"))
             .register(LoggingFeature.class)
diff --git a/tests/e2e-core-common/pom.xml b/tests/e2e-core-common/pom.xml
index 87be1d8..b0ff4eb 100644
--- a/tests/e2e-core-common/pom.xml
+++ b/tests/e2e-core-common/pom.xml
@@ -35,7 +35,7 @@
     <dependencies>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/e2e-entity/pom.xml b/tests/e2e-entity/pom.xml
index 506d61a..28d2747 100644
--- a/tests/e2e-entity/pom.xml
+++ b/tests/e2e-entity/pom.xml
@@ -160,13 +160,6 @@
         </dependency>
 
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${guava.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.glassfish.jersey.test-framework</groupId>
             <artifactId>jersey-test-framework-util</artifactId>
             <scope>test</scope>
@@ -174,7 +167,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/tests/e2e-inject/cdi-inject-weld/pom.xml b/tests/e2e-inject/cdi-inject-weld/pom.xml
index 89c9804..97697b2 100644
--- a/tests/e2e-inject/cdi-inject-weld/pom.xml
+++ b/tests/e2e-inject/cdi-inject-weld/pom.xml
@@ -75,7 +75,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/e2e-inject/cdi-inject-weld/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/weld/RequestContextBuilder.java b/tests/e2e-inject/cdi-inject-weld/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/weld/RequestContextBuilder.java
index 94849a7..5eb8dd2 100644
--- a/tests/e2e-inject/cdi-inject-weld/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/weld/RequestContextBuilder.java
+++ b/tests/e2e-inject/cdi-inject-weld/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/weld/RequestContextBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2021, 2022 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
@@ -80,31 +80,33 @@
         public void setWorkers(final MessageBodyWorkers workers) {
             super.setWorkers(workers);
             final byte[] entityBytes;
-            if (entity != null) {
-                final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
-                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                OutputStream stream = null;
-                try {
-                    stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
-                            new Annotation[0], getMediaType(),
-                            myMap,
-                            propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
-                } catch (final IOException | WebApplicationException ex) {
-                    Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
-                } finally {
-                    if (stream != null) {
-                        try {
-                            stream.close();
-                        } catch (final IOException e) {
-                            // ignore
+            if (workers != null) {
+                if (entity != null) {
+                    final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    OutputStream stream = null;
+                    try {
+                        stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
+                                new Annotation[0], getMediaType(),
+                                myMap,
+                                propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
+                    } catch (final IOException | WebApplicationException ex) {
+                        Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
+                    } finally {
+                        if (stream != null) {
+                            try {
+                                stream.close();
+                            } catch (final IOException e) {
+                                // ignore
+                            }
                         }
                     }
+                    entityBytes = baos.toByteArray();
+                } else {
+                    entityBytes = new byte[0];
                 }
-                entityBytes = baos.toByteArray();
-            } else {
-                entityBytes = new byte[0];
+                setEntityStream(new ByteArrayInputStream(entityBytes));
             }
-            setEntityStream(new ByteArrayInputStream(entityBytes));
         }
     }
 
diff --git a/tests/e2e-inject/cdi2-se/pom.xml b/tests/e2e-inject/cdi2-se/pom.xml
index efbbae1..ea644cd 100644
--- a/tests/e2e-inject/cdi2-se/pom.xml
+++ b/tests/e2e-inject/cdi2-se/pom.xml
@@ -55,7 +55,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/e2e-inject/cdi2-se/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/se/RequestContextBuilder.java b/tests/e2e-inject/cdi2-se/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/se/RequestContextBuilder.java
index 7f9146b..42a04a3 100644
--- a/tests/e2e-inject/cdi2-se/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/se/RequestContextBuilder.java
+++ b/tests/e2e-inject/cdi2-se/src/test/java/org/glassfish/jersey/tests/e2e/inject/cdi/se/RequestContextBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2017, 2022 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
@@ -81,31 +81,33 @@
         public void setWorkers(final MessageBodyWorkers workers) {
             super.setWorkers(workers);
             final byte[] entityBytes;
-            if (entity != null) {
-                final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
-                final ByteArrayOutputStream baos = new ByteArrayOutputStream();
-                OutputStream stream = null;
-                try {
-                    stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
-                            new Annotation[0], getMediaType(),
-                            myMap,
-                            propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
-                } catch (final IOException | WebApplicationException ex) {
-                    Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
-                } finally {
-                    if (stream != null) {
-                        try {
-                            stream.close();
-                        } catch (final IOException e) {
-                            // ignore
+            if (workers != null) {
+                if (entity != null) {
+                    final MultivaluedMap<String, Object> myMap = new MultivaluedHashMap<String, Object>(getHeaders());
+                    final ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                    OutputStream stream = null;
+                    try {
+                        stream = workers.writeTo(entity, entity.getClass(), entityType.getType(),
+                                new Annotation[0], getMediaType(),
+                                myMap,
+                                propertiesDelegate, baos, Collections.<WriterInterceptor>emptyList());
+                    } catch (final IOException | WebApplicationException ex) {
+                        Logger.getLogger(TestContainerRequest.class.getName()).log(Level.SEVERE, null, ex);
+                    } finally {
+                        if (stream != null) {
+                            try {
+                                stream.close();
+                            } catch (final IOException e) {
+                                // ignore
+                            }
                         }
                     }
+                    entityBytes = baos.toByteArray();
+                } else {
+                    entityBytes = new byte[0];
                 }
-                entityBytes = baos.toByteArray();
-            } else {
-                entityBytes = new byte[0];
+                setEntityStream(new ByteArrayInputStream(entityBytes));
             }
-            setEntityStream(new ByteArrayInputStream(entityBytes));
         }
     }
 
diff --git a/tests/e2e-server/pom.xml b/tests/e2e-server/pom.xml
index aedaed3..aca4fa5 100644
--- a/tests/e2e-server/pom.xml
+++ b/tests/e2e-server/pom.xml
@@ -169,13 +169,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${guava.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.glassfish.jersey.test-framework</groupId>
             <artifactId>jersey-test-framework-util</artifactId>
             <scope>test</scope>
@@ -183,7 +176,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4097Test.java b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4097Test.java
new file mode 100644
index 0000000..ebe9bf7
--- /dev/null
+++ b/tests/e2e-server/src/test/java/org/glassfish/jersey/tests/e2e/server/Issue4097Test.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.tests.e2e.server;
+
+import static org.junit.Assert.assertEquals;
+
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.client.WebTarget;
+import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Response;
+
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.junit.Test;
+
+public class Issue4097Test extends JerseyTest {
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig(Issue4097Resource.class);
+    }
+
+    @Test
+    public void reuseResponse() throws InterruptedException {
+        WebTarget webTarget = target("/issue4097/reuseResponse");
+        assertEquals(410, webTarget.request().get().getStatus());
+        assertEquals(500, webTarget.request().get().getStatus());
+        assertEquals(500, webTarget.request().get().getStatus());
+    }
+
+    @Path("/issue4097")
+    public static class Issue4097Resource {
+
+        private static final Response RESPONSE =
+            Response.status(410).entity("test").build();
+
+        @GET
+        @Path("/reuseResponse")
+        public Response reuseResponse() {
+            // returning the same response is obviously wrong
+            return RESPONSE;
+        }
+    }
+
+}
diff --git a/tests/e2e/pom.xml b/tests/e2e/pom.xml
index 85d2e40..ec78efa 100644
--- a/tests/e2e/pom.xml
+++ b/tests/e2e/pom.xml
@@ -171,13 +171,6 @@
         </dependency>
 
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <version>${guava.version}</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
             <groupId>org.glassfish.jersey.test-framework</groupId>
             <artifactId>jersey-test-framework-util</artifactId>
             <scope>test</scope>
@@ -185,7 +178,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
 
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/common/LoggingFeatureTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/common/LoggingFeatureTest.java
index e24905f..f005095 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/common/LoggingFeatureTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/common/LoggingFeatureTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
@@ -18,10 +18,13 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
+import java.util.Locale;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.Logger;
+import java.util.regex.Pattern;
 
 import jakarta.ws.rs.GET;
 import jakarta.ws.rs.POST;
@@ -37,6 +40,8 @@
 import jakarta.ws.rs.container.ContainerResponseContext;
 import jakarta.ws.rs.container.ContainerResponseFilter;
 import jakarta.ws.rs.core.Application;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
 import jakarta.ws.rs.core.MediaType;
 import jakarta.ws.rs.core.Response;
 
@@ -48,9 +53,13 @@
 import org.glassfish.jersey.test.JerseyTest;
 import org.glassfish.jersey.test.TestProperties;
 
+import org.hamcrest.Matcher;
+import org.hamcrest.core.SubstringMatcher;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
+
+import static org.hamcrest.CoreMatchers.allOf;
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.equalTo;
 import static org.hamcrest.CoreMatchers.is;
@@ -117,6 +126,16 @@
                     .build();
         }
 
+        @Path("/echo-headers")
+        @GET
+        @Produces(TEXT_MEDIA_TYPE)
+        public Response getSameHeadersAsRequest(@Context HttpHeaders httpHeaders) {
+            Response.ResponseBuilder responseBuilder = Response.ok(ENTITY);
+            httpHeaders.getRequestHeaders().forEach(
+                    (key, values) -> values.forEach(
+                            value -> responseBuilder.header(key, value)));
+            return responseBuilder.build();
+        }
     }
 
     /**
@@ -269,11 +288,9 @@
         @Test
         public void testLoggingFeatureBuilderProperty() {
             final Response response = target("/text")
-                    .register(LoggingFeature
-                            .builder()
-                            .withLogger(Logger.getLogger(LOGGER_NAME))
-                            .build()
-                    ).property(LoggingFeature.LOGGING_FEATURE_SEPARATOR, SEPARATOR)
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_SEPARATOR, SEPARATOR)
                     .request()
                     .post(Entity.text(ENTITY));
 
@@ -284,6 +301,236 @@
             assertThat(record.getMessage(), containsString(SEPARATOR));
         }
 
+        @Test
+        public void testLoggingFeatureMaxEntitySize() {
+            final Response response = target("/text")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_MAX_ENTITY_SIZE, 1)
+                    .request()
+                    .post(Entity.text(ENTITY));
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for trimmedEntity.
+            String trimmedEntity = ENTITY.charAt(0) + "...more...";
+            List<LogRecord> logRecords = getLoggedRecords();
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), containsString(trimmedEntity));
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), containsString(trimmedEntity));
+        }
+
+        @Test
+        public void testSingleValuedHeader() {
+            String headerName = "X-Single-Valued-Header";
+            String headerValue = "test-value";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .request()
+                    .header(headerName, headerValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = new ContainsHeaderMatcher(headerName, headerValue);
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testMultivaluedHeader() {
+            String headerName = "X-Multi-Valued-Header";
+            String firstHeaderValue = "first-value";
+            String secondHeaderValue = "second-value";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .request()
+                    .header(headerName, firstHeaderValue)
+                    .header(headerName, secondHeaderValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = new ContainsHeaderMatcher(headerName, firstHeaderValue, secondHeaderValue);
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testMultipleHeaders() {
+            String firstHeaderName = "X-First-Header";
+            String firstHeaderValue = "first-value";
+            String secondHeaderName = "X-Second-Header";
+            String secondHeaderValue = "second-value";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .request()
+                    .header(firstHeaderName, firstHeaderValue)
+                    .header(secondHeaderName, secondHeaderValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(firstHeaderName, firstHeaderValue),
+                    new ContainsHeaderMatcher(secondHeaderName, secondHeaderValue));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testAuthorizationHeaderRedactedByDefault() {
+            String headerName = HttpHeaders.AUTHORIZATION;
+            String headerValue = "username:password";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .request()
+                    .header(headerName, headerValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(headerName, "[redacted]"),
+                    not(containsString(headerValue)));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testLoggingFeatureRedactOneHeader() {
+            String headerName = "X-Redact-This-Header";
+            String headerValue = "sensitive-info";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS, headerName)
+                    .request()
+                    .header(headerName, headerValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(headerName, "[redacted]"),
+                    not(containsString(headerValue)));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testLoggingFeatureRedactOneHeaderNormalizing() {
+            String headerName = "X-Redact-This-Header";
+            String headerValue = "sensitive-info";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS,
+                            " " + headerName.toUpperCase(Locale.ROOT) + " ")
+                    .request()
+                    .header(headerName, headerValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(headerName, "[redacted]"),
+                    not(containsString(headerValue)));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testLoggingFeatureRedactMultivaluedHeader() {
+            String headerName = "X-Redact-This-Header";
+            String firstHeaderValue = "sensitive-info";
+            String secondHeaderValue = "additional-info";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS, headerName)
+                    .request()
+                    .header(headerName, firstHeaderValue)
+                    .header(headerName, secondHeaderValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(headerName, "[redacted]"),
+                    not(containsString(firstHeaderValue)),
+                    not(containsString(secondHeaderValue)));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testLoggingFeatureRedactMultipleHeaders() {
+            String firstHeaderName = "X-Redact-This-Header";
+            String firstHeaderValue = "sensitive-info";
+            String secondHeaderName = "X-Also-Redact-This-Header";
+            String secondHeaderValue = "additional-info";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS, firstHeaderName + ';' + secondHeaderName)
+                    .request()
+                    .header(firstHeaderName, firstHeaderValue)
+                    .header(secondHeaderName, secondHeaderValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(firstHeaderName, "[redacted]"),
+                    not(containsString(firstHeaderValue)),
+                    new ContainsHeaderMatcher(secondHeaderName, "[redacted]"),
+                    not(containsString(secondHeaderValue)));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
+
+        @Test
+        public void testLoggingFeatureRedactZeroHeaders() {
+            String headerName = HttpHeaders.AUTHORIZATION;
+            String headerValue = "username:password";
+            final Response response = target("/echo-headers")
+                    .register(LoggingFeature.class)
+                    .property(LoggingFeature.LOGGING_FEATURE_LOGGER_NAME, LOGGER_NAME)
+                    .property(LoggingFeature.LOGGING_FEATURE_REDACT_HEADERS, "")
+                    .request()
+                    .header(headerName, headerValue)
+                    .get();
+
+            // Correct response status.
+            assertThat(response.getStatus(), is(Response.Status.OK.getStatusCode()));
+            // Check logs for header
+            List<LogRecord> logRecords = getLoggedRecords();
+            Matcher<String> matcher = allOf(
+                    new ContainsHeaderMatcher(headerName, headerValue),
+                    not(containsString("[redacted]")));
+            assertThat(getLoggingFilterRequestLogRecord(logRecords).getMessage(), matcher);
+            assertThat(getLoggingFilterResponseLogRecord(logRecords).getMessage(), matcher);
+        }
     }
 
     /**
@@ -488,4 +735,37 @@
         }
 
     }
+
+    private static final class ContainsHeaderMatcher extends SubstringMatcher {
+
+        ContainsHeaderMatcher(String headerName, String... headerValues) {
+            super(makeRegex(headerName, Arrays.asList(headerValues)));
+        }
+
+        private static String makeRegex(String headerName, List<String> headerValues) {
+            StringBuilder stringBuilder = new StringBuilder("^[\\s\\S]*")
+                    // Header name is case insensitive
+                    .append("(?i)").append(quote(headerName)).append("(?-i): ");
+
+            // Not assuming order of header values is guaranteed to be consistent
+            headerValues.forEach(headerValue -> stringBuilder
+                    .append("(?=.*").append(quote(headerValue)).append(",?)"));
+
+            return stringBuilder.append("[\\s\\S]*$").toString();
+        }
+
+        private static String quote(String input) {
+            return Pattern.quote(input);
+        }
+
+        @Override
+        protected boolean evalSubstringOf(String string) {
+            return string.matches(substring);
+        }
+
+        @Override
+        protected String relationship() {
+            return "matching regex";
+        }
+    }
 }
diff --git a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/LeadingSlashesTest.java b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/LeadingSlashesTest.java
index 9af6cb5..19ce489 100644
--- a/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/LeadingSlashesTest.java
+++ b/tests/e2e/src/test/java/org/glassfish/jersey/tests/e2e/container/LeadingSlashesTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
diff --git a/tests/integration/asm/pom.xml b/tests/integration/asm/pom.xml
index 53056eb..9ee983a 100644
--- a/tests/integration/asm/pom.xml
+++ b/tests/integration/asm/pom.xml
@@ -49,7 +49,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
index a15f2f5..e4769b2 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
@@ -66,7 +66,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml b/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
index a7084f3..fd910a3 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/war2/pom.xml
@@ -61,7 +61,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/cdi-integration/cdi-test-webapp/src/test/java/org/glassfish/jersey/tests/cdi/resources/CdiComponentProviderTest.java b/tests/integration/cdi-integration/cdi-test-webapp/src/test/java/org/glassfish/jersey/tests/cdi/resources/CdiComponentProviderTest.java
new file mode 100644
index 0000000..12193c1
--- /dev/null
+++ b/tests/integration/cdi-integration/cdi-test-webapp/src/test/java/org/glassfish/jersey/tests/cdi/resources/CdiComponentProviderTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2022 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 org.glassfish.jersey.tests.cdi.resources;
+
+import org.glassfish.jersey.ext.cdi1x.internal.CdiComponentProvider;
+import org.glassfish.jersey.server.ResourceConfig;
+import org.glassfish.jersey.test.JerseyTest;
+import org.jboss.weld.environment.se.Weld;
+import org.junit.Test;
+
+import jakarta.enterprise.inject.Vetoed;
+import jakarta.enterprise.inject.spi.BeanManager;
+import jakarta.enterprise.inject.spi.CDI;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Application;
+import java.util.Collections;
+
+import static org.junit.Assert.assertFalse;
+
+public class CdiComponentProviderTest extends JerseyTest {
+    Weld weld;
+
+    @Override
+    public void setUp() throws Exception {
+        weld = new Weld();
+        weld.initialize();
+        super.setUp();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        weld.shutdown();
+        super.tearDown();
+    }
+
+    @Override
+    protected Application configure() {
+        return new ResourceConfig();
+    }
+
+    @Test
+    public void testVetoedClassIsNotBound() {
+        BeanManager beanManager = CDI.current().getBeanManager();
+        CdiComponentProvider provider = beanManager.getExtension(CdiComponentProvider.class);
+        assertFalse(provider.bind(VetoedResourceClass.class, Collections.singleton(Path.class)));
+    }
+
+    @Test
+    public void testInterfaceIsNotBound() {
+        BeanManager beanManager = CDI.current().getBeanManager();
+        CdiComponentProvider provider = beanManager.getExtension(CdiComponentProvider.class);
+        assertFalse(provider.bind(InterfaceResource.class, Collections.singleton(Path.class)));
+    }
+
+    @Path("/vetoed")
+    @Vetoed
+    public static class VetoedResourceClass {
+        @GET
+        public String get() {
+            return null;
+        }
+    }
+
+    @Path("/iface")
+    public static interface InterfaceResource {
+        @GET
+        public String get();
+    }
+}
diff --git a/tests/integration/ejb-multimodule-reload/war1/pom.xml b/tests/integration/ejb-multimodule-reload/war1/pom.xml
index 42df2a0..32ee160 100644
--- a/tests/integration/ejb-multimodule-reload/war1/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/war1/pom.xml
@@ -71,7 +71,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/ejb-multimodule-reload/war2/pom.xml b/tests/integration/ejb-multimodule-reload/war2/pom.xml
index 7343b4f..8c9dd4c 100644
--- a/tests/integration/ejb-multimodule-reload/war2/pom.xml
+++ b/tests/integration/ejb-multimodule-reload/war2/pom.xml
@@ -61,7 +61,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/ejb-multimodule/war/pom.xml b/tests/integration/ejb-multimodule/war/pom.xml
index 3820658..0e315af 100644
--- a/tests/integration/ejb-multimodule/war/pom.xml
+++ b/tests/integration/ejb-multimodule/war/pom.xml
@@ -61,7 +61,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/ejb-test-webapp/pom.xml b/tests/integration/ejb-test-webapp/pom.xml
index 42cd393..cb1ca1c 100644
--- a/tests/integration/ejb-test-webapp/pom.xml
+++ b/tests/integration/ejb-test-webapp/pom.xml
@@ -66,7 +66,7 @@
         </dependency>
         <dependency>
           <groupId>org.hamcrest</groupId>
-          <artifactId>hamcrest-library</artifactId>
+          <artifactId>hamcrest</artifactId>
           <scope>test</scope>
         </dependency>
    </dependencies>
diff --git a/tests/integration/j-59/war/pom.xml b/tests/integration/j-59/war/pom.xml
index 51914ce..0870851 100644
--- a/tests/integration/j-59/war/pom.xml
+++ b/tests/integration/j-59/war/pom.xml
@@ -62,7 +62,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/integration/jersey-2612/pom.xml b/tests/integration/jersey-2612/pom.xml
index 8e3ab36..294dc90 100644
--- a/tests/integration/jersey-2612/pom.xml
+++ b/tests/integration/jersey-2612/pom.xml
@@ -39,11 +39,6 @@
         </dependency>
 
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-
-        <dependency>
             <groupId>org.glassfish.jersey.test-framework.providers</groupId>
             <artifactId>jersey-test-framework-provider-external</artifactId>
             <scope>test</scope>
diff --git a/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/OptionalParamConverterProvider.java b/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/OptionalParamConverterProvider.java
index 2d8cc98..c1ec97b 100644
--- a/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/OptionalParamConverterProvider.java
+++ b/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/OptionalParamConverterProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
@@ -19,6 +19,7 @@
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Type;
 import java.util.List;
+import java.util.Optional;
 import java.util.Set;
 
 import jakarta.ws.rs.ext.ParamConverter;
@@ -32,9 +33,6 @@
 import org.glassfish.jersey.internal.util.ReflectionHelper;
 import org.glassfish.jersey.internal.util.collection.ClassTypePair;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
-
 @Singleton
 public class OptionalParamConverterProvider implements ParamConverterProvider {
 
@@ -53,7 +51,7 @@
             return new ParamConverter<T>() {
                 @Override
                 public T fromString(final String value) {
-                    return rawType.cast(Optional.fromNullable(value));
+                    return rawType.cast(Optional.ofNullable(value));
                 }
 
                 @Override
@@ -71,8 +69,7 @@
                 return new ParamConverter<T>() {
                     @Override
                     public T fromString(final String value) {
-                        return rawType.cast(Optional.fromNullable(value)
-                                                    .transform((Function<String, Object>) s -> converter.fromString(value)));
+                        return rawType.cast(Optional.ofNullable(value).map(o -> converter.fromString(value)));
                     }
 
                     @Override
diff --git a/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/Resource.java b/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/Resource.java
index 36f30f5..9e0d8f6 100644
--- a/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/Resource.java
+++ b/tests/integration/jersey-2612/src/main/java/org/glassfish/jersey/tests/integration/jersey2612/Resource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2022 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
@@ -21,8 +21,7 @@
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.QueryParam;
 
-import com.google.common.base.Function;
-import com.google.common.base.Optional;
+import java.util.Optional;
 
 /**
  * Test resource.
@@ -34,19 +33,15 @@
     @GET
     @Produces("text/plain")
     public String hello(@QueryParam("name") final Optional<String> name) {
-        return "Hello " + name.or("World") + "!";
+        return "Hello " + name.orElse("World") + "!";
     }
 
     @Path("square")
     @GET
     @Produces("text/plain")
     public int echo(@QueryParam("value") final Optional<Integer> value) {
-        return value.transform(new Function<Integer, Integer>() {
-            @Override
-            public Integer apply(final Integer integer) {
-                return integer * integer;
-            }
-        }).or(0);
+
+        return value.map(integer -> integer * integer).orElse(0);
     }
 
 }
diff --git a/tests/integration/jersey-4321/pom.xml b/tests/integration/jersey-4321/pom.xml
index cf27667..6cea96b 100644
--- a/tests/integration/jersey-4321/pom.xml
+++ b/tests/integration/jersey-4321/pom.xml
@@ -44,11 +44,6 @@
             <scope>test</scope>
         </dependency>
         <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-            <scope>test</scope>
-        </dependency>
-        <dependency>
             <groupId>org.glassfish.jersey.connectors</groupId>
             <artifactId>jersey-apache-connector</artifactId>
             <exclusions>
diff --git a/tests/integration/property-check/pom.xml b/tests/integration/property-check/pom.xml
index 42a882e..81c0dbb 100644
--- a/tests/integration/property-check/pom.xml
+++ b/tests/integration/property-check/pom.xml
@@ -94,6 +94,7 @@
             <groupId>com.google.guava</groupId>
             <artifactId>guava</artifactId>
             <scope>test</scope>
+            <version>${guava.version}</version>
         </dependency>
     </dependencies>
 
diff --git a/tests/integration/servlet-request-wrapper-binding-2/pom.xml b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
index e5440a0..52761de 100644
--- a/tests/integration/servlet-request-wrapper-binding-2/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
@@ -52,7 +52,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/servlet-request-wrapper-binding/pom.xml b/tests/integration/servlet-request-wrapper-binding/pom.xml
index 375227a..1d0a483 100644
--- a/tests/integration/servlet-request-wrapper-binding/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding/pom.xml
@@ -51,7 +51,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/integration/spring4/pom.xml b/tests/integration/spring4/pom.xml
deleted file mode 100644
index 66764b8..0000000
--- a/tests/integration/spring4/pom.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2012, 2022 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 xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-
-    <modelVersion>4.0.0</modelVersion>
-
-    <parent>
-        <groupId>org.glassfish.jersey.tests.integration</groupId>
-        <artifactId>project</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
-    </parent>
-
-    <artifactId>spring4</artifactId>
-
-    <packaging>war</packaging>
-    <name>jersey-tests-integration-spring4</name>
-
-    <description>
-        Jersey tests for Spring 4 integration
-    </description>
-
-    <dependencies>
-
-        <dependency>
-            <groupId>jakarta.servlet</groupId>
-            <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet4.version}</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>jakarta.ws.rs</groupId>
-            <artifactId>jakarta.ws.rs-api</artifactId>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.ext</groupId>
-            <artifactId>jersey-spring4</artifactId>
-            <version>${project.version}</version>
-            <scope>compile</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework</groupId>
-            <artifactId>jersey-test-framework-core</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.containers</groupId>
-            <artifactId>jersey-container-servlet</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.glassfish.jersey.test-framework.providers</groupId>
-            <artifactId>jersey-test-framework-provider-external</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>commons-logging</groupId>
-            <artifactId>commons-logging</artifactId>
-            <scope>runtime</scope>
-        </dependency>
-    </dependencies>
-
-    <build>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-compiler-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-failsafe-plugin</artifactId>
-            </plugin>
-            <plugin>
-                <groupId>org.eclipse.jetty</groupId>
-                <artifactId>jetty-maven-plugin</artifactId>
-                <configuration>
-                    <webApp>
-                        <contextPath>/</contextPath>
-                        <webInfIncludeJarPattern>.*$</webInfIncludeJarPattern>
-                    </webApp>
-                </configuration>
-            </plugin>
-        </plugins>
-    </build>
-
-    <profiles>
-        <profile>
-            <id>delayed-strategy-skip-test</id>
-            <activation>
-                <property>
-                    <name>org.glassfish.jersey.injection.manager.strategy</name>
-                    <value>delayed</value>
-                </property>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-failsafe-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>jakartification_exclude_tests</id> <!-- TODO remove after jakartification -->
-            <activation>
-                <jdk>[1.8,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-failsafe-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-        <profile>
-            <id>ignore.on.jdk16</id>
-            <!-- Spring 4 does not support JDK 16 at the moment, and it is superseded by Spring 5.2-5.3 -->
-            <activation>
-                <jdk>[16,)</jdk>
-            </activation>
-            <build>
-                <plugins>
-                    <plugin>
-                        <groupId>org.apache.maven.plugins</groupId>
-                        <artifactId>maven-failsafe-plugin</artifactId>
-                        <configuration>
-                            <skipTests>true</skipTests>
-                        </configuration>
-                    </plugin>
-                </plugins>
-            </build>
-        </profile>
-    </profiles>
-</project>
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java b/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
deleted file mode 100644
index da9f170..0000000
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.glassfish.jersey.server.spring.test;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import org.springframework.stereotype.Component;
-
-/**
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.TYPE)
-@Component
-public @interface Endpoint {
-
-}
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java b/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
deleted file mode 100644
index da45aea..0000000
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.glassfish.jersey.server.spring.test;
-
-/**
- * Type to be handled as HK2 request scoped bean.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class HK2ServiceRequestScoped {
-}
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java b/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
deleted file mode 100644
index a7b8fa8..0000000
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013, 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 org.glassfish.jersey.server.spring.test;
-
-/**
- * Type to be handled as HK2 singleton.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class HK2ServiceSingleton {
-}
diff --git a/tests/integration/spring5/README.txt b/tests/integration/spring5/README.txt
deleted file mode 100644
index 9a105f7..0000000
--- a/tests/integration/spring5/README.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-
-tests
-=====
-
-Tests are located in jersey-spring-test module.
-The module contains a test webapp and test code.
-The tests can be run in Jersey test container or an external container.
-
-- Running tests in Jersey test container
-    mvn clean test
-
-- Running tests in an external container
-  build the test app
-  deploy to an external container
-  configure container connection info in jersey-spring-test/pom.xml, if needed
-  run tests in integration test mode:
-    mvn -Pit verify
-
-- Running tests in embedded Jetty instance
-  build the test app
-  deploy to Jetty:
-    mvn -Pjetty jetty:run
-  run tests in integration test mode in another console session:
-    mvn -Pit verify
-
-test class naming conventions
-- *ITTest.java: run in unit and IT test mode
-- *Test.java: run as unit tests
-- *IT.java: run as IT tests
-
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
deleted file mode 100644
index bd10b50..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import java.math.BigDecimal;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.core.MediaType;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-
-/**
- * Jersey managed JAX-RS resource for testing jersey-spring.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-@Path("/jersey/account")
-public class AccountJerseyResource {
-
-    @Inject
-    @Named("AccountService-singleton")
-    private AccountService accountServiceInject;
-
-    @Autowired
-    @Qualifier("AccountService-singleton")
-    private AccountService accountServiceAutowired;
-
-    @Inject
-    @Named("AccountService-request-1")
-    private AccountService accountServiceRequest1;
-
-    @Autowired
-    @Qualifier("AccountService-request-1")
-    private AccountService accountServiceRequest2;
-
-    @Autowired
-    @Qualifier("AccountService-prototype-1")
-    private AccountService accountServicePrototype1;
-
-    @Autowired
-    @Qualifier("AccountService-prototype-1")
-    private AccountService accountServicePrototype2;
-
-    @Autowired
-    private HttpServletRequest httpServletRequest;
-
-    @Inject
-    private HK2ServiceSingleton hk2Singleton;
-
-    @Inject
-    private HK2ServiceRequestScoped hk2RequestScoped;
-
-    @Inject
-    private HK2ServicePerLookup hk2PerLookup;
-
-    private String message = "n/a";
-
-    // resource methods for testing resource class scope
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(final String message) {
-        this.message = message;
-        return message;
-    }
-
-    // JERSEY-2506 FIX VERIFICATION
-    @GET
-    @Path("server")
-    public String verifyServletRequestInjection() {
-        return "PASSED: " + httpServletRequest.getServerName();
-    }
-
-    @GET
-    @Path("singleton/server")
-    public String verifyServletRequestInjectionIntoSingleton() {
-        return accountServiceInject.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("singleton/autowired/server")
-    public String verifyServletRequestInjectionIntoAutowiredSingleton() {
-        return accountServiceAutowired.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("request/server")
-    public String verifyServletRequestInjectionIntoRequestScopedBean() {
-        return accountServiceRequest1.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("prototype/server")
-    public String verifyServletRequestInjectionIntoPrototypeScopedBean() {
-        return accountServicePrototype1.verifyServletRequestInjection();
-    }
-
-    // resource methods for testing singleton scoped beans
-    @GET
-    @Path("singleton/inject/{accountId}")
-    public BigDecimal getAccountBalanceSingletonInject(@PathParam("accountId") final String accountId) {
-        return accountServiceInject.getAccountBalance(accountId);
-    }
-
-    @GET
-    @Path("singleton/autowired/{accountId}")
-    public BigDecimal getAccountBalanceSingletonAutowired(@PathParam("accountId") final String accountId) {
-        return accountServiceAutowired.getAccountBalance(accountId);
-    }
-
-    @PUT
-    @Path("singleton/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public void setAccountBalanceSingleton(@PathParam("accountId") final String accountId, final String balance) {
-        accountServiceInject.setAccountBalance(accountId, new BigDecimal(balance));
-    }
-
-    // resource methods for testing request scoped beans
-    @PUT
-    @Path("request/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public BigDecimal setAccountBalanceRequest(@PathParam("accountId") final String accountId, final String balance) {
-        accountServiceRequest1.setAccountBalance(accountId, new BigDecimal(balance));
-        return accountServiceRequest2.getAccountBalance(accountId);
-    }
-
-    // resource methods for testing prototype scoped beans
-    @PUT
-    @Path("prototype/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public BigDecimal setAccountBalancePrototype(@PathParam("accountId") final String accountId, final String balance) {
-        accountServicePrototype1.setAccountBalance(accountId, new BigDecimal(balance));
-        return accountServicePrototype2.getAccountBalance(accountId);
-    }
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
deleted file mode 100644
index 70d90b0..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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 org.glassfish.jersey.server.spring.test;
-
-import java.math.BigDecimal;
-
-/**
- * Simple account service to testify injection into different scopes.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public interface AccountService {
-
-    void setAccountBalance(String accountId, BigDecimal balance);
-
-    BigDecimal getAccountBalance(String accountId);
-
-    String verifyServletRequestInjection();
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
deleted file mode 100644
index b7fb876..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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 org.glassfish.jersey.server.spring.test;
-
-import java.math.BigDecimal;
-import java.util.HashMap;
-import java.util.Map;
-
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.springframework.beans.factory.annotation.Autowired;
-
-/**
- * AccountService implementation.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class AccountServiceImpl implements AccountService {
-
-    private Map<String, BigDecimal> accounts = new HashMap<>();
-    private BigDecimal defaultAccountBalance;
-
-    // JERSEY-2506 FIX VERIFICATION
-    @Autowired
-    private HttpServletRequest httpServletRequest;
-
-    @Override
-    public void setAccountBalance(String accountId, BigDecimal balance) {
-        accounts.put(accountId, balance);
-    }
-
-    @Override
-    public BigDecimal getAccountBalance(String accountId) {
-        BigDecimal balance = accounts.get(accountId);
-        if (balance == null) {
-            return defaultAccountBalance;
-        }
-        return balance;
-    }
-
-    public void setDefaultAccountBalance(String defaultAccountBalance) {
-        this.defaultAccountBalance = new BigDecimal(defaultAccountBalance);
-    }
-
-    public String verifyServletRequestInjection() {
-        return "PASSED: " + httpServletRequest.getServerName();
-    }
-
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
deleted file mode 100644
index 0e5d2cf..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import java.math.BigDecimal;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.PathParam;
-import jakarta.ws.rs.core.MediaType;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Named;
-import jakarta.servlet.http.HttpServletRequest;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Qualifier;
-import org.springframework.stereotype.Component;
-
-/**
- * Spring managed JAX-RS resource for testing jersey-spring.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-@Path("/spring/account")
-@Component
-public class AccountSpringResource {
-
-    @Inject
-    @Named("AccountService-singleton")
-    private AccountService accountServiceInject;
-
-    @Autowired
-    @Qualifier("AccountService-singleton")
-    private AccountService accountServiceAutowired;
-
-    @Inject
-    @Named("AccountService-request-1")
-    private AccountService accountServiceRequest1;
-
-    @Autowired
-    @Qualifier("AccountService-request-1")
-    private AccountService accountServiceRequest2;
-
-    @Autowired
-    @Qualifier("AccountService-prototype-1")
-    private AccountService accountServicePrototype1;
-
-    @Autowired
-    @Qualifier("AccountService-prototype-1")
-    private AccountService accountServicePrototype2;
-
-    @Autowired
-    private HttpServletRequest httpServletRequest;
-
-    @Inject
-    private HK2ServiceSingleton hk2Singleton;
-
-    @Inject
-    private HK2ServiceRequestScoped hk2RequestScoped;
-
-    @Inject
-    private HK2ServicePerLookup hk2PerLookup;
-
-    private String message = "n/a";
-
-    // resource methods for testing resource class scope
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(String message) {
-        this.message = message;
-        return message;
-    }
-
-    // JERSEY-2506 FIX VERIFICATION
-    @GET
-    @Path("server")
-    public String verifyServletRequestInjection() {
-        return "PASSED: " + httpServletRequest.getServerName();
-    }
-
-    @GET
-    @Path("singleton/server")
-    public String verifyServletRequestInjectionIntoSingleton() {
-        return accountServiceInject.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("singleton/autowired/server")
-    public String verifyServletRequestInjectionIntoAutowiredSingleton() {
-        return accountServiceAutowired.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("request/server")
-    public String verifyServletRequestInjectionIntoRequestScopedBean() {
-        return accountServiceRequest1.verifyServletRequestInjection();
-    }
-
-    @GET
-    @Path("prototype/server")
-    public String verifyServletRequestInjectionIntoPrototypeScopedBean() {
-        return accountServicePrototype1.verifyServletRequestInjection();
-    }
-
-    // resource methods for testing singleton scoped beans
-    @GET
-    @Path("singleton/inject/{accountId}")
-    public BigDecimal getAccountBalanceSingletonInject(@PathParam("accountId") String accountId) {
-        return accountServiceInject.getAccountBalance(accountId);
-    }
-
-    @GET
-    @Path("singleton/autowired/{accountId}")
-    public BigDecimal getAccountBalanceSingletonAutowired(@PathParam("accountId") String accountId) {
-        return accountServiceAutowired.getAccountBalance(accountId);
-    }
-
-    @PUT
-    @Path("singleton/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public void setAccountBalanceSingleton(@PathParam("accountId") String accountId, String balance) {
-        accountServiceInject.setAccountBalance(accountId, new BigDecimal(balance));
-    }
-
-    // resource methods for testing request scoped beans
-    @PUT
-    @Path("request/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public BigDecimal setAccountBalanceRequest(@PathParam("accountId") String accountId, String balance) {
-        accountServiceRequest1.setAccountBalance(accountId, new BigDecimal(balance));
-        return accountServiceRequest2.getAccountBalance(accountId);
-    }
-
-    // resource methods for testing prototype scoped beans
-    @PUT
-    @Path("prototype/{accountId}")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public BigDecimal setAccountBalancePrototype(@PathParam("accountId") String accountId, String balance) {
-        accountServicePrototype1.setAccountBalance(accountId, new BigDecimal(balance));
-        return accountServicePrototype2.getAccountBalance(accountId);
-    }
-
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
deleted file mode 100644
index 39dd5aa..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.MediaType;
-
-import org.springframework.stereotype.Controller;
-
-/**
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-@Controller
-@Path("/spring/controller")
-public class ControllerResource {
-
-    private String message;
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(final String message) {
-        this.message = message;
-        return message;
-    }
-
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
deleted file mode 100644
index d61ef3b..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.MediaType;
-
-/**
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-@Endpoint
-@Path("/spring/endpoint")
-public class EndpointResource {
-
-    private String message;
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(final String message) {
-        this.message = message;
-        return message;
-    }
-
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
deleted file mode 100644
index 4b6bbf5..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (c) 2013, 2019 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 org.glassfish.jersey.server.spring.test;
-
-/**
- * Type to be handled as HK2 per-lookup bean.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class HK2ServicePerLookup {
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
deleted file mode 100644
index b0f82c7..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.core.Application;
-
-import jakarta.inject.Inject;
-import jakarta.inject.Singleton;
-
-import org.glassfish.jersey.internal.inject.AbstractBinder;
-import org.glassfish.jersey.internal.inject.Binder;
-import org.glassfish.jersey.internal.inject.InjectionManager;
-import org.glassfish.jersey.internal.inject.PerLookup;
-import org.glassfish.jersey.process.internal.RequestScoped;
-
-/**
- * JAX-RS application class for configuring injectable services in HK2 registry for testing purposes.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class MyApplication extends Application {
-
-    @Inject
-    public MyApplication(final InjectionManager injectionManager) {
-        Binder binder = new AbstractBinder() {
-            @Override
-            protected void configure() {
-                bindAsContract(HK2ServiceSingleton.class).in(Singleton.class);
-                bindAsContract(HK2ServiceRequestScoped.class).in(RequestScoped.class);
-                bindAsContract(HK2ServicePerLookup.class).in(PerLookup.class);
-            }
-        };
-
-        injectionManager.register(binder);
-    }
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
deleted file mode 100644
index b815fe0..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.MediaType;
-
-import org.springframework.stereotype.Repository;
-
-/**
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-@Repository
-@Path("/spring/repository")
-public class RepositoryResource {
-
-    private String message;
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(final String message) {
-        this.message = message;
-        return message;
-    }
-
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-}
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java b/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
deleted file mode 100644
index d50e5a6..0000000
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.Consumes;
-import jakarta.ws.rs.GET;
-import jakarta.ws.rs.PUT;
-import jakarta.ws.rs.Path;
-import jakarta.ws.rs.core.MediaType;
-
-import org.springframework.stereotype.Service;
-
-/**
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-@Service
-@Path("/spring/service")
-public class ServiceResource {
-
-    private String message;
-
-    @PUT
-    @Path("message")
-    @Consumes(MediaType.TEXT_PLAIN)
-    public String setMessage(final String message) {
-        this.message = message;
-        return message;
-    }
-
-    @GET
-    @Path("message")
-    public String getMessage() {
-        return message;
-    }
-}
diff --git a/tests/integration/spring5/src/main/resources/applicationContext.xml b/tests/integration/spring5/src/main/resources/applicationContext.xml
deleted file mode 100644
index c7e421e..0000000
--- a/tests/integration/spring5/src/main/resources/applicationContext.xml
+++ /dev/null
@@ -1,69 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2012, 2019 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
-
--->
-
-<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans
-        http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop
-        http://www.springframework.org/schema/aop/spring-aop.xsd">
-
-    <!--<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>-->
-    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
-        <property name="autowiredAnnotationTypes">
-            <set>
-                <value>org.springframework.beans.factory.annotation.Autowired</value>
-                <value>org.springframework.beans.factory.annotation.Value</value>
-            </set>
-        </property>
-    </bean>
-
-    <!-- Needed since Spring Context 4, was default in Spring Context 3 -->
-    <bean id="customAutowireConfigurer" class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
-        <property name="customQualifierTypes">
-            <set>
-                <value>org.springframework.beans.factory.annotation.Qualifier</value>
-            </set>
-        </property>
-    </bean>
-
-    <bean name="AccountService-singleton" class="org.glassfish.jersey.server.spring.test.AccountServiceImpl" />
-
-    <bean name="AccountService-request-1" class="org.glassfish.jersey.server.spring.test.AccountServiceImpl" scope="request">
-        <aop:scoped-proxy/>
-    </bean>
-
-    <bean name="AccountService-request-2" class="org.glassfish.jersey.server.spring.test.AccountServiceImpl" scope="request"/>
-
-    <bean name="AccountService-prototype-1" class="org.glassfish.jersey.server.spring.test.AccountServiceImpl" scope="prototype">
-        <property name="defaultAccountBalance" value="987.65"/>
-    </bean>
-
-    <bean name="AccountService-prototype-2" class="org.glassfish.jersey.server.spring.test.AccountServiceImpl" scope="prototype"/>
-
-    <!-- Spring managed JAX-RS resources -->
-    <bean class="org.glassfish.jersey.server.spring.test.AccountSpringResource"/>
-
-    <bean class="org.glassfish.jersey.server.spring.test.ServiceResource"/>
-
-    <bean class="org.glassfish.jersey.server.spring.test.ControllerResource"/>
-
-    <bean class="org.glassfish.jersey.server.spring.test.RepositoryResource"/>
-
-    <bean class="org.glassfish.jersey.server.spring.test.EndpointResource"/>
-
-</beans>
diff --git a/tests/integration/spring5/src/main/webapp/WEB-INF/web.xml b/tests/integration/spring5/src/main/webapp/WEB-INF/web.xml
deleted file mode 100644
index 4004dd3..0000000
--- a/tests/integration/spring5/src/main/webapp/WEB-INF/web.xml
+++ /dev/null
@@ -1,50 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-    Copyright (c) 2013, 2019 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="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
-  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
-
-  <module-name>jersey-spring-test</module-name>
-
-    <!-- use this to explicitly configure Spring -->
-    <!--
-    <listener>
-        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
-    </listener>
-    <listener>
-        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
-    </listener>
-    <context-param>
-        <param-name>contextConfigLocation</param-name>
-        <param-value>classpath:/applicationContext.xml</param-value>
-    </context-param>
-    -->
-
-    <servlet>
-        <servlet-name>org.glassfish.jersey.server.spring.test.MyApplication</servlet-name>
-    </servlet>
-    <servlet-mapping>
-        <servlet-name>org.glassfish.jersey.server.spring.test.MyApplication</servlet-name>
-        <url-pattern>/*</url-pattern>
-    </servlet-mapping>
-
-
-</web-app>
-
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
deleted file mode 100644
index 77f2984..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
-import org.glassfish.jersey.test.spi.TestContainerException;
-import org.glassfish.jersey.test.spi.TestContainerFactory;
-import org.glassfish.jersey.test.JerseyTest;
-
-import org.junit.Test;
-
-import static org.junit.Assert.assertEquals;
-
-public class AccountResourceITCase extends JerseyTest {
-
-    @Override
-    protected Application configure() {
-        return new Application();
-    }
-
-    @Override
-    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
-        return new ExternalTestContainerFactory();
-    }
-
-    @Test
-    public void testGet() throws Exception {
-        final String r = target().path("/jersey/account/message").request().get(String.class);
-        assertEquals(r, "n/a");
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
deleted file mode 100644
index 5cc9fc7..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import java.math.BigDecimal;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-import jakarta.ws.rs.core.MediaType;
-
-import org.junit.Test;
-import static org.hamcrest.CoreMatchers.startsWith;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertThat;
-
-/**
- * Base class for JAX-RS resource tests.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public abstract class AccountResourceTestBase extends ResourceTestBase {
-
-    // test singleton scoped Spring bean injection using @Inject + @Autowired
-    @Test
-    public void testSingletonScopedSpringService() {
-        final BigDecimal newBalance = new BigDecimal(Math.random());
-        final WebTarget t = target(getResourceFullPath());
-
-        t.path("/singleton/xyz123").request().put(Entity.entity(newBalance.toString(), MediaType.TEXT_PLAIN_TYPE));
-        final BigDecimal balance = t.path("/singleton/autowired/xyz123").request().get(BigDecimal.class);
-        assertEquals(newBalance, balance);
-    }
-
-    @Test
-    public void testRequestScopedSpringService() {
-        final BigDecimal newBalance = new BigDecimal(Math.random());
-        final WebTarget t = target(getResourceFullPath());
-        final BigDecimal balance = t.path("request/abc456").request().put(Entity.text(newBalance), BigDecimal.class);
-        assertEquals(newBalance, balance);
-    }
-
-    @Test
-    public void testPrototypeScopedSpringService() {
-        final BigDecimal newBalance = new BigDecimal(Math.random());
-        final WebTarget t = target(getResourceFullPath());
-        final BigDecimal balance = t.path("prototype/abc456").request().put(Entity.text(newBalance), BigDecimal.class);
-        assertEquals(new BigDecimal("987.65"), balance);
-    }
-
-    @Test
-    public void testServletInjection() {
-        final WebTarget t = target(getResourceFullPath());
-
-        String server = t.path("server").request().get(String.class);
-        assertThat(server, startsWith("PASSED: "));
-
-        server = t.path("singleton/server").request().get(String.class);
-        assertThat(server, startsWith("PASSED: "));
-
-        server = t.path("singleton/autowired/server").request().get(String.class);
-        assertThat(server, startsWith("PASSED: "));
-
-        server = t.path("request/server").request().get(String.class);
-        assertThat(server, startsWith("PASSED: "));
-
-        server = t.path("prototype/server").request().get(String.class);
-        assertThat(server, startsWith("PASSED: "));
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
deleted file mode 100644
index fa3d1a2..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Jersey managed JAX-RS resources.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class JerseyManagedITCase extends AccountResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(AccountJerseyResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/jersey/account";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals("n/a", msg);
-    }
-
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
deleted file mode 100644
index 08c4902..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.core.Application;
-
-import org.glassfish.jersey.server.ResourceConfig;
-import org.glassfish.jersey.server.spring.SpringLifecycleListener;
-import org.glassfish.jersey.server.spring.scope.RequestContextFilter;
-import org.glassfish.jersey.test.JerseyTest;
-import org.glassfish.jersey.test.TestProperties;
-import org.glassfish.jersey.test.external.ExternalTestContainerFactory;
-import org.glassfish.jersey.test.spi.TestContainerException;
-import org.glassfish.jersey.test.spi.TestContainerFactory;
-
-/**
- * Base class for JAX-RS resource tests.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public abstract class ResourceTestBase extends JerseyTest {
-
-    private static final String TEST_WEBAPP_CONTEXT_PATH = "jersey.spring.test.contextPath";
-    private static final String TEST_CONTAINER_FACTORY_EXTERNAL = "org.glassfish.jersey.test.external"
-            + ".ExternalTestContainerFactory";
-
-    @Override
-    protected TestContainerFactory getTestContainerFactory() throws TestContainerException {
-        return new ExternalTestContainerFactory();
-    }
-
-    @Override
-    protected Application configure() {
-        final ResourceConfig rc = new ResourceConfig()
-                .register(SpringLifecycleListener.class)
-                .register(RequestContextFilter.class);
-        TestUtil.registerHK2Services(rc);
-        rc.property("contextConfigLocation", "classpath:applicationContext.xml");
-        return configure(rc);
-    }
-
-    protected abstract ResourceConfig configure(ResourceConfig rc);
-
-    protected abstract String getResourcePath();
-
-    protected String getResourceFullPath() {
-        final String containerFactory = System.getProperty(TestProperties.CONTAINER_FACTORY);
-        if (TEST_CONTAINER_FACTORY_EXTERNAL.equals(containerFactory)) {
-            return System.getProperty(TEST_WEBAPP_CONTEXT_PATH) + getResourcePath();
-        }
-        return getResourcePath();
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
deleted file mode 100644
index 9b24994..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Spring managed JAX-RS resources with @Controller archetype.
- *
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-public class SpringManagedControllerITCase extends ResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(ControllerResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/spring/controller";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals(message, msg);
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
deleted file mode 100644
index 79ade92..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Spring managed JAX-RS resources with custom composite
- * annotation that derives from @Component.
- *
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-public class SpringManagedEndpointITCase extends ResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(EndpointResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/spring/endpoint";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals(message, msg);
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
deleted file mode 100644
index 2b351f0..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Spring managed JAX-RS resources.
- *
- * @author Marko Asplund (marko.asplund at yahoo.com)
- */
-public class SpringManagedITCase extends AccountResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(AccountSpringResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/spring/account";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals(message, msg);
-    }
-
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
deleted file mode 100644
index 0bfcd04..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Spring managed JAX-RS resources with @Repository archetype.
- *
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-public class SpringManagedRepositoryITCase extends ResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(RepositoryResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/spring/repository";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals(message, msg);
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
deleted file mode 100644
index fd31b99..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.ws.rs.client.Entity;
-import jakarta.ws.rs.client.WebTarget;
-
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.junit.Test;
-import static org.junit.Assert.assertEquals;
-
-/**
- * Tests for Spring managed JAX-RS resources with @Service archetype.
- *
- * @author Konrad Garus (konrad.garus at gmail.com)
- */
-public class SpringManagedServiceITCase extends ResourceTestBase {
-
-    @Override
-    protected ResourceConfig configure(final ResourceConfig rc) {
-        return rc.register(ServiceResource.class);
-    }
-
-    @Override
-    protected String getResourcePath() {
-        return "/spring/service";
-    }
-
-    @Test
-    public void testResourceScope() {
-        final WebTarget t = target(getResourceFullPath());
-        final String message = "hello, world";
-        final String echo = t.path("message").request().put(Entity.text(message), String.class);
-        assertEquals(message, echo);
-        final String msg = t.path("message").request().get(String.class);
-        assertEquals(message, msg);
-    }
-}
diff --git a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java b/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
deleted file mode 100644
index 8c837c8..0000000
--- a/tests/integration/spring5/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * 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 org.glassfish.jersey.server.spring.test;
-
-import jakarta.inject.Singleton;
-
-import org.glassfish.jersey.internal.inject.PerLookup;
-import org.glassfish.jersey.process.internal.RequestScoped;
-import org.glassfish.jersey.server.ResourceConfig;
-
-import org.glassfish.hk2.utilities.BuilderHelper;
-import org.glassfish.hk2.utilities.binding.AbstractBinder;
-
-class TestUtil {
-
-    public static ResourceConfig registerHK2Services(final ResourceConfig rc) {
-        rc
-                .register(new AbstractBinder() {
-                    @Override
-                    protected void configure() {
-                        bind(BuilderHelper.link(HK2ServiceSingleton.class).in(Singleton.class).build());
-                    }
-                })
-                .register(new AbstractBinder() {
-                    @Override
-                    protected void configure() {
-                        bind(BuilderHelper.link(HK2ServiceRequestScoped.class).in(RequestScoped.class).build());
-                    }
-                })
-                .register(new AbstractBinder() {
-                    @Override
-                    protected void configure() {
-                        bind(BuilderHelper.link(HK2ServicePerLookup.class).in(PerLookup.class).build());
-                    }
-                });
-        return rc;
-    }
-}
diff --git a/tests/integration/spring4/README.txt b/tests/integration/spring6/README.txt
similarity index 100%
rename from tests/integration/spring4/README.txt
rename to tests/integration/spring6/README.txt
diff --git a/tests/integration/spring5/pom.xml b/tests/integration/spring6/pom.xml
similarity index 73%
rename from tests/integration/spring5/pom.xml
rename to tests/integration/spring6/pom.xml
index 7a07120..e7df36c 100644
--- a/tests/integration/spring5/pom.xml
+++ b/tests/integration/spring6/pom.xml
@@ -25,24 +25,32 @@
     <parent>
         <groupId>org.glassfish.jersey.tests.integration</groupId>
         <artifactId>project</artifactId>
-        <version>3.0.0-SNAPSHOT</version>
+        <version>3.1.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>spring5</artifactId>
+    <artifactId>spring6</artifactId>
 
     <packaging>war</packaging>
-    <name>jersey-tests-integration-spring5</name>
+    <name>jersey-tests-integration-spring6</name>
 
     <description>
-        Jersey tests for Spring 5 integration
+        Jersey tests for Spring 6 integration
     </description>
 
+    <repositories>
+        <repository>
+            <name>Spring Repository</name>
+            <id>spring-repository</id>
+            <url>https://repo.spring.io/milestone</url>
+        </repository>
+    </repositories>
+
     <dependencies>
 
         <dependency>
             <groupId>jakarta.servlet</groupId>
             <artifactId>jakarta.servlet-api</artifactId>
-            <version>${servlet4.version}</version>
+            <version>${servlet5.version}</version>
             <scope>provided</scope>
         </dependency>
 
@@ -54,12 +62,42 @@
 
         <dependency>
             <groupId>org.glassfish.jersey.ext</groupId>
-            <artifactId>jersey-spring5</artifactId>
+            <artifactId>jersey-spring6</artifactId>
             <version>${project.version}</version>
             <scope>compile</scope>
         </dependency>
 
         <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-beans</artifactId>
+            <version>${spring6.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+            <version>${spring6.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+            <version>${spring6.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-web</artifactId>
+            <version>${spring6.version}</version>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+            <version>${spring6.version}</version>
+        </dependency>
+
+        <dependency>
             <groupId>org.glassfish.jersey.test-framework</groupId>
             <artifactId>jersey-test-framework-core</artifactId>
             <scope>test</scope>
@@ -93,16 +131,11 @@
             <plugin>
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-failsafe-plugin</artifactId>
-                <!-- TODO remove after jakartification -->
-                <configuration>
-                    <excludes> <!--JDK 11 -->
-                        <exclude>**/**/*.java</exclude>
-                    </excludes>
-                </configuration>
             </plugin>
             <plugin>
                 <groupId>org.eclipse.jetty</groupId>
                 <artifactId>jetty-maven-plugin</artifactId>
+                <version>11.0.7</version>
                 <configuration>
                     <webApp>
                         <contextPath>/</contextPath>
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
similarity index 98%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
index bd10b50..ab54e71 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountJerseyResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
similarity index 94%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
index 851e215..2a764dc 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
similarity index 96%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
index e79d9bd..58919af 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountServiceImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
similarity index 98%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
index 0e5d2cf..e6e8e43 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/AccountSpringResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
similarity index 95%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
index 39dd5aa..8cf0a7e 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ControllerResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
similarity index 94%
rename from tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
index 80f5d8c..53a9ef1 100644
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/Endpoint.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
similarity index 95%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
index d61ef3b..a1d8682 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/EndpointResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
similarity index 92%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
index ff689c6..0fb4f76 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServicePerLookup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
similarity index 92%
rename from tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
index 3bde89d..f55662a 100644
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceRequestScoped.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
similarity index 92%
rename from tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
index 424f186..64ea0ba 100644
--- a/tests/integration/spring5/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/HK2ServiceSingleton.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2019 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
similarity index 96%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
index b0f82c7..e0f0c99 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/MyApplication.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
similarity index 95%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
index b815fe0..52a8b64 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/RepositoryResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
similarity index 95%
rename from tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
rename to tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
index d50e5a6..75cf5af 100644
--- a/tests/integration/spring4/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
+++ b/tests/integration/spring6/src/main/java/org/glassfish/jersey/server/spring/test/ServiceResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/main/resources/applicationContext.xml b/tests/integration/spring6/src/main/resources/applicationContext.xml
similarity index 97%
rename from tests/integration/spring4/src/main/resources/applicationContext.xml
rename to tests/integration/spring6/src/main/resources/applicationContext.xml
index c7e421e..c36223c 100644
--- a/tests/integration/spring4/src/main/resources/applicationContext.xml
+++ b/tests/integration/spring6/src/main/resources/applicationContext.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2012, 2019 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2012, 2022 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
diff --git a/tests/integration/spring4/src/main/webapp/WEB-INF/web.xml b/tests/integration/spring6/src/main/webapp/WEB-INF/web.xml
similarity index 96%
rename from tests/integration/spring4/src/main/webapp/WEB-INF/web.xml
rename to tests/integration/spring6/src/main/webapp/WEB-INF/web.xml
index c3cff9d..1710d82 100644
--- a/tests/integration/spring4/src/main/webapp/WEB-INF/web.xml
+++ b/tests/integration/spring6/src/main/webapp/WEB-INF/web.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <!--
 
-    Copyright (c) 2013, 2018 Oracle and/or its affiliates. All rights reserved.
+    Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
similarity index 95%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
index 77f2984..a17f3ee 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
similarity index 97%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
index 5cc9fc7..301e155 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/AccountResourceTestBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
index fa3d1a2..241f450 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/JerseyManagedITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
similarity index 97%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
index 08c4902..bab4d70 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/ResourceTestBase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
index 9b24994..f2847ff 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedControllerITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
index 79ade92..5a316ec 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedEndpointITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
index 2b351f0..8046675 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
index 0bfcd04..0fa4a22 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedRepositoryITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
index fd31b99..36a602c 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/SpringManagedServiceITCase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
similarity index 96%
rename from tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
rename to tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
index 8c837c8..1961242 100644
--- a/tests/integration/spring4/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
+++ b/tests/integration/spring6/src/test/java/org/glassfish/jersey/server/spring/test/TestUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2022 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
diff --git a/tests/integration/thin-server/pom.xml b/tests/integration/thin-server/pom.xml
index 4a26ef0..8f9f511 100644
--- a/tests/integration/thin-server/pom.xml
+++ b/tests/integration/thin-server/pom.xml
@@ -58,7 +58,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tests/jmockit/pom.xml b/tests/jmockit/pom.xml
index 593dc8c..74de785 100644
--- a/tests/jmockit/pom.xml
+++ b/tests/jmockit/pom.xml
@@ -63,7 +63,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
diff --git a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
index 26d63be..294bd3c 100644
--- a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
+++ b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/pom.xml
@@ -101,11 +101,6 @@
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-
     </dependencies>
 
     <profiles>
diff --git a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/DaemonThreadMemoryLeakingResource.java b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/DaemonThreadMemoryLeakingResource.java
index a23663d..9bca4af 100644
--- a/tests/mem-leaks/redeployment/redeployment-leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/DaemonThreadMemoryLeakingResource.java
+++ b/tests/mem-leaks/redeployment/redeployment-leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/DaemonThreadMemoryLeakingResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -16,6 +16,8 @@
 
 package org.glassfish.jersey.tests.memleaks.testleak;
 
+import org.glassfish.jersey.internal.guava.ThreadFactoryBuilder;
+
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 
@@ -28,7 +30,6 @@
 
 import jakarta.inject.Singleton;
 
-import com.google.common.util.concurrent.ThreadFactoryBuilder;
 
 /**
  * Resource that causes {@link OutOfMemoryError} exception upon repetitive call of {@link #invoke(int)} of an application that is
diff --git a/tests/mem-leaks/test-cases/leaking-test-app/pom.xml b/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
index 22f7e73..3be0eba 100644
--- a/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
+++ b/tests/mem-leaks/test-cases/leaking-test-app/pom.xml
@@ -67,11 +67,6 @@
             <scope>test</scope>
         </dependency>
 
-        <dependency>
-            <groupId>com.google.guava</groupId>
-            <artifactId>guava</artifactId>
-        </dependency>
-
     </dependencies>
 
     <profiles>
diff --git a/tests/mem-leaks/test-cases/leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/MemoryLeakingResource.java b/tests/mem-leaks/test-cases/leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/MemoryLeakingResource.java
index fd2381a..5693089 100644
--- a/tests/mem-leaks/test-cases/leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/MemoryLeakingResource.java
+++ b/tests/mem-leaks/test-cases/leaking-test-app/src/main/java/org/glassfish/jersey/tests/memleaks/testleak/MemoryLeakingResource.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2022 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
@@ -25,9 +25,6 @@
 import jakarta.ws.rs.Path;
 import jakarta.ws.rs.Produces;
 import jakarta.ws.rs.QueryParam;
-import jakarta.ws.rs.client.Client;
-import jakarta.ws.rs.client.ClientBuilder;
-import jakarta.ws.rs.client.WebTarget;
 
 import jakarta.inject.Singleton;
 
diff --git a/tests/stress/pom.xml b/tests/stress/pom.xml
index b8b6460..95a9b88 100644
--- a/tests/stress/pom.xml
+++ b/tests/stress/pom.xml
@@ -81,7 +81,7 @@
 
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
     </dependencies>
diff --git a/tools/jersey-release-notes-maven-plugin/pom.xml b/tools/jersey-release-notes-maven-plugin/pom.xml
index 6b7cc0f..a9c74ec 100644
--- a/tools/jersey-release-notes-maven-plugin/pom.xml
+++ b/tools/jersey-release-notes-maven-plugin/pom.xml
@@ -74,7 +74,7 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <version>2.6</version>
+            <version>2.11.0</version>
         </dependency>
         <dependency>
             <groupId>org.apache.maven</groupId>