update the 3.x branch with actual master

diff --git a/bom/pom.xml b/bom/pom.xml
index 345928f..e64e12f 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>
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/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/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ClientProperties.java b/connectors/apache5-connector/src/main/java/org/glassfish/jersey/apache5/connector/Apache5ClientProperties.java
index eac5be5..df4c8e0 100644
--- 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
@@ -90,8 +90,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.hc.client5.http.io.HttpClientConnectionManager#close()} gets
@@ -124,7 +124,7 @@
     public static final String REQUEST_CONFIG = "jersey.config.apache5.client.requestConfig";
 
     /**
-     * HttpRequestRetryHandler which will be used to create {@link org.apache.hc.client5.http.classic.HttpClient}.
+     * 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/>
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
index fdebf7f..5cc2e63 100644
--- 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
@@ -107,18 +107,21 @@
  * <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#REQUEST_CONFIG}</li>
- * <li>{@link Apache5ClientProperties#CREDENTIALS_PROVIDER}</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#PREEMPTIVE_BASIC_AUTHENTICATION}</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
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
index 9ef300b..a5a5ffd 100644
--- 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
@@ -32,19 +32,22 @@
  * <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#REQUEST_CONFIG}</li>
- * <li>{@link Apache5ClientProperties#CREDENTIALS_PROVIDER}</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#PREEMPTIVE_BASIC_AUTHENTICATION}</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>
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/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/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
index ef1585c..655a203 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnector.java
+++ b/connectors/jetty-connector/src/main/java11/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/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
index 44146c8..dfd3b79 100644
--- a/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.java
+++ b/connectors/jetty-connector/src/main/java11/org/glassfish/jersey/jetty/connector/JettyConnectorProvider.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
@@ -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/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 e722332..188cda3 100644
--- a/connectors/pom.xml
+++ b/connectors/pom.xml
@@ -67,7 +67,7 @@
         </dependency>
         <dependency>
             <groupId>org.hamcrest</groupId>
-            <artifactId>hamcrest-library</artifactId>
+            <artifactId>hamcrest</artifactId>
             <scope>test</scope>
         </dependency>
         <dependency>
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 0db4e76..5b51a2f 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
@@ -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
@@ -233,6 +233,7 @@
             }
         } finally {
             requestTimeoutHandler.close();
+            responseContext.completeExceptionally(error);
             rethrow(error);
         }
     }
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 3e1bbfd..8b5bf6d 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 e9c10c5..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
@@ -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:
@@ -50,6 +54,7 @@
  * <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:
@@ -59,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>
@@ -67,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
@@ -94,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.
@@ -121,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";
     /**
@@ -143,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";
     /**
@@ -165,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;
 
@@ -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 a9c7090..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
@@ -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);
-            }
+            };
         }
     }
 
@@ -312,4 +332,24 @@
         }
     }
 
+    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-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/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 4311fee..3e0ab6c 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
@@ -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
@@ -71,6 +71,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/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 a59ca08..800c3f9 100644
--- a/docs/src/main/docbook/jersey.ent
+++ b/docs/src/main/docbook/jersey.ent
@@ -298,6 +298,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>">
@@ -411,36 +440,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>">
@@ -478,9 +533,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>">
@@ -912,21 +969,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_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/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/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/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 82aeec6..5305302 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1977,7 +1977,7 @@
 
             <dependency>
                 <groupId>org.hamcrest</groupId>
-                <artifactId>hamcrest-library</artifactId>
+                <artifactId>hamcrest</artifactId>
                 <version>${hamcrest.version}</version>
                 <scope>test</scope>
             </dependency>
@@ -2117,7 +2117,8 @@
 
         <grizzly2.version>2.4.4</grizzly2.version>
         <guava.version>31.1-jre</guava.version>
-        <hamcrest.version>1.3</hamcrest.version>
+        <hamcrest.version>2.2</hamcrest.version>
+        <!--<helidon.version>1.0.3</helidon.version>-->
         <xmlunit.version>1.6</xmlunit.version>
         <hk2.osgi.version>org.glassfish.hk2.*;version="[2.5,4)"</hk2.osgi.version>
         <hk2.jvnet.osgi.version>org.jvnet.hk2.*;version="[2.5,4)"</hk2.jvnet.osgi.version>
@@ -2154,7 +2155,8 @@
         <skip.e2e>false</skip.e2e>
         <slf4j.version>1.7.21</slf4j.version>
         <spring6.version>6.0.0-M3</spring6.version>
-        <surefire.version>3.0.0-M3</surefire.version>
+        <surefire.version>3.0.0-M6</surefire.version>
+        <validation.impl.version>6.2.0.Final</validation.impl.version>
 
         <!-- Jakartified, eligible for CQ -->
         <weld.version>4.0.2.Final</weld.version>
diff --git a/tests/e2e-client/pom.xml b/tests/e2e-client/pom.xml
index 9f21ec4..3890a59 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>
@@ -169,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 67945ac..28d2747 100644
--- a/tests/e2e-entity/pom.xml
+++ b/tests/e2e-entity/pom.xml
@@ -167,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/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-server/pom.xml b/tests/e2e-server/pom.xml
index 8c320ea..aca4fa5 100644
--- a/tests/e2e-server/pom.xml
+++ b/tests/e2e-server/pom.xml
@@ -176,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 eadfa10..567044b 100644
--- a/tests/e2e/pom.xml
+++ b/tests/e2e/pom.xml
@@ -178,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 b24e745..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
@@ -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();
+        }
     }
 
     /**
@@ -299,6 +318,219 @@
             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);
+        }
     }
 
     /**
@@ -503,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/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 3e155e6..e5a76ea 100644
--- a/tests/integration/cdi-integration/cdi-multimodule/war1/pom.xml
+++ b/tests/integration/cdi-integration/cdi-multimodule/war1/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/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/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 756b2e8..5597e20 100644
--- a/tests/integration/ejb-test-webapp/pom.xml
+++ b/tests/integration/ejb-test-webapp/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/tests/integration/j-59/war/pom.xml b/tests/integration/j-59/war/pom.xml
index 8dfc6fc..9b77f25 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>
     </dependencies>
diff --git a/tests/integration/servlet-request-wrapper-binding-2/pom.xml b/tests/integration/servlet-request-wrapper-binding-2/pom.xml
index b1d32de..3437dbd 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 e47b273..2ff1a47 100644
--- a/tests/integration/servlet-request-wrapper-binding/pom.xml
+++ b/tests/integration/servlet-request-wrapper-binding/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/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/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>