You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2021/04/27 11:13:03 UTC

[httpcomponents-client] 01/04: Java 1.8 upgrade

This is an automated email from the ASF dual-hosted git repository.

olegk pushed a commit to branch 5.2.x
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git

commit 3bb88a74d2f2336dcf47df37e46dc64da19a55e0
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Dec 20 15:22:42 2020 +0100

    Java 1.8 upgrade
---
 .../hc/client5/http/cache/HttpCacheEntry.java      |   2 +-
 .../AbstractSerializingAsyncCacheStorage.java      |   2 +-
 .../client5/http/impl/cache/AsyncCachingExec.java  | 154 +++------
 .../http/impl/cache/BasicHttpAsyncCache.java       |  19 +-
 .../hc/client5/http/impl/cache/BasicHttpCache.java |  19 +-
 .../client5/http/impl/cache/BasicIdGenerator.java  |   2 +-
 .../hc/client5/http/impl/cache/CachingExec.java    |  20 +-
 .../impl/cache/CachingH2AsyncClientBuilder.java    |  20 +-
 .../impl/cache/CachingHttpAsyncClientBuilder.java  |  20 +-
 .../http/impl/cache/CachingHttpClientBuilder.java  |  20 +-
 .../impl/cache/DefaultAsyncCacheInvalidator.java   |   2 +-
 .../impl/cache/DefaultAsyncCacheRevalidator.java   |  99 +++---
 .../http/impl/cache/DefaultCacheRevalidator.java   |  41 +--
 .../hc/client5/http/impl/cache/WarningValue.java   |   4 +-
 .../memcached/MemcachedHttpAsyncCacheStorage.java  |  62 ++--
 .../hc/client5/http/cache/TestHttpCacheEntry.java  |   2 +-
 .../http/impl/cache/AbstractProtocolTest.java      |   2 +-
 .../TestAbstractSerializingAsyncCacheStorage.java  | 336 ++++++-------------
 .../cache/TestAbstractSerializingCacheStorage.java |  95 ++----
 .../cache/TestCachedHttpResponseGenerator.java     |   2 +-
 .../client5/http/impl/cache/TestCachingExec.java   |   2 +-
 .../impl/cache/TestConditionalRequestBuilder.java  |  10 +-
 .../cache/TestDefaultAsyncCacheInvalidator.java    |  37 +-
 .../impl/cache/TestDefaultCacheInvalidator.java    |  22 +-
 .../memcached/TestPrefixKeyHashingScheme.java      |   9 +-
 .../org/apache/hc/client5/http/fluent/Request.java |   2 +-
 .../examples/fluent/FluentResponseHandling.java    |  58 ++--
 .../AbstractHttpAsyncClientAuthentication.java     | 182 ++--------
 .../async/AbstractHttpAsyncFundamentalsTest.java   |  19 +-
 .../async/AbstractHttpAsyncRedirectsTest.java      | 372 ++++++---------------
 .../AbstractHttpReactiveFundamentalsTest.java      |  19 +-
 .../testing/async/AbstractServerTestBase.java      |  32 +-
 .../testing/async/TestHttp1AsyncRedirects.java     |  47 +--
 .../TestHttp1AsyncStatefulConnManagement.java      |  63 +---
 .../async/TestHttp1ClientAuthentication.java       |  25 +-
 .../hc/client5/testing/fluent/TestFluent.java      |  63 +---
 .../testing/sync/TestClientAuthentication.java     |  74 +---
 .../testing/sync/TestClientRequestExecution.java   |  13 +-
 .../testing/sync/TestCookieVirtualHost.java        |  87 ++---
 .../testing/sync/TestMalformedServerResponse.java  |  29 +-
 .../hc/client5/testing/sync/TestRedirects.java     | 328 +++++-------------
 .../client5/testing/sync/TestSSLSocketFactory.java |  40 +--
 .../testing/sync/TestStatefulConnManagement.java   |  21 +-
 .../testing/sync/TestWindowsNegotiateScheme.java   |  31 +-
 .../apache/hc/client5/http/entity/mime/Header.java |   6 +-
 .../client5/http/impl/IdleConnectionEvictor.java   |  25 +-
 .../apache/hc/client5/http/impl/Operations.java    |  18 +-
 .../impl/async/AbstractHttpAsyncClientBase.java    |   8 +-
 .../http/impl/async/AsyncExecChainElement.java     |  14 +-
 .../http/impl/async/H2AsyncClientBuilder.java      |  76 +----
 .../http/impl/async/HttpAsyncClientBuilder.java    |  59 +---
 .../client5/http/impl/async/HttpAsyncClients.java  |  23 +-
 .../async/InternalAbstractHttpAsyncClient.java     | 302 ++++++++---------
 .../impl/async/InternalHttpAsyncExecRuntime.java   |   9 +-
 .../async/LoggingAsyncClientExchangeHandler.java   |  52 ++-
 .../http/impl/async/MinimalH2AsyncClient.java      | 243 ++++++--------
 .../http/impl/async/MinimalHttpAsyncClient.java    | 292 ++++++++--------
 .../hc/client5/http/impl/auth/NTLMEngineImpl.java  |   2 +-
 .../http/impl/classic/AIMDBackoffManager.java      |  12 +-
 .../http/impl/classic/ExecChainElement.java        |  11 +-
 .../http/impl/classic/HttpClientBuilder.java       |  31 +-
 .../http/impl/classic/ResponseEntityProxy.java     |  19 +-
 .../http/impl/cookie/LaxExpiresHandler.java        |   2 +-
 .../http/impl/cookie/RFC6265CookieSpec.java        |   2 +-
 .../nio/PoolingAsyncClientConnectionManager.java   |  18 +-
 .../http/socket/PlainConnectionSocketFactory.java  |   9 +-
 .../http/ssl/AbstractClientTlsStrategy.java        |  75 ++---
 .../client5/http/ssl/ClientTlsStrategyBuilder.java |  13 +-
 .../http/ssl/ConscryptClientTlsStrategy.java       |   2 +-
 .../apache/hc/client5/http/ssl/HttpsSupport.java   |   9 +-
 .../http/ssl/SSLConnectionSocketFactory.java       |   9 +-
 .../http/entity/TestDecompressingEntity.java       |  10 +-
 .../http/examples/AsyncClientCustomSSL.java        |  15 +-
 .../http/examples/AsyncClientH2ServerPush.java     |  55 ++-
 .../http/examples/AsyncClientInterceptors.java     |  38 +--
 .../http/examples/AsyncClientMessageTrailers.java  |  31 +-
 .../hc/client5/http/examples/ClientCustomSSL.java  |  15 +-
 .../client5/http/examples/ClientInterceptors.java  |  27 +-
 .../http/examples/ClientWithRequestFuture.java     |  11 +-
 .../http/examples/ClientWithResponseHandler.java   |  29 +-
 .../examples/ReactiveClientFullDuplexExchange.java |  21 +-
 .../http/impl/classic/MockConnPoolControl.java     |   4 +-
 .../client5/http/impl/classic/TestConnectExec.java |  25 +-
 .../classic/TestFutureRequestExecutionService.java |  35 +-
 .../classic/TestHttpClientBuilderInterceptors.java |  39 +--
 .../impl/classic/TestHttpRequestRetryExec.java     |  44 +--
 .../http/impl/classic/TestMainClientExec.java      |  23 +-
 .../http/impl/classic/TestProtocolExec.java        |  18 +-
 .../http/impl/routing/TestRouteTracker.java        |  40 +--
 .../hc/client5/http/routing/TestHttpRoute.java     |  21 +-
 pom.xml                                            |   4 +-
 91 files changed, 1385 insertions(+), 2969 deletions(-)

diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
index ff53120..8d071d6 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
@@ -124,7 +124,7 @@ public class HttpCacheEntry implements MessageHeaders, Serializable {
      */
     public HttpCacheEntry(final Date requestDate, final Date responseDate, final int status,
             final Header[] responseHeaders, final Resource resource) {
-        this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<String,String>());
+        this(requestDate, responseDate, status, responseHeaders, resource, new HashMap<>());
     }
 
     /**
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
index 0263a6d..126192b 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
@@ -187,7 +187,7 @@ public abstract class AbstractSerializingAsyncCacheStorage<T, CAS> implements Ht
 
                                 @Override
                                 public void completed(final Boolean result) {
-                                    if (result) {
+                                    if (result.booleanValue()) {
                                         callback.completed(result);
                                     } else {
                                         if (!complexCancellable.isCancelled()) {
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
index 93419a7..c9001b2 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
@@ -57,7 +57,6 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Factory;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
@@ -102,14 +101,8 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
         super(config);
         this.responseCache = Args.notNull(cache, "Response cache");
         this.cacheRevalidator = cacheRevalidator;
-        this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(new Factory<HttpRequest, HttpRequest>() {
-
-            @Override
-            public HttpRequest create(final HttpRequest request) {
-                return BasicRequestBuilder.copy(request).build();
-            }
-
-        });
+        this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(request ->
+                BasicRequestBuilder.copy(request).build());
     }
 
     AsyncCachingExec(
@@ -675,14 +668,7 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
                     cacheRevalidator.revalidateCacheEntry(
                             responseCache.generateKey(target, request, entry),
                             asyncExecCallback,
-                            new DefaultAsyncCacheRevalidator.RevalidationCall() {
-
-                                @Override
-                                public void execute(final AsyncExecCallback asyncExecCallback) {
-                                    revalidateCacheEntry(target, request, entityProducer, fork, chain, asyncExecCallback, entry);
-                                }
-
-                            });
+                            asyncExecCallback1 -> revalidateCacheEntry(target, request, entityProducer, fork, chain, asyncExecCallback1, entry));
                     triggerResponse(cacheResponse, scope, asyncExecCallback);
                 } catch (final ResourceIOException ex) {
                     asyncExecCallback.failed(ex);
@@ -771,26 +757,12 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
                     recordCacheUpdate(scope.clientContext);
                 }
                 if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
-                    return new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                        @Override
-                        public void run() {
-                            triggerUpdatedCacheEntryResponse(backendResponse, responseDate);
-                        }
-
-                    });
+                    return new AsyncExecCallbackWrapper(asyncExecCallback, () -> triggerUpdatedCacheEntryResponse(backendResponse, responseDate));
                 }
                 if (staleIfErrorAppliesTo(statusCode)
                         && !staleResponseNotAllowed(request, cacheEntry, getCurrentDate())
                         && validityPolicy.mayReturnStaleIfError(request, cacheEntry, responseDate)) {
-                    return new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                        @Override
-                        public void run() {
-                            triggerResponseStaleCacheEntry();
-                        }
-
-                    });
+                    return new AsyncExecCallbackWrapper(asyncExecCallback, this::triggerResponseStaleCacheEntry);
                 }
                 return new BackendResponseHandler(target, conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
             }
@@ -809,57 +781,49 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
                     final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
                             BasicRequestBuilder.copy(scope.originalRequest).build());
 
-                    callback1 = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
+                    callback1 = new AsyncExecCallbackWrapper(asyncExecCallback, () -> chainProceed(unconditional, entityProducer, scope, chain, new AsyncExecCallback() {
 
                         @Override
-                        public void run() {
-                            chainProceed(unconditional, entityProducer, scope, chain, new AsyncExecCallback() {
-
-                                @Override
-                                public AsyncDataConsumer handleResponse(
-                                        final HttpResponse backendResponse2,
-                                        final EntityDetails entityDetails) throws HttpException, IOException {
-                                    final Date responseDate2 = getCurrentDate();
-                                    final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2);
-                                    callbackRef.set(callback2);
-                                    return callback2.handleResponse(backendResponse2, entityDetails);
-                                }
-
-                                @Override
-                                public void handleInformationResponse(final HttpResponse response) throws HttpException, IOException {
-                                    final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
-                                    if (callback2 != null) {
-                                        callback2.handleInformationResponse(response);
-                                    } else {
-                                        asyncExecCallback.handleInformationResponse(response);
-                                    }
-                                }
-
-                                @Override
-                                public void completed() {
-                                    final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
-                                    if (callback2 != null) {
-                                        callback2.completed();
-                                    } else {
-                                        asyncExecCallback.completed();
-                                    }
-                                }
+                        public AsyncDataConsumer handleResponse(
+                                final HttpResponse backendResponse2,
+                                final EntityDetails entityDetails1) throws HttpException, IOException {
+                            final Date responseDate2 = getCurrentDate();
+                            final AsyncExecCallback callback2 = evaluateResponse(backendResponse2, responseDate2);
+                            callbackRef.set(callback2);
+                            return callback2.handleResponse(backendResponse2, entityDetails1);
+                        }
 
-                                @Override
-                                public void failed(final Exception cause) {
-                                    final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
-                                    if (callback2 != null) {
-                                        callback2.failed(cause);
-                                    } else {
-                                        asyncExecCallback.failed(cause);
-                                    }
-                                }
+                        @Override
+                        public void handleInformationResponse(final HttpResponse response) throws HttpException, IOException {
+                            final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
+                            if (callback2 != null) {
+                                callback2.handleInformationResponse(response);
+                            } else {
+                                asyncExecCallback.handleInformationResponse(response);
+                            }
+                        }
 
-                            });
+                        @Override
+                        public void completed() {
+                            final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
+                            if (callback2 != null) {
+                                callback2.completed();
+                            } else {
+                                asyncExecCallback.completed();
+                            }
+                        }
 
+                        @Override
+                        public void failed(final Exception cause) {
+                            final AsyncExecCallback callback2 = callbackRef.getAndSet(null);
+                            if (callback2 != null) {
+                                callback2.failed(cause);
+                            } else {
+                                asyncExecCallback.failed(cause);
+                            }
                         }
 
-                    });
+                    }));
                 } else {
                     callback1 = evaluateResponse(backendResponse1, responseDate1);
                 }
@@ -1036,49 +1000,21 @@ class AsyncCachingExec extends CachingExecBase implements AsyncExecChainHandler
                     final Header resultEtagHeader = backendResponse.getFirstHeader(HeaderConstants.ETAG);
                     if (resultEtagHeader == null) {
                         LOG.warn("304 response did not contain ETag");
-                        callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                            @Override
-                            public void run() {
-                                callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
-                            }
-
-                        });
+                        callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
                     } else {
                         final String resultEtag = resultEtagHeader.getValue();
                         final Variant matchingVariant = variants.get(resultEtag);
                         if (matchingVariant == null) {
                             LOG.debug("304 response did not contain ETag matching one sent in If-None-Match");
-                            callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                                @Override
-                                public void run() {
-                                    callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
-                                }
-
-                            });
+                            callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
                         } else {
                             if (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry())) {
                                 final HttpRequest unconditional = conditionalRequestBuilder.buildUnconditionalRequest(
                                         BasicRequestBuilder.copy(request).build());
                                 scope.clientContext.setAttribute(HttpCoreContext.HTTP_REQUEST, unconditional);
-                                callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                                    @Override
-                                    public void run() {
-                                        callBackend(target, request, entityProducer, scope, chain, asyncExecCallback);
-                                    }
-
-                                });
+                                callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target, request, entityProducer, scope, chain, asyncExecCallback));
                             } else {
-                                callback = new AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
-
-                                    @Override
-                                    public void run() {
-                                        updateVariantCacheEntry(backendResponse, responseDate, matchingVariant);
-                                    }
-
-                                });
+                                callback = new AsyncExecCallbackWrapper(asyncExecCallback, () -> updateVariantCacheEntry(backendResponse, responseDate, matchingVariant));
                             }
                         }
                     }
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
index 7ba4040..e3bf75b 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
@@ -34,7 +34,6 @@ import java.util.Set;
 import org.apache.hc.client5.http.cache.HeaderConstants;
 import org.apache.hc.client5.http.cache.HttpAsyncCacheInvalidator;
 import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
 import org.apache.hc.client5.http.cache.ResourceFactory;
@@ -211,14 +210,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
             @Override
             public void completed(final Boolean result) {
                 storage.updateEntry(cacheKey,
-                        new HttpCacheCASOperation() {
-
-                            @Override
-                            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                                return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
-                            }
-
-                        },
+                        existing -> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey),
                         new FutureCallback<Boolean>() {
 
                             @Override
@@ -280,14 +272,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
         final String variantKey = cacheKeyGenerator.generateVariantKey(request, entry);
         final String variantCacheKey = variant.getCacheKey();
         return storage.updateEntry(cacheKey,
-                new HttpCacheCASOperation() {
-
-                    @Override
-                    public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                        return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
-                    }
-
-                },
+                existing -> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey),
                 new FutureCallback<Boolean>() {
 
                     @Override
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
index 11125d0..70e5272 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
@@ -31,7 +31,6 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.hc.client5.http.cache.HeaderConstants;
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
 import org.apache.hc.client5.http.cache.HttpCacheStorage;
@@ -163,14 +162,7 @@ class BasicHttpCache implements HttpCache {
         final String variantCacheKey = cacheKeyGenerator.generateKey(host, req, entry);
         storeEntry(variantCacheKey, entry);
         try {
-            storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
-
-                @Override
-                public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey);
-                }
-
-            });
+            storage.updateEntry(cacheKey, existing -> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing, entry, variantKey, variantCacheKey));
         } catch (final HttpCacheUpdateException ex) {
             if (LOG.isWarnEnabled()) {
                 LOG.warn("Cannot update cache entry with key {}", cacheKey);
@@ -194,14 +186,7 @@ class BasicHttpCache implements HttpCache {
         final String variantCacheKey = variant.getCacheKey();
 
         try {
-            storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
-
-                @Override
-                public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey);
-                }
-
-            });
+            storage.updateEntry(cacheKey, existing -> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(), existing, entry, variantKey, variantCacheKey));
         } catch (final HttpCacheUpdateException ex) {
             if (LOG.isWarnEnabled()) {
                 LOG.warn("Cannot update cache entry with key {}", cacheKey);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
index 80fdb6b..c49a36a 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
@@ -66,7 +66,7 @@ class BasicIdGenerator {
         buffer.append(System.currentTimeMillis());
         buffer.append('.');
         final Formatter formatter = new Formatter(buffer, Locale.ROOT);
-        formatter.format("%1$016x-%2$08x", Long.valueOf(this.count), Integer.valueOf(rndnum));
+        formatter.format("%1$016x-%2$08x", this.count, rndnum);
         formatter.close();
         buffer.append('.');
         buffer.append(this.hostname);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
index fa702e0..f2e4125 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
@@ -48,7 +48,6 @@ import org.apache.hc.client5.http.impl.ExecSupport;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.schedule.SchedulingStrategy;
 import org.apache.hc.client5.http.utils.DateUtils;
-import org.apache.hc.core5.function.Factory;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.Header;
@@ -111,14 +110,8 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
         super(config);
         this.responseCache = Args.notNull(cache, "Response cache");
         this.cacheRevalidator = cacheRevalidator;
-        this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(new Factory<ClassicHttpRequest, ClassicHttpRequest>() {
-
-            @Override
-            public ClassicHttpRequest create(final ClassicHttpRequest classicHttpRequest) {
-                return ClassicRequestBuilder.copy(classicHttpRequest).build();
-            }
-
-        });
+        this.conditionalRequestBuilder = new ConditionalRequestBuilder<>(classicHttpRequest ->
+                    ClassicRequestBuilder.copy(classicHttpRequest).build());
     }
 
     CachingExec(
@@ -290,14 +283,7 @@ class CachingExec extends CachingExecBase implements ExecChainHandler {
                     final SimpleHttpResponse response = generateCachedResponse(request, context, entry, now);
                     cacheRevalidator.revalidateCacheEntry(
                             responseCache.generateKey(target, request, entry),
-                            new DefaultCacheRevalidator.RevalidationCall() {
-
-                        @Override
-                        public ClassicHttpResponse execute() throws HttpException, IOException {
-                            return revalidateCacheEntry(target, request, fork, chain, entry);
-                        }
-
-                    });
+                            () -> revalidateCacheEntry(target, request, fork, chain, entry));
                     return convert(response, scope);
                 }
                 return revalidateCacheEntry(target, request, scope, chain, entry);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
index e8b4b50..f468cfe 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
@@ -26,9 +26,7 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.Closeable;
 import java.io.File;
-import java.io.IOException;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 
@@ -130,14 +128,7 @@ public class CachingH2AsyncClientBuilder extends H2AsyncClientBuilder {
             } else {
                 final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
                 if (this.deleteCache) {
-                    addCloseable(new Closeable() {
-
-                        @Override
-                        public void close() throws IOException {
-                            managedStorage.shutdown();
-                        }
-
-                    });
+                    addCloseable(managedStorage::shutdown);
                 } else {
                     addCloseable(managedStorage);
                 }
@@ -153,14 +144,7 @@ public class CachingH2AsyncClientBuilder extends H2AsyncClientBuilder {
         DefaultAsyncCacheRevalidator cacheRevalidator = null;
         if (config.getAsynchronousWorkers() > 0) {
             final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
-            addCloseable(new Closeable() {
-
-                @Override
-                public void close() throws IOException {
-                    executorService.shutdownNow();
-                }
-
-            });
+            addCloseable(executorService::shutdownNow);
             cacheRevalidator = new DefaultAsyncCacheRevalidator(
                     executorService,
                     this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
index fe92f61..15dbe7c 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
@@ -26,9 +26,7 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.Closeable;
 import java.io.File;
-import java.io.IOException;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 
@@ -130,14 +128,7 @@ public class CachingHttpAsyncClientBuilder extends HttpAsyncClientBuilder {
             } else {
                 final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
                 if (this.deleteCache) {
-                    addCloseable(new Closeable() {
-
-                        @Override
-                        public void close() throws IOException {
-                            managedStorage.shutdown();
-                        }
-
-                    });
+                    addCloseable(managedStorage::shutdown);
                 } else {
                     addCloseable(managedStorage);
                 }
@@ -153,14 +144,7 @@ public class CachingHttpAsyncClientBuilder extends HttpAsyncClientBuilder {
         DefaultAsyncCacheRevalidator cacheRevalidator = null;
         if (config.getAsynchronousWorkers() > 0) {
             final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
-            addCloseable(new Closeable() {
-
-                @Override
-                public void close() throws IOException {
-                    executorService.shutdownNow();
-                }
-
-            });
+            addCloseable(executorService::shutdownNow);
             cacheRevalidator = new DefaultAsyncCacheRevalidator(
                     executorService,
                     this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
index 5d6bf91..f2b1e51 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
@@ -26,9 +26,7 @@
  */
 package org.apache.hc.client5.http.impl.cache;
 
-import java.io.Closeable;
 import java.io.File;
-import java.io.IOException;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledThreadPoolExecutor;
 
@@ -122,14 +120,7 @@ public class CachingHttpClientBuilder extends HttpClientBuilder {
             } else {
                 final ManagedHttpCacheStorage managedStorage = new ManagedHttpCacheStorage(config);
                 if (this.deleteCache) {
-                    addCloseable(new Closeable() {
-
-                        @Override
-                        public void close() throws IOException {
-                            managedStorage.shutdown();
-                        }
-
-                    });
+                    addCloseable(managedStorage::shutdown);
                 } else {
                     addCloseable(managedStorage);
                 }
@@ -145,14 +136,7 @@ public class CachingHttpClientBuilder extends HttpClientBuilder {
         DefaultCacheRevalidator cacheRevalidator = null;
         if (config.getAsynchronousWorkers() > 0) {
             final ScheduledExecutorService executorService = new ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
-            addCloseable(new Closeable() {
-
-                @Override
-                public void close() throws IOException {
-                    executorService.shutdownNow();
-                }
-
-            });
+            addCloseable(executorService::shutdownNow);
             cacheRevalidator = new DefaultCacheRevalidator(
                     executorService,
                     this.schedulingStrategy != null ? this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
index 4a57479..77b720b 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
@@ -70,7 +70,7 @@ public class DefaultAsyncCacheInvalidator extends CacheInvalidatorBase implement
             @Override
             public void completed(final Boolean result) {
                 if (LOG.isDebugEnabled()) {
-                    if (result) {
+                    if (result.booleanValue()) {
                         LOG.debug("Cache entry with key {} successfully flushed", cacheKey);
                     } else {
                         LOG.debug("Cache entry with key {} could not be flushed", cacheKey);
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
index 90718d8..43fab11 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
@@ -118,59 +118,52 @@ class DefaultAsyncCacheRevalidator extends CacheRevalidatorBase {
             final String cacheKey ,
             final AsyncExecCallback asyncExecCallback,
             final RevalidationCall call) {
-        scheduleRevalidation(cacheKey, new Runnable() {
-
-                        @Override
-                        public void run() {
-                            call.execute(new AsyncExecCallback() {
-
-                                private final AtomicReference<HttpResponse> responseRef = new AtomicReference<>(null);
-
-                                @Override
-                                public AsyncDataConsumer handleResponse(
-                                        final HttpResponse response,
-                                        final EntityDetails entityDetails) throws HttpException, IOException {
-                                    responseRef.set(response);
-                                    return asyncExecCallback.handleResponse(response, entityDetails);
-                                }
-
-                                @Override
-                                public void handleInformationResponse(
-                                        final HttpResponse response) throws HttpException, IOException {
-                                    asyncExecCallback.handleInformationResponse(response);
-                                }
-
-                                @Override
-                                public void completed() {
-                                    final HttpResponse httpResponse = responseRef.getAndSet(null);
-                                    if (httpResponse != null && httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
-                                        jobSuccessful(cacheKey);
-                                    } else {
-                                        jobFailed(cacheKey);
-                                    }
-                                    asyncExecCallback.completed();
-                                }
-
-                                @Override
-                                public void failed(final Exception cause) {
-                                    if (cause instanceof IOException) {
-                                        LOG.debug("Asynchronous revalidation failed due to I/O error", cause);
-                                    } else if (cause instanceof HttpException) {
-                                        LOG.error("HTTP protocol exception during asynchronous revalidation", cause);
-                                    } else {
-                                        LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", cause);
-                                    }
-                                    try {
-                                        jobFailed(cacheKey);
-                                    } finally {
-                                        asyncExecCallback.failed(cause);
-                                    }
-                                }
-
-                            });
-                        }
-
-                    });
+        scheduleRevalidation(cacheKey, () -> call.execute(new AsyncExecCallback() {
+
+            private final AtomicReference<HttpResponse> responseRef = new AtomicReference<>(null);
+
+            @Override
+            public AsyncDataConsumer handleResponse(
+                    final HttpResponse response,
+                    final EntityDetails entityDetails) throws HttpException, IOException {
+                responseRef.set(response);
+                return asyncExecCallback.handleResponse(response, entityDetails);
+            }
+
+            @Override
+            public void handleInformationResponse(
+                    final HttpResponse response) throws HttpException, IOException {
+                asyncExecCallback.handleInformationResponse(response);
+            }
+
+            @Override
+            public void completed() {
+                final HttpResponse httpResponse = responseRef.getAndSet(null);
+                if (httpResponse != null && httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
+                    jobSuccessful(cacheKey);
+                } else {
+                    jobFailed(cacheKey);
+                }
+                asyncExecCallback.completed();
+            }
+
+            @Override
+            public void failed(final Exception cause) {
+                if (cause instanceof IOException) {
+                    LOG.debug("Asynchronous revalidation failed due to I/O error", cause);
+                } else if (cause instanceof HttpException) {
+                    LOG.error("HTTP protocol exception during asynchronous revalidation", cause);
+                } else {
+                    LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", cause);
+                }
+                try {
+                    jobFailed(cacheKey);
+                } finally {
+                    asyncExecCallback.failed(cause);
+                }
+            }
+
+        }));
     }
 
 }
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
index 514b904..b4846aa 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
@@ -75,30 +75,25 @@ class DefaultCacheRevalidator extends CacheRevalidatorBase {
     public void revalidateCacheEntry(
             final String cacheKey,
             final RevalidationCall call) {
-        scheduleRevalidation(cacheKey, new Runnable() {
+        scheduleRevalidation(cacheKey, () -> {
+            try (ClassicHttpResponse httpResponse = call.execute()) {
+                if (httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
+                    jobSuccessful(cacheKey);
+                } else {
+                    jobFailed(cacheKey);
+                }
+            } catch (final IOException ex) {
+                jobFailed(cacheKey);
+                LOG.debug("Asynchronous revalidation failed due to I/O error", ex);
+            } catch (final HttpException ex) {
+                jobFailed(cacheKey);
+                LOG.error("HTTP protocol exception during asynchronous revalidation", ex);
+            } catch (final RuntimeException ex) {
+                jobFailed(cacheKey);
+                LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", ex);
+            }
 
-                        @Override
-                        public void run() {
-                            try (ClassicHttpResponse httpResponse = call.execute()) {
-                                if (httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
-                                    jobSuccessful(cacheKey);
-                                } else {
-                                    jobFailed(cacheKey);
-                                }
-                            } catch (final IOException ex) {
-                                jobFailed(cacheKey);
-                                LOG.debug("Asynchronous revalidation failed due to I/O error", ex);
-                            } catch (final HttpException ex) {
-                                jobFailed(cacheKey);
-                                LOG.error("HTTP protocol exception during asynchronous revalidation", ex);
-                            } catch (final RuntimeException ex) {
-                                jobFailed(cacheKey);
-                                LOG.error("Unexpected runtime exception thrown during asynchronous revalidation", ex);
-                            }
-
-                        }
-
-                    });
+        });
     }
 
 }
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
index 70747cf..905cf86 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
@@ -358,10 +358,10 @@ class WarningValue {
     @Override
     public String toString() {
         if (warnDate != null) {
-            return String.format("%d %s %s \"%s\"", Integer.valueOf(warnCode),
+            return String.format("%d %s %s \"%s\"", warnCode,
                     warnAgent, warnText, DateUtils.formatDate(warnDate));
         } else {
-            return String.format("%d %s %s", Integer.valueOf(warnCode), warnAgent, warnText);
+            return String.format("%d %s %s", warnCode, warnAgent, warnText);
         }
     }
 
diff --git a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
index 36d075c..b49d63f 100644
--- a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
+++ b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
@@ -47,11 +47,7 @@ import net.spy.memcached.CASResponse;
 import net.spy.memcached.CASValue;
 import net.spy.memcached.MemcachedClient;
 import net.spy.memcached.internal.BulkFuture;
-import net.spy.memcached.internal.BulkGetCompletionListener;
-import net.spy.memcached.internal.BulkGetFuture;
-import net.spy.memcached.internal.GetCompletionListener;
 import net.spy.memcached.internal.GetFuture;
-import net.spy.memcached.internal.OperationCompletionListener;
 import net.spy.memcached.internal.OperationFuture;
 
 /**
@@ -160,21 +156,16 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
     }
 
     private <T> Cancellable operation(final OperationFuture<T> operationFuture, final FutureCallback<T> callback) {
-        operationFuture.addListener(new OperationCompletionListener() {
-
-            @Override
-            public void onComplete(final OperationFuture<?> future) throws Exception {
-                try {
-                    callback.completed(operationFuture.get());
-                } catch (final ExecutionException ex) {
-                    if (ex.getCause() instanceof Exception) {
-                        callback.failed((Exception) ex.getCause());
-                    } else {
-                        callback.failed(ex);
-                    }
+        operationFuture.addListener(future -> {
+            try {
+                callback.completed(operationFuture.get());
+            } catch (final ExecutionException ex) {
+                if (ex.getCause() instanceof Exception) {
+                    callback.failed((Exception) ex.getCause());
+                } else {
+                    callback.failed(ex);
                 }
             }
-
         });
         return Operations.cancellable(operationFuture);
     }
@@ -187,21 +178,16 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
     @Override
     protected Cancellable restore(final String storageKey, final FutureCallback<byte[]> callback) {
         final GetFuture<Object> getFuture = client.asyncGet(storageKey);
-        getFuture.addListener(new GetCompletionListener() {
-
-            @Override
-            public void onComplete(final GetFuture<?> future) throws Exception {
-                try {
-                    callback.completed(castAsByteArray(getFuture.get()));
-                } catch (final ExecutionException ex) {
-                    if (ex.getCause() instanceof Exception) {
-                        callback.failed((Exception) ex.getCause());
-                    } else {
-                        callback.failed(ex);
-                    }
+        getFuture.addListener(future -> {
+            try {
+                callback.completed(castAsByteArray(getFuture.get()));
+            } catch (final ExecutionException ex) {
+                if (ex.getCause() instanceof Exception) {
+                    callback.failed((Exception) ex.getCause());
+                } else {
+                    callback.failed(ex);
                 }
             }
-
         });
         return Operations.cancellable(getFuture);
     }
@@ -242,17 +228,13 @@ public class MemcachedHttpAsyncCacheStorage extends AbstractBinaryAsyncCacheStor
     @Override
     protected Cancellable bulkRestore(final Collection<String> storageKeys, final FutureCallback<Map<String, byte[]>> callback) {
         final BulkFuture<Map<String, Object>> future = client.asyncGetBulk(storageKeys);
-        future.addListener(new BulkGetCompletionListener() {
-
-            @Override
-            public void onComplete(final BulkGetFuture<?> future) throws Exception {
-                final Map<String, ?> storageObjectMap = future.get();
-                final Map<String, byte[]> resultMap = new HashMap<>(storageObjectMap.size());
-                for (final Map.Entry<String, ?> resultEntry: storageObjectMap.entrySet()) {
-                    resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue()));
-                }
-                callback.completed(resultMap);
+        future.addListener(future1 -> {
+            final Map<String, ?> storageObjectMap = future1.get();
+            final Map<String, byte[]> resultMap = new HashMap<>(storageObjectMap.size());
+            for (final Map.Entry<String, ?> resultEntry: storageObjectMap.entrySet()) {
+                resultMap.put(resultEntry.getKey(), castAsByteArray(resultEntry.getValue()));
             }
+            callback.completed(resultMap);
         });
         return Operations.cancellable(future);
     }
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
index 88b8cbc..791ae61 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
@@ -217,7 +217,7 @@ public class TestHttpCacheEntry {
     public void canProvideVariantMap() {
         new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
                 new Header[]{}, mockResource,
-                new HashMap<String,String>());
+                new HashMap<>());
     }
 
     @Test
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
index 8d83f7f..67e75a2 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
@@ -155,7 +155,7 @@ public abstract class AbstractProtocolTest {
         EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
             .andReturn(null).anyTimes();
         EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class)))
-            .andReturn(new HashMap<String,Variant>()).anyTimes();
+            .andReturn(new HashMap<>()).anyTimes();
 
         mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class), EasyMock.isA(HttpRequest.class));
         EasyMock.expectLastCall().anyTimes();
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
index f0b1ad6..1692054 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
@@ -35,7 +35,6 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
 import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
@@ -52,7 +51,6 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 
@@ -90,16 +88,11 @@ public class TestAbstractSerializingAsyncCacheStorage {
         Mockito.when(impl.store(
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(2);
-                callback.completed(true);
-                return cancellable;
-            }
-
-        });
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(2);
+                    callback.completed(true);
+                    return cancellable;
+                });
 
         impl.putEntry(key, value, operationCallback);
 
@@ -114,15 +107,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
         final String key = "foo";
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
-        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<byte[]> callback = invocation.getArgument(1);
-                callback.completed(null);
-                return cancellable;
-            }
-
+        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+            final FutureCallback<byte[]> callback = invocation.getArgument(1);
+            callback.completed(null);
+            return cancellable;
         });
 
         impl.getEntry(key, cacheEntryCallback);
@@ -138,15 +126,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
         final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
-        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<byte[]> callback = invocation.getArgument(1);
-                callback.completed(serialize(key, value));
-                return cancellable;
-            }
-
+        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+            final FutureCallback<byte[]> callback = invocation.getArgument(1);
+            callback.completed(serialize(key, value));
+            return cancellable;
         });
 
         impl.getEntry(key, cacheEntryCallback);
@@ -162,15 +145,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
         final String key = "foo";
         final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
-        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<byte[]> callback = invocation.getArgument(1);
-                callback.completed(serialize("not-foo", value));
-                return cancellable;
-            }
-
+        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+            final FutureCallback<byte[]> callback = invocation.getArgument(1);
+            callback.completed(serialize("not-foo", value));
+            return cancellable;
         });
 
         impl.getEntry(key, cacheEntryCallback);
@@ -187,16 +165,11 @@ public class TestAbstractSerializingAsyncCacheStorage {
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
         Mockito.when(impl.delete(
                 ArgumentMatchers.eq("bar"),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(1);
-                callback.completed(true);
-                return cancellable;
-            }
-
-        });
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(1);
+                    callback.completed(true);
+                    return cancellable;
+                });
         impl.removeEntry(key, operationCallback);
 
         Mockito.verify(impl).delete("bar", operationCallback);
@@ -209,38 +182,23 @@ public class TestAbstractSerializingAsyncCacheStorage {
         final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
-        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<byte[]> callback = invocation.getArgument(1);
-                callback.completed(null);
-                return cancellable;
-            }
-
+        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+            final FutureCallback<byte[]> callback = invocation.getArgument(1);
+            callback.completed(null);
+            return cancellable;
         });
         Mockito.when(impl.store(
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(2);
-                callback.completed(true);
-                return cancellable;
-            }
-
-        });
-
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                Assert.assertThat(existing, CoreMatchers.nullValue());
-                return updatedValue;
-            }
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(2);
+                    callback.completed(true);
+                    return cancellable;
+                });
 
+        impl.updateEntry(key, existing -> {
+            Assert.assertThat(existing, CoreMatchers.nullValue());
+            return updatedValue;
         }, operationCallback);
 
         Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
@@ -255,40 +213,23 @@ public class TestAbstractSerializingAsyncCacheStorage {
         final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
-        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<String> callback = invocation.getArgument(1);
-                callback.completed("stuff");
-                return cancellable;
-            }
-
+        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+            final FutureCallback<String> callback = invocation.getArgument(1);
+            callback.completed("stuff");
+            return cancellable;
         });
         Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
         Mockito.when(impl.updateCAS(
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.eq("stuff"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(3);
-                callback.completed(true);
-                return cancellable;
-            }
-
-        });
-
-        impl.updateEntry(key, new HttpCacheCASOperation() {
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(3);
+                    callback.completed(true);
+                    return cancellable;
+                });
 
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                return updatedValue;
-            }
-
-        }, operationCallback);
+        impl.updateEntry(key, existing -> updatedValue, operationCallback);
 
         Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
         Mockito.verify(impl).getStorageObject("stuff");
@@ -304,39 +245,24 @@ public class TestAbstractSerializingAsyncCacheStorage {
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
         Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
-                new Answer<Cancellable>() {
-
-                    @Override
-                    public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                        final FutureCallback<String> callback = invocation.getArgument(1);
-                        callback.completed("stuff");
-                        return cancellable;
-                    }
-
+                (Answer<Cancellable>) invocation -> {
+                    final FutureCallback<String> callback = invocation.getArgument(1);
+                    callback.completed("stuff");
+                    return cancellable;
                 });
         Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
         Mockito.when(impl.store(
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(2);
-                callback.completed(true);
-                return cancellable;
-            }
-
-        });
-
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                Assert.assertThat(existing, CoreMatchers.nullValue());
-                return updatedValue;
-            }
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(2);
+                    callback.completed(true);
+                    return cancellable;
+                });
 
+        impl.updateEntry(key, existing -> {
+            Assert.assertThat(existing, CoreMatchers.nullValue());
+            return updatedValue;
         }, operationCallback);
 
         Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
@@ -355,15 +281,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
         Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
-                new Answer<Cancellable>() {
-
-                    @Override
-                    public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                        final FutureCallback<String> callback = invocation.getArgument(1);
-                        callback.completed("stuff");
-                        return cancellable;
-                    }
-
+                (Answer<Cancellable>) invocation -> {
+                    final FutureCallback<String> callback = invocation.getArgument(1);
+                    callback.completed("stuff");
+                    return cancellable;
                 });
         Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
         final AtomicInteger count = new AtomicInteger(0);
@@ -371,29 +292,17 @@ public class TestAbstractSerializingAsyncCacheStorage {
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.eq("stuff"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(3);
-                if (count.incrementAndGet() == 1) {
-                    callback.completed(false);
-                } else {
-                    callback.completed(true);
-                }
-                return cancellable;
-            }
-
-        });
-
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                return updatedValue;
-            }
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(3);
+                    if (count.incrementAndGet() == 1) {
+                        callback.completed(false);
+                    } else {
+                        callback.completed(true);
+                    }
+                    return cancellable;
+                });
 
-        }, operationCallback);
+        impl.updateEntry(key, existing -> updatedValue, operationCallback);
 
         Mockito.verify(impl, Mockito.times(2)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
         Mockito.verify(impl, Mockito.times(2)).getStorageObject("stuff");
@@ -410,15 +319,10 @@ public class TestAbstractSerializingAsyncCacheStorage {
 
         Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
         Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
-                new Answer<Cancellable>() {
-
-                    @Override
-                    public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                        final FutureCallback<String> callback = invocation.getArgument(1);
-                        callback.completed("stuff");
-                        return cancellable;
-                    }
-
+                (Answer<Cancellable>) invocation -> {
+                    final FutureCallback<String> callback = invocation.getArgument(1);
+                    callback.completed("stuff");
+                    return cancellable;
                 });
         Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
         final AtomicInteger count = new AtomicInteger(0);
@@ -426,29 +330,17 @@ public class TestAbstractSerializingAsyncCacheStorage {
                 ArgumentMatchers.eq("bar"),
                 ArgumentMatchers.eq("stuff"),
                 ArgumentMatchers.<byte[]>any(),
-                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<Boolean> callback = invocation.getArgument(3);
-                if (count.incrementAndGet() <= 3) {
-                    callback.completed(false);
-                } else {
-                    callback.completed(true);
-                }
-                return cancellable;
-            }
-
-        });
-
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                return updatedValue;
-            }
+                ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<Boolean> callback = invocation.getArgument(3);
+                    if (count.incrementAndGet() <= 3) {
+                        callback.completed(false);
+                    } else {
+                        callback.completed(true);
+                    }
+                    return cancellable;
+                });
 
-        }, operationCallback);
+        impl.updateEntry(key, existing -> updatedValue, operationCallback);
 
         Mockito.verify(impl, Mockito.times(3)).getForUpdateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.<FutureCallback<String>>any());
         Mockito.verify(impl, Mockito.times(3)).getStorageObject("stuff");
@@ -472,23 +364,19 @@ public class TestAbstractSerializingAsyncCacheStorage {
 
         when(impl.bulkRestore(
                 ArgumentMatchers.<String>anyCollection(),
-                ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final Collection<String> keys = invocation.getArgument(0);
-                final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
-                final Map<String, byte[]> resultMap = new HashMap<>();
-                if (keys.contains(storageKey1)) {
-                    resultMap.put(storageKey1, serialize(key1, value1));
-                }
-                if (keys.contains(storageKey2)) {
-                    resultMap.put(storageKey2, serialize(key2, value2));
-                }
-                callback.completed(resultMap);
-                return cancellable;
-            }
-        });
+                ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final Collection<String> keys = invocation.getArgument(0);
+                    final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
+                    final Map<String, byte[]> resultMap = new HashMap<>();
+                    if (keys.contains(storageKey1)) {
+                        resultMap.put(storageKey1, serialize(key1, value1));
+                    }
+                    if (keys.contains(storageKey2)) {
+                        resultMap.put(storageKey2, serialize(key2, value2));
+                    }
+                    callback.completed(resultMap);
+                    return cancellable;
+                });
 
         impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
         final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
@@ -521,23 +409,19 @@ public class TestAbstractSerializingAsyncCacheStorage {
 
         when(impl.bulkRestore(
                 ArgumentMatchers.<String>anyCollection(),
-                ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final Collection<String> keys = invocation.getArgument(0);
-                final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
-                final Map<String, byte[]> resultMap = new HashMap<>();
-                if (keys.contains(storageKey1)) {
-                    resultMap.put(storageKey1, serialize(key1, value1));
-                }
-                if (keys.contains(storageKey2)) {
-                    resultMap.put(storageKey2, serialize("not foo", value2));
-                }
-                callback.completed(resultMap);
-                return cancellable;
-            }
-        });
+                ArgumentMatchers.<FutureCallback<Map<String, byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final Collection<String> keys = invocation.getArgument(0);
+                    final FutureCallback<Map<String, byte[]>> callback = invocation.getArgument(1);
+                    final Map<String, byte[]> resultMap = new HashMap<>();
+                    if (keys.contains(storageKey1)) {
+                        resultMap.put(storageKey1, serialize(key1, value1));
+                    }
+                    if (keys.contains(storageKey2)) {
+                        resultMap.put(storageKey2, serialize("not foo", value2));
+                    }
+                    callback.completed(resultMap);
+                    return cancellable;
+                });
 
         impl.getEntries(Arrays.asList(key1, key2), bulkCacheEntryCallback);
         final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor = ArgumentCaptor.forClass(Map.class);
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
index 5fd0b03..1cbbaae 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
@@ -35,7 +35,6 @@ import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
-import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
 import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
@@ -48,7 +47,6 @@ import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 @SuppressWarnings("boxing") // test code
@@ -143,14 +141,9 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.digestToStorageKey(key)).thenReturn("bar");
         when(impl.getForUpdateCAS("bar")).thenReturn(null);
 
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                Assert.assertThat(existing, CoreMatchers.nullValue());
-                return updatedValue;
-            }
-
+        impl.updateEntry(key, existing -> {
+            Assert.assertThat(existing, CoreMatchers.nullValue());
+            return updatedValue;
         });
 
         verify(impl).getForUpdateCAS("bar");
@@ -168,14 +161,7 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
         when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
 
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                return updatedValue;
-            }
-
-        });
+        impl.updateEntry(key, existing -> updatedValue);
 
         verify(impl).getForUpdateCAS("bar");
         verify(impl).getStorageObject("stuff");
@@ -193,14 +179,9 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo", existingValue));
         when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(true);
 
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                Assert.assertThat(existing, CoreMatchers.nullValue());
-                return updatedValue;
-            }
-
+        impl.updateEntry(key, existing -> {
+            Assert.assertThat(existing, CoreMatchers.nullValue());
+            return updatedValue;
         });
 
         verify(impl).getForUpdateCAS("bar");
@@ -219,14 +200,7 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.getStorageObject("stuff")).thenReturn(serialize(key, existingValue));
         when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, true);
 
-        impl.updateEntry(key, new HttpCacheCASOperation() {
-
-            @Override
-            public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                return updatedValue;
-            }
-
-        });
+        impl.updateEntry(key, existing -> updatedValue);
 
         verify(impl, Mockito.times(2)).getForUpdateCAS("bar");
         verify(impl, Mockito.times(2)).getStorageObject("stuff");
@@ -245,14 +219,7 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.updateCAS(ArgumentMatchers.eq("bar"), ArgumentMatchers.eq("stuff"), ArgumentMatchers.<byte[]>any())).thenReturn(false, false, false, true);
 
         try {
-            impl.updateEntry(key, new HttpCacheCASOperation() {
-
-                @Override
-                public HttpCacheEntry execute(final HttpCacheEntry existing) throws ResourceIOException {
-                    return updatedValue;
-                }
-
-            });
+            impl.updateEntry(key, existing -> updatedValue);
             Assert.fail("HttpCacheUpdateException expected");
         } catch (final HttpCacheUpdateException ignore) {
         }
@@ -274,20 +241,16 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
         when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
 
-        when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new Answer<Map<String, byte[]>>() {
-
-            @Override
-            public Map<String, byte[]> answer(final InvocationOnMock invocation) throws Throwable {
-                final Collection<String> keys = invocation.getArgument(0);
-                final Map<String, byte[]> resultMap = new HashMap<>();
-                if (keys.contains(storageKey1)) {
-                    resultMap.put(storageKey1, serialize(key1, value1));
-                }
-                if (keys.contains(storageKey2)) {
-                    resultMap.put(storageKey2, serialize(key2, value2));
-                }
-                return resultMap;
+        when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String, byte[]>>) invocation -> {
+            final Collection<String> keys = invocation.getArgument(0);
+            final Map<String, byte[]> resultMap = new HashMap<>();
+            if (keys.contains(storageKey1)) {
+                resultMap.put(storageKey1, serialize(key1, value1));
             }
+            if (keys.contains(storageKey2)) {
+                resultMap.put(storageKey2, serialize(key2, value2));
+            }
+            return resultMap;
         });
 
         final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
@@ -312,20 +275,16 @@ public class TestAbstractSerializingCacheStorage {
         when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
         when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
 
-        when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new Answer<Map<String, byte[]>>() {
-
-            @Override
-            public Map<String, byte[]> answer(final InvocationOnMock invocation) throws Throwable {
-                final Collection<String> keys = invocation.getArgument(0);
-                final Map<String, byte[]> resultMap = new HashMap<>();
-                if (keys.contains(storageKey1)) {
-                    resultMap.put(storageKey1, serialize(key1, value1));
-                }
-                if (keys.contains(storageKey2)) {
-                    resultMap.put(storageKey2, serialize("not foo", value2));
-                }
-                return resultMap;
+        when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String, byte[]>>) invocation -> {
+            final Collection<String> keys = invocation.getArgument(0);
+            final Map<String, byte[]> resultMap = new HashMap<>();
+            if (keys.contains(storageKey1)) {
+                resultMap.put(storageKey1, serialize(key1, value1));
+            }
+            if (keys.contains(storageKey2)) {
+                resultMap.put(storageKey2, serialize("not foo", value2));
             }
+            return resultMap;
         });
 
         final Map<String, HttpCacheEntry> entryMap = impl.getEntries(Arrays.asList(key1, key2));
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
index ace354b..66aa443 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
@@ -55,7 +55,7 @@ public class TestCachedHttpResponseGenerator {
 
     @Before
     public void setUp() {
-        entry = HttpTestUtils.makeCacheEntry(new HashMap<String, String>());
+        entry = HttpTestUtils.makeCacheEntry(new HashMap<>());
         request = HttpTestUtils.makeDefaultRequest();
         mockValidityPolicy = mock(CacheValidityPolicy.class);
         impl = new CachedHttpResponseGenerator(mockValidityPolicy);
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
index 171da3e..8ec3db6 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
@@ -170,7 +170,7 @@ public class TestCachingExec extends TestCachingExecChain {
         mockImplMethods(CALL_BACKEND);
         requestPolicyAllowsCaching(true);
         getCacheEntryReturns(null);
-        getVariantCacheEntriesReturns(new HashMap<String,Variant>());
+        getVariantCacheEntriesReturns(new HashMap<>());
 
         requestIsFatallyNonCompliant(null);
 
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
index 186b886..58ca6a0 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
@@ -34,7 +34,6 @@ import java.util.Map;
 import org.apache.hc.client5.http.cache.HeaderConstants;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.utils.DateUtils;
-import org.apache.hc.core5.function.Factory;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HeaderElement;
 import org.apache.hc.core5.http.HttpRequest;
@@ -53,14 +52,7 @@ public class TestConditionalRequestBuilder {
 
     @Before
     public void setUp() throws Exception {
-        impl = new ConditionalRequestBuilder<>(new Factory<HttpRequest, HttpRequest>() {
-
-            @Override
-            public HttpRequest create(final HttpRequest request) {
-                return BasicRequestBuilder.copy(request).build();
-            }
-
-        });
+        impl = new ConditionalRequestBuilder<>(request -> BasicRequestBuilder.copy(request).build());
         request = new BasicHttpRequest("GET", "/");
     }
 
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultAsyncCacheInvalidator.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultAsyncCacheInvalidator.java
index 73660e9..9d0589c 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultAsyncCacheInvalidator.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultAsyncCacheInvalidator.java
@@ -55,7 +55,6 @@ import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 
@@ -83,14 +82,9 @@ public class TestDefaultAsyncCacheInvalidator {
         now = new Date();
         tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
-        when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer(new Answer<String>() {
-
-            @Override
-            public String answer(final InvocationOnMock invocation) throws Throwable {
-                final URI uri = invocation.getArgument(0);
-                return HttpCacheSupport.normalize(uri).toASCIIString();
-            }
-
+        when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer((Answer<String>) invocation -> {
+            final URI uri = invocation.getArgument(0);
+            return HttpCacheSupport.normalize(uri).toASCIIString();
         });
 
         host = new HttpHost("foo.example.com");
@@ -124,7 +118,7 @@ public class TestDefaultAsyncCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key, mockEntry);
 
@@ -146,7 +140,7 @@ public class TestDefaultAsyncCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key, mockEntry);
 
@@ -168,7 +162,7 @@ public class TestDefaultAsyncCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key, mockEntry);
 
@@ -190,7 +184,7 @@ public class TestDefaultAsyncCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key, mockEntry);
 
@@ -226,7 +220,7 @@ public class TestDefaultAsyncCacheInvalidator {
         final HttpRequest request = new BasicHttpRequest("GET", uri);
 
         cacheEntryisForMethod("HEAD");
-        cacheEntryHasVariantMap(new HashMap<String, String>());
+        cacheEntryHasVariantMap(new HashMap<>());
         cacheReturnsEntryForUri(key, mockEntry);
 
         impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage, operationCallback);
@@ -679,16 +673,11 @@ public class TestDefaultAsyncCacheInvalidator {
     private void cacheReturnsEntryForUri(final String key, final HttpCacheEntry cacheEntry) {
         Mockito.when(mockStorage.getEntry(
                 ArgumentMatchers.eq(key),
-                ArgumentMatchers.<FutureCallback<HttpCacheEntry>>any())).thenAnswer(new Answer<Cancellable>() {
-
-            @Override
-            public Cancellable answer(final InvocationOnMock invocation) throws Throwable {
-                final FutureCallback<HttpCacheEntry> callback = invocation.getArgument(1);
-                callback.completed(cacheEntry);
-                return cancellable;
-            }
-
-        });
+                ArgumentMatchers.<FutureCallback<HttpCacheEntry>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
+                    final FutureCallback<HttpCacheEntry> callback = invocation.getArgument(1);
+                    callback.completed(cacheEntry);
+                    return cancellable;
+                });
     }
 
     private void cacheEntryisForMethod(final String httpMethod) {
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultCacheInvalidator.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultCacheInvalidator.java
index 1d2dee9..e97422c 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultCacheInvalidator.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestDefaultCacheInvalidator.java
@@ -53,7 +53,6 @@ import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.junit.MockitoJUnitRunner;
 import org.mockito.stubbing.Answer;
 
@@ -77,14 +76,9 @@ public class TestDefaultCacheInvalidator {
         now = new Date();
         tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
 
-        when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer(new Answer<String>() {
-
-            @Override
-            public String answer(final InvocationOnMock invocation) throws Throwable {
-                final URI uri = invocation.getArgument(0);
-                return HttpCacheSupport.normalize(uri).toASCIIString();
-            }
-
+        when(cacheKeyResolver.resolve(ArgumentMatchers.<URI>any())).thenAnswer((Answer<String>) invocation -> {
+            final URI uri = invocation.getArgument(0);
+            return HttpCacheSupport.normalize(uri).toASCIIString();
         });
 
         host = new HttpHost("foo.example.com");
@@ -118,7 +112,7 @@ public class TestDefaultCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key);
 
@@ -140,7 +134,7 @@ public class TestDefaultCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key);
 
@@ -162,7 +156,7 @@ public class TestDefaultCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key);
 
@@ -184,7 +178,7 @@ public class TestDefaultCacheInvalidator {
 
         final URI uri = new URI("http://foo.example.com:80/");
         final String key = uri.toASCIIString();
-        cacheEntryHasVariantMap(new HashMap<String,String>());
+        cacheEntryHasVariantMap(new HashMap<>());
 
         cacheReturnsEntryForUri(key);
 
@@ -220,7 +214,7 @@ public class TestDefaultCacheInvalidator {
         final HttpRequest request = new BasicHttpRequest("GET", uri);
 
         cacheEntryisForMethod("HEAD");
-        cacheEntryHasVariantMap(new HashMap<String, String>());
+        cacheEntryHasVariantMap(new HashMap<>());
         cacheReturnsEntryForUri(key);
 
         impl.flushCacheEntriesInvalidatedByRequest(host, request, cacheKeyResolver, mockStorage);
diff --git a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/memcached/TestPrefixKeyHashingScheme.java b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/memcached/TestPrefixKeyHashingScheme.java
index d89d286..a4b3e2f 100644
--- a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/memcached/TestPrefixKeyHashingScheme.java
+++ b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/memcached/TestPrefixKeyHashingScheme.java
@@ -41,12 +41,9 @@ public class TestPrefixKeyHashingScheme {
 
     @Before
     public void setUp() {
-        scheme = new KeyHashingScheme() {
-            @Override
-            public String hash(final String storageKey) {
-                assertEquals(KEY, storageKey);
-                return "hash";
-            }
+        scheme = storageKey -> {
+            assertEquals(KEY, storageKey);
+            return "hash";
         };
         impl = new PrefixKeyHashingScheme(PREFIX, scheme);
     }
diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
index 064943b..bc41434 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/Request.java
@@ -173,7 +173,7 @@ public class Request {
             builder = RequestConfig.custom();
         }
         if (this.useExpectContinue != null) {
-            builder.setExpectContinueEnabled(this.useExpectContinue);
+            builder.setExpectContinueEnabled(this.useExpectContinue.booleanValue());
         }
         if (this.connectTimeout != null) {
             builder.setConnectTimeout(this.connectTimeout);
diff --git a/httpclient5-fluent/src/test/java/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java b/httpclient5-fluent/src/test/java/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
index 65e4e7b..828391c 100644
--- a/httpclient5-fluent/src/test/java/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
+++ b/httpclient5-fluent/src/test/java/org/apache/hc/client5/http/examples/fluent/FluentResponseHandling.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.http.examples.fluent;
 
-import java.io.IOException;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 
@@ -37,11 +36,9 @@ import javax.xml.parsers.ParserConfigurationException;
 import org.apache.hc.client5.http.ClientProtocolException;
 import org.apache.hc.client5.http.HttpResponseException;
 import org.apache.hc.client5.http.fluent.Request;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 import org.w3c.dom.Document;
 import org.xml.sax.SAXException;
 
@@ -53,38 +50,33 @@ public class FluentResponseHandling {
 
     public static void main(final String... args)throws Exception {
         final Document result = Request.get("http://somehost/content")
-                .execute().handleResponse(new HttpClientResponseHandler<Document>() {
-
-            @Override
-            public Document handleResponse(final ClassicHttpResponse response) throws IOException {
-                final int status = response.getCode();
-                final HttpEntity entity = response.getEntity();
-                if (status >= HttpStatus.SC_REDIRECTION) {
-                    throw new HttpResponseException(status, response.getReasonPhrase());
-                }
-                if (entity == null) {
-                    throw new ClientProtocolException("Response contains no content");
-                }
-                final DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
-                try {
-                    final DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
-                    final ContentType contentType = ContentType.parseLenient(entity.getContentType());
-                    if (!contentType.equals(ContentType.APPLICATION_XML)) {
-                        throw new ClientProtocolException("Unexpected content type:" + contentType);
+                .execute().handleResponse(response -> {
+                    final int status = response.getCode();
+                    final HttpEntity entity = response.getEntity();
+                    if (status >= HttpStatus.SC_REDIRECTION) {
+                        throw new HttpResponseException(status, response.getReasonPhrase());
                     }
-                    Charset charset = contentType.getCharset();
-                    if (charset == null) {
-                        charset = StandardCharsets.ISO_8859_1;
+                    if (entity == null) {
+                        throw new ClientProtocolException("Response contains no content");
                     }
-                    return docBuilder.parse(entity.getContent(), charset.name());
-                } catch (final ParserConfigurationException ex) {
-                    throw new IllegalStateException(ex);
-                } catch (final SAXException ex) {
-                    throw new ClientProtocolException("Malformed XML document", ex);
-                }
-            }
-
-            });
+                    final DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
+                    try {
+                        final DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
+                        final ContentType contentType = ContentType.parseLenient(entity.getContentType());
+                        if (!contentType.equals(ContentType.APPLICATION_XML)) {
+                            throw new ClientProtocolException("Unexpected content type:" + contentType);
+                        }
+                        Charset charset = contentType.getCharset();
+                        if (charset == null) {
+                            charset = StandardCharsets.ISO_8859_1;
+                        }
+                        return docBuilder.parse(entity.getContent(), charset.name());
+                    } catch (final ParserConfigurationException ex) {
+                        throw new IllegalStateException(ex);
+                    } catch (final SAXException ex) {
+                        throw new ClientProtocolException("Malformed XML document", ex);
+                    }
+                });
         // Do something useful with the result
         System.out.println(result);
     }
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncClientAuthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncClientAuthentication.java
index a8b4613..307b82d 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncClientAuthentication.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncClientAuthentication.java
@@ -54,7 +54,6 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.testing.BasicTestAuthenticator;
 import org.apache.hc.client5.testing.auth.Authenticator;
 import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
@@ -89,14 +88,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Override
     public final HttpHost start() throws Exception {
-        return start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler requestHandler) {
-                return new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm"));
-            }
-
-        });
+        return start(requestHandler -> new AuthenticatingAsyncDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")));
     }
 
     public final HttpHost start(
@@ -150,14 +142,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationNoCreds() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(null);
@@ -179,14 +164,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationFailure() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -209,14 +187,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationSuccess() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -240,14 +211,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationWithEntitySuccess() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -271,14 +235,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationExpectationFailure() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -300,14 +257,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationExpectationSuccess() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
@@ -332,14 +282,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testBasicAuthenticationCredentialsCaching() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
 
         final AtomicLong count = new AtomicLong(0);
         setTargetAuthenticationStrategy(new DefaultAuthenticationStrategy() {
@@ -382,14 +325,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testAuthenticationUserinfoInRequestSuccess() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
@@ -407,14 +343,7 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testAuthenticationUserinfoInRequestFailure() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
 
         final HttpClientContext context = HttpClientContext.create();
@@ -431,31 +360,17 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start();
-        server.register("/thatway", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/thatway", () -> new AbstractSimpleServerExchangeHandler() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(
-                            final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
-                        final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_PERMANENTLY);
-                        response.addHeader(new BasicHeader("Location", target.getSchemeName() + "://test:test@" + target.toHostString() + "/"));
-                        return response;
-                    }
-                };
+            protected SimpleHttpResponse handle(
+                    final SimpleHttpRequest request, final HttpCoreContext context) throws HttpException {
+                final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_MOVED_PERMANENTLY);
+                response.addHeader(new BasicHeader("Location", target.getSchemeName() + "://test:test@" + target.toHostString() + "/"));
+                return response;
             }
-
         });
 
         final HttpClientContext context = HttpClientContext.create();
@@ -473,32 +388,18 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testReauthentication() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final TestCredentialsProvider credsProvider = new TestCredentialsProvider(
                 new UsernamePasswordCredentials("test", "test".toCharArray()));
 
         final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
-                .register("MyBasic", new AuthSchemeFactory() {
-
-                    @Override
-                    public AuthScheme create(final HttpContext context) {
-                        return new BasicScheme() {
+                .register("MyBasic", context -> new BasicScheme() {
 
-                            private static final long serialVersionUID = 1L;
+                    private static final long serialVersionUID = 1L;
 
-                            @Override
-                            public String getName() {
-                                return "MyBasic";
-                            }
-
-                        };
+                    @Override
+                    public String getName() {
+                        return "MyBasic";
                     }
 
                 })
@@ -520,19 +421,12 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
         };
 
         final HttpHost target = start(
-                new Decorator<AsyncServerExchangeHandler>() {
+                exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
 
                     @Override
-                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                        return new AuthenticatingAsyncDecorator(exchangeHandler, authenticator) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
-                                unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
-                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
-                            }
-
-                        };
+                    protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                        unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
+                        unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
                     }
 
                 });
@@ -558,27 +452,13 @@ public abstract class AbstractHttpAsyncClientAuthentication<T extends CloseableH
 
     @Test
     public void testAuthenticationFallback() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start(
-                new Decorator<AsyncServerExchangeHandler>() {
+                exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
                     @Override
-                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                        return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
-                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
-                            }
-
-                        };
+                    protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                        unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
                     }
 
                 });
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
index a7e8cd6..446151a 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncFundamentalsTest.java
@@ -185,19 +185,14 @@ public abstract class AbstractHttpAsyncFundamentalsTest<T extends CloseableHttpA
         final int threadNum = 5;
         final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
         for (int i = 0; i < threadNum; i++) {
-            executorService.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    if (!Thread.currentThread().isInterrupted()) {
-                        httpclient.execute(
-                                SimpleRequestBuilder.get()
-                                        .setHttpHost(target)
-                                        .setPath("/random/2048")
-                                        .build(), callback);
-                    }
+            executorService.execute(() -> {
+                if (!Thread.currentThread().isInterrupted()) {
+                    httpclient.execute(
+                            SimpleRequestBuilder.get()
+                                    .setHttpHost(target)
+                                    .setPath("/random/2048")
+                                    .build(), callback);
                 }
-
             });
         }
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
index 182a385..a961e61 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpAsyncRedirectsTest.java
@@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.async;
 
 import java.net.InetSocketAddress;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
@@ -46,9 +45,7 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.testing.OldPathRedirectResolver;
 import org.apache.hc.client5.testing.SSLTestContexts;
 import org.apache.hc.client5.testing.redirect.Redirect;
-import org.apache.hc.client5.testing.redirect.RedirectResolver;
 import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
@@ -100,16 +97,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect300() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
 
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
@@ -128,16 +118,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect301() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
                 SimpleRequestBuilder.get()
@@ -156,16 +139,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect302() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
                 SimpleRequestBuilder.get()
@@ -184,27 +160,15 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect302NoLocation() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.startsWith("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
-                                }
-                                return null;
-                            }
-
-                        });
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.startsWith("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
+                    }
+                    return null;
+                }));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
                 SimpleRequestBuilder.get()
@@ -222,16 +186,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect303() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
                 SimpleRequestBuilder.get()
@@ -250,20 +207,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect304() throws Exception {
-        server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(final SimpleHttpRequest request,
-                                                        final HttpCoreContext context) throws HttpException {
-                        return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
-                    }
-                };
-
+            protected SimpleHttpResponse handle(final SimpleHttpRequest request,
+                                                final HttpCoreContext context) throws HttpException {
+                return SimpleHttpResponse.create(HttpStatus.SC_NOT_MODIFIED, (String) null);
             }
         });
         final HttpHost target = start();
@@ -284,20 +233,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect305() throws Exception {
-        server.register("/oldlocation/*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/oldlocation/*", () -> new AbstractSimpleServerExchangeHandler() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(final SimpleHttpRequest request,
-                                                        final HttpCoreContext context) throws HttpException {
-                        return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
-                    }
-                };
-
+            protected SimpleHttpResponse handle(final SimpleHttpRequest request,
+                                                final HttpCoreContext context) throws HttpException {
+                return SimpleHttpResponse.create(HttpStatus.SC_USE_PROXY, (String) null);
             }
         });
         final HttpHost target = start();
@@ -318,16 +259,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testBasicRedirect307() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
                 SimpleRequestBuilder.get()
@@ -346,17 +280,10 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test(expected=ExecutionException.class)
     public void testMaxRedirectCheck() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
-                                HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+                        HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final RequestConfig config = RequestConfig.custom()
                 .setCircularRedirectsAllowed(true)
@@ -376,17 +303,10 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test(expected=ExecutionException.class)
     public void testCircularRedirect() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
-                                HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+                        HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final RequestConfig config = RequestConfig.custom()
                 .setCircularRedirectsAllowed(false)
@@ -407,16 +327,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testPostRedirect() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_TEMPORARY_REDIRECT)));
 
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
@@ -437,16 +350,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testPostRedirectSeeOther() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
 
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(
@@ -467,28 +373,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testRelativeRedirect() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.startsWith("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.startsWith("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
 
-        });
+                    }
+                    return null;
+                }));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -509,28 +403,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testRelativeRedirect2() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/random/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/random/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
 
-        });
+                    }
+                    return null;
+                }));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -551,28 +433,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test(expected=ExecutionException.class)
     public void testRejectBogusRedirectLocation() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/oldlocation/")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/oldlocation/")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
 
-        });
+                    }
+                    return null;
+                }));
 
         try {
             final Future<SimpleHttpResponse> future = httpclient.execute(
@@ -589,28 +459,16 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test(expected=ExecutionException.class)
     public void testRejectInvalidRedirectLocation() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/oldlocation/")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
 
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/oldlocation/")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
-
-        });
+                    }
+                    return null;
+                }));
 
         try {
             final Future<SimpleHttpResponse> future = httpclient.execute(
@@ -627,16 +485,9 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
 
     @Test
     public void testRedirectWithCookie() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final CookieStore cookieStore = new BasicCookieStore();
         final HttpClientContext context = HttpClientContext.create();
@@ -670,17 +521,12 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
         final H2TestServer secondServer = new H2TestServer(IOReactorConfig.DEFAULT,
                 scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
         try {
-            secondServer.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler get() {
-                    if (isReactive()) {
-                        return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
-                    } else {
-                        return new AsyncRandomHandler();
-                    }
+            secondServer.register("/random/*", () -> {
+                if (isReactive()) {
+                    return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
+                } else {
+                    return new AsyncRandomHandler();
                 }
-
             });
             final InetSocketAddress address2;
             if (version.greaterEquals(HttpVersion.HTTP_2)) {
@@ -690,31 +536,19 @@ public abstract class AbstractHttpAsyncRedirectsTest <T extends CloseableHttpAsy
             }
             final HttpHost redirectTarget = new HttpHost(scheme.name(), "localhost", address2.getPort());
 
-            final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                    return new RedirectingAsyncDecorator(
-                            exchangeHandler,
-                            new RedirectResolver() {
-
-                                @Override
-                                public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                    final String path = requestUri.getPath();
-                                    if (path.equals("/oldlocation")) {
-                                        final URI location = new URIBuilder(requestUri)
-                                                .setHttpHost(redirectTarget)
-                                                .setPath("/random/100")
-                                                .build();
-                                        return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
-                                    }
-                                    return null;
-                                }
-
-                            });
-                }
-
-            });
+            final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                    exchangeHandler,
+                    requestUri -> {
+                        final String path = requestUri.getPath();
+                        if (path.equals("/oldlocation")) {
+                            final URI location = new URIBuilder(requestUri)
+                                    .setHttpHost(redirectTarget)
+                                    .setPath("/random/100")
+                                    .build();
+                            return new Redirect(HttpStatus.SC_MOVED_PERMANENTLY, location.toString());
+                        }
+                        return null;
+                    }));
 
             final HttpClientContext context = HttpClientContext.create();
             final Future<SimpleHttpResponse> future = httpclient.execute(
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpReactiveFundamentalsTest.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpReactiveFundamentalsTest.java
index e4814f1..3fff89e 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpReactiveFundamentalsTest.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractHttpReactiveFundamentalsTest.java
@@ -67,7 +67,6 @@ import org.junit.Test;
 import org.reactivestreams.Publisher;
 
 import io.reactivex.Flowable;
-import io.reactivex.functions.Consumer;
 import io.reactivex.schedulers.Schedulers;
 
 public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHttpAsyncClient> extends AbstractIntegrationTestBase<T> {
@@ -163,12 +162,7 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
                     final Flowable<ByteBuffer> flowable = Flowable.fromPublisher(result.getBody())
                             .observeOn(Schedulers.io()); // Stream the data on an RxJava scheduler, not a client thread
                     ReactiveTestUtils.consumeStream(flowable)
-                            .subscribe(new Consumer<StreamDescription>() {
-                                @Override
-                                public void accept(final StreamDescription streamDescription) {
-                                    responses.add(streamDescription);
-                                }
-                            });
+                            .subscribe(responses::add);
                 }
                 @Override
                 public void failed(final Exception ex) { }
@@ -227,13 +221,10 @@ public abstract class AbstractHttpReactiveFundamentalsTest<T extends CloseableHt
         final int threadNum = 5;
         final ExecutorService executorService = Executors.newFixedThreadPool(threadNum);
         for (int i = 0; i < threadNum; i++) {
-            executorService.execute(new Runnable() {
-                @Override
-                public void run() {
-                    if (!Thread.currentThread().isInterrupted()) {
-                        final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
-                        httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
-                    }
+            executorService.execute(() -> {
+                if (!Thread.currentThread().isInterrupted()) {
+                    final ReactiveResponseConsumer consumer = new ReactiveResponseConsumer(callback);
+                    httpclient.execute(AsyncRequestBuilder.get(target + "/random/2048").build(), consumer, null);
                 }
             });
         }
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractServerTestBase.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractServerTestBase.java
index f281db2..03d974e 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractServerTestBase.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/AbstractServerTestBase.java
@@ -28,9 +28,7 @@
 package org.apache.hc.client5.testing.async;
 
 import org.apache.hc.client5.testing.SSLTestContexts;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.URIScheme;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.testing.nio.H2TestServer;
@@ -68,29 +66,19 @@ public abstract class AbstractServerTestBase {
                         .setSoTimeout(TIMEOUT)
                         .build(),
                     scheme == URIScheme.HTTPS ? SSLTestContexts.createServerSSLContext() : null, null, null);
-            server.register("/echo/*", new Supplier<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler get() {
-                    if (isReactive()) {
-                        return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
-                    } else {
-                        return new AsyncEchoHandler();
-                    }
+            server.register("/echo/*", () -> {
+                if (isReactive()) {
+                    return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
+                } else {
+                    return new AsyncEchoHandler();
                 }
-
             });
-            server.register("/random/*", new Supplier<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler get() {
-                    if (isReactive()) {
-                        return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
-                    } else {
-                        return new AsyncRandomHandler();
-                    }
+            server.register("/random/*", () -> {
+                if (isReactive()) {
+                    return new ReactiveServerExchangeHandler(new ReactiveRandomProcessor());
+                } else {
+                    return new AsyncRandomHandler();
                 }
-
             });
         }
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
index 4fc621a..67f3ca7 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncRedirects.java
@@ -44,7 +44,6 @@ import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
 import org.apache.hc.client5.testing.OldPathRedirectResolver;
 import org.apache.hc.client5.testing.SSLTestContexts;
 import org.apache.hc.client5.testing.redirect.Redirect;
-import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
@@ -54,7 +53,6 @@ import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
@@ -125,17 +123,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
 
     @Test
     public void testBasicRedirect300NoKeepAlive() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
-                                Redirect.ConnControl.CLOSE));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
+                        Redirect.ConnControl.CLOSE)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
                         .setHttpHost(target)
@@ -152,17 +143,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
 
     @Test
     public void testBasicRedirect301NoKeepAlive() throws Exception {
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
-                                Redirect.ConnControl.CLOSE));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
+                        Redirect.ConnControl.CLOSE)));
         final HttpClientContext context = HttpClientContext.create();
         final Future<SimpleHttpResponse> future = httpclient.execute(SimpleRequestBuilder.get()
                         .setHttpHost(target)
@@ -184,17 +168,10 @@ public class TestHttp1AsyncRedirects extends AbstractHttpAsyncRedirectsTest<Clos
         defaultHeaders.add(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client"));
         clientBuilder.setDefaultHeaders(defaultHeaders);
 
-        final HttpHost target = start(new Decorator<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                return new RedirectingAsyncDecorator(
-                        exchangeHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
-                                Redirect.ConnControl.CLOSE));
-            }
-
-        });
+        final HttpHost target = start(exchangeHandler -> new RedirectingAsyncDecorator(
+                exchangeHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY,
+                        Redirect.ConnControl.CLOSE)));
 
         final HttpClientContext context = HttpClientContext.create();
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncStatefulConnManagement.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncStatefulConnManagement.java
index 01607e5..fdbc72b 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncStatefulConnManagement.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1AsyncStatefulConnManagement.java
@@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.async;
 
 import java.util.concurrent.Future;
 
-import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.UserTokenHandler;
 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
@@ -41,7 +40,6 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBu
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
 import org.apache.hc.client5.testing.SSLTestContexts;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EndpointDetails;
 import org.apache.hc.core5.http.HttpException;
@@ -49,7 +47,6 @@ import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.config.Http1Config;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.protocol.BasicHttpContext;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
@@ -111,33 +108,19 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
 
     @Test
     public void testStatefulConnections() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(
-                            final SimpleHttpRequest request,
-                            final HttpCoreContext context) throws HttpException {
-                        final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
-                        response.setBody("Whatever", ContentType.TEXT_PLAIN);
-                        return response;
-                    }
-                };
+            protected SimpleHttpResponse handle(
+                    final SimpleHttpRequest request,
+                    final HttpCoreContext context) throws HttpException {
+                final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
+                response.setBody("Whatever", ContentType.TEXT_PLAIN);
+                return response;
             }
-
         });
 
-        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
-
-            @Override
-            public Object getUserToken(final HttpRoute route, final HttpContext context) {
-                return context.getAttribute("user");
-            }
-
-        };
+        final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
         clientBuilder.setUserTokenHandler(userTokenHandler);
         final HttpHost target = start();
 
@@ -239,36 +222,22 @@ public class TestHttp1AsyncStatefulConnManagement extends AbstractIntegrationTes
 
     @Test
     public void testRouteSpecificPoolRecylcing() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new AbstractSimpleServerExchangeHandler() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractSimpleServerExchangeHandler() {
-
-                    @Override
-                    protected SimpleHttpResponse handle(
-                            final SimpleHttpRequest request,
-                            final HttpCoreContext context) throws HttpException {
-                        final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
-                        response.setBody("Whatever", ContentType.TEXT_PLAIN);
-                        return response;
-                    }
-                };
+            protected SimpleHttpResponse handle(
+                    final SimpleHttpRequest request,
+                    final HttpCoreContext context) throws HttpException {
+                final SimpleHttpResponse response = new SimpleHttpResponse(HttpStatus.SC_OK);
+                response.setBody("Whatever", ContentType.TEXT_PLAIN);
+                return response;
             }
-
         });
 
         // This tests what happens when a maxed connection pool needs
         // to kill the last idle connection to a route to build a new
         // one to the same route.
-        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
-
-            @Override
-            public Object getUserToken(final HttpRoute route, final HttpContext context) {
-                return context.getAttribute("user");
-            }
-
-        };
+        final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
         clientBuilder.setUserTokenHandler(userTokenHandler);
 
         final HttpHost target = start();
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1ClientAuthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1ClientAuthentication.java
index 25764c5..4bfca6f 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1ClientAuthentication.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/async/TestHttp1ClientAuthentication.java
@@ -46,8 +46,6 @@ import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
 import org.apache.hc.client5.testing.BasicTestAuthenticator;
 import org.apache.hc.client5.testing.SSLTestContexts;
-import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.HeaderElements;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
@@ -58,7 +56,6 @@ import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.Http1Config;
 import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.impl.HttpProcessors;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.junit.Assert;
 import org.junit.Rule;
 import org.junit.Test;
@@ -136,29 +133,15 @@ public class TestHttp1ClientAuthentication extends AbstractHttpAsyncClientAuthen
 
     @Test
     public void testBasicAuthenticationSuccessNonPersistentConnection() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncEchoHandler();
-            }
-
-        });
+        server.register("*", AsyncEchoHandler::new);
         final HttpHost target = start(
                 HttpProcessors.server(),
-                new Decorator<AsyncServerExchangeHandler>() {
+                exchangeHandler -> new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
                     @Override
-                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler exchangeHandler) {
-                        return new AuthenticatingAsyncDecorator(exchangeHandler, new BasicTestAuthenticator("test:test", "test realm")) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
-                                unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-                            }
-                        };
+                    protected void customizeUnauthorizedResponse(final HttpResponse unauthorized) {
+                        unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
                     }
-
                 },
                 Http1Config.DEFAULT);
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
index 93c690a..0b227b2 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
@@ -27,7 +27,6 @@
 package org.apache.hc.client5.testing.fluent;
 
 import java.io.File;
-import java.io.IOException;
 import java.net.URI;
 import java.nio.charset.StandardCharsets;
 
@@ -35,17 +34,11 @@ import org.apache.hc.client5.http.ClientProtocolException;
 import org.apache.hc.client5.http.fluent.Content;
 import org.apache.hc.client5.http.fluent.Request;
 import org.apache.hc.client5.testing.sync.LocalServerTestBase;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpEntity;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
@@ -54,40 +47,22 @@ public class TestFluent extends LocalServerTestBase {
 
     @Before
     public void setUp() throws Exception {
-        this.server.registerHandler("/", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN));
-            }
-
-        });
-        this.server.registerHandler("/echo", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                HttpEntity responseEntity = null;
-                final HttpEntity requestEntity = request.getEntity();
-                if (requestEntity != null) {
-                    final String contentTypeStr = requestEntity.getContentType();
-                    final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
-                    if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
-                        responseEntity = new StringEntity(
-                                EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
-                    }
-                }
-                if (responseEntity == null) {
-                    responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
+        this.server.registerHandler("/", (request, response, context) -> response.setEntity(new StringEntity("All is well", ContentType.TEXT_PLAIN)));
+        this.server.registerHandler("/echo", (request, response, context) -> {
+            HttpEntity responseEntity = null;
+            final HttpEntity requestEntity = request.getEntity();
+            if (requestEntity != null) {
+                final String contentTypeStr = requestEntity.getContentType();
+                final ContentType contentType = contentTypeStr == null ? ContentType.DEFAULT_TEXT : ContentType.parse(contentTypeStr);
+                if (ContentType.TEXT_PLAIN.getMimeType().equals(contentType.getMimeType())) {
+                    responseEntity = new StringEntity(
+                            EntityUtils.toString(requestEntity), ContentType.TEXT_PLAIN);
                 }
-                response.setEntity(responseEntity);
             }
-
+            if (responseEntity == null) {
+                responseEntity = new StringEntity("echo", ContentType.TEXT_PLAIN);
+            }
+            response.setEntity(responseEntity);
         });
     }
 
@@ -155,15 +130,7 @@ public class TestFluent extends LocalServerTestBase {
             Request.get(baseURL + "/").execute().returnContent();
             Request.get(baseURL + "/").execute().returnResponse();
             Request.get(baseURL + "/").execute().discardContent();
-            Request.get(baseURL + "/").execute().handleResponse(new HttpClientResponseHandler<Object>() {
-
-                @Override
-                public Object handleResponse(
-                        final ClassicHttpResponse response) throws IOException {
-                    return null;
-                }
-
-            });
+            Request.get(baseURL + "/").execute().handleResponse(response -> null);
             final File tmpFile = File.createTempFile("test", ".bin");
             try {
                 Request.get(baseURL + "/").execute().saveContent(tmpFile);
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
index d463c32..1473062 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientAuthentication.java
@@ -39,11 +39,11 @@ import org.apache.hc.client5.http.auth.AuthCache;
 import org.apache.hc.client5.http.auth.AuthChallenge;
 import org.apache.hc.client5.http.auth.AuthScheme;
 import org.apache.hc.client5.http.auth.AuthSchemeFactory;
-import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.ChallengeType;
 import org.apache.hc.client5.http.auth.Credentials;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.classic.methods.HttpPost;
@@ -60,7 +60,6 @@ import org.apache.hc.client5.testing.BasicTestAuthenticator;
 import org.apache.hc.client5.testing.auth.Authenticator;
 import org.apache.hc.client5.testing.classic.AuthenticatingDecorator;
 import org.apache.hc.client5.testing.classic.EchoHandler;
-import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.EndpointDetails;
@@ -74,7 +73,6 @@ import org.apache.hc.core5.http.config.Registry;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.HttpProcessors;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpServerRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
 import org.apache.hc.core5.http.io.entity.StringEntity;
@@ -91,14 +89,7 @@ import org.junit.Test;
 public class TestClientAuthentication extends LocalServerTestBase {
 
     public HttpHost start(final Authenticator authenticator) throws IOException {
-        return super.start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new AuthenticatingDecorator(requestHandler, authenticator);
-            }
-
-        });
+        return super.start(null, requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator));
     }
 
     @Override
@@ -444,20 +435,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
     @Test
     public void testAuthenticationUserinfoInRedirectSuccess() throws Exception {
         this.server.registerHandler("/*", new EchoHandler());
-        this.server.registerHandler("/thatway", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
-                final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
-                final int port = socketAddress.getPort();
-                response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
-                response.addHeader(new BasicHeader("Location", "http://test:test@localhost:" + port + "/secure"));
-            }
-
+        this.server.registerHandler("/thatway", (request, response, context) -> {
+            final EndpointDetails endpoint = (EndpointDetails) context.getAttribute(HttpCoreContext.CONNECTION_ENDPOINT);
+            final InetSocketAddress socketAddress = (InetSocketAddress) endpoint.getLocalAddress();
+            final int port = socketAddress.getPort();
+            response.setCode(HttpStatus.SC_MOVED_PERMANENTLY);
+            response.addHeader(new BasicHeader("Location", "http://test:test@localhost:" + port + "/secure"));
         });
 
         final HttpHost target = start(new BasicTestAuthenticator("test:test", "test realm") {
@@ -594,18 +577,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
         final HttpHost target = start(
                 HttpProcessors.server(),
-                new Decorator<HttpServerRequestHandler>() {
+                requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
                     @Override
-                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                        return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
-                                unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-                            }
-
-                        };
+                    protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                        unauthorized.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
                     }
 
                 });
@@ -676,19 +652,12 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
         final HttpHost target = start(
                 HttpProcessors.server(),
-                new Decorator<HttpServerRequestHandler>() {
+                requestHandler -> new AuthenticatingDecorator(requestHandler, authenticator) {
 
                     @Override
-                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                        return new AuthenticatingDecorator(requestHandler, authenticator) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
-                                unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
-                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
-                            }
-
-                        };
+                    protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                        unauthorized.removeHeaders(HttpHeaders.WWW_AUTHENTICATE);
+                        unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, "MyBasic realm=\"test realm\"");
                     }
 
                 });
@@ -712,18 +681,11 @@ public class TestClientAuthentication extends LocalServerTestBase {
 
         final HttpHost target = start(
                 HttpProcessors.server(),
-                new Decorator<HttpServerRequestHandler>() {
+                requestHandler -> new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
 
                     @Override
-                    public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                        return new AuthenticatingDecorator(requestHandler, new BasicTestAuthenticator("test:test", "test realm")) {
-
-                            @Override
-                            protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
-                                unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
-                            }
-
-                        };
+                    protected void customizeUnauthorizedResponse(final ClassicHttpResponse unauthorized) {
+                        unauthorized.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.DIGEST + " realm=\"test realm\" invalid");
                     }
 
                 });
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
index d9be97e..21d1ae4 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestClientRequestExecution.java
@@ -38,7 +38,6 @@ import org.apache.hc.client5.http.protocol.RedirectLocations;
 import org.apache.hc.client5.http.utils.URIUtils;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
@@ -112,17 +111,7 @@ public class TestClientRequestExecution extends LocalServerTestBase {
     public void testAutoGeneratedHeaders() throws Exception {
         this.server.registerHandler("*", new SimpleService());
 
-        final HttpRequestInterceptor interceptor = new HttpRequestInterceptor() {
-
-            @Override
-            public void process(
-                    final HttpRequest request,
-                    final EntityDetails entityDetails,
-                    final HttpContext context) throws HttpException, IOException {
-                request.addHeader("my-header", "stuff");
-            }
-
-        };
+        final HttpRequestInterceptor interceptor = (request, entityDetails, context) -> request.addHeader("my-header", "stuff");
 
         final HttpRequestRetryStrategy requestRetryStrategy = new HttpRequestRetryStrategy() {
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
index 7223558..ff78c56 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestCookieVirtualHost.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.testing.sync;
 
-import java.io.IOException;
 import java.net.URI;
 import java.util.List;
 
@@ -36,15 +35,10 @@ import org.apache.hc.client5.http.cookie.Cookie;
 import org.apache.hc.client5.http.cookie.CookieStore;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.message.BasicHeader;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -55,51 +49,44 @@ public class TestCookieVirtualHost extends LocalServerTestBase {
 
     @Test
     public void testCookieMatchingWithVirtualHosts() throws Exception {
-        this.server.registerHandlerVirtual("app.mydomain.fr", "*", new HttpRequestHandler() {
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
-                switch (n) {
-                case 1:
-                    // Assert Host is forwarded from URI
-                    Assert.assertEquals("app.mydomain.fr", request
-                            .getFirstHeader("Host").getValue());
-
-                    response.setCode(HttpStatus.SC_OK);
-                    // Respond with Set-Cookie on virtual host domain. This
-                    // should be valid.
-                    response.addHeader(new BasicHeader("Set-Cookie",
-                            "name1=value1; domain=mydomain.fr; path=/"));
-                    break;
-
-                case 2:
-                    // Assert Host is still forwarded from URI
-                    Assert.assertEquals("app.mydomain.fr", request
-                            .getFirstHeader("Host").getValue());
-
-                    // We should get our cookie back.
-                    Assert.assertNotNull("We must get a cookie header",
-                            request.getFirstHeader("Cookie"));
-                    response.setCode(HttpStatus.SC_OK);
-                    break;
-
-                case 3:
-                    // Assert Host is forwarded from URI
-                    Assert.assertEquals("app.mydomain.fr", request
-                            .getFirstHeader("Host").getValue());
-
-                    response.setCode(HttpStatus.SC_OK);
-                    break;
-                default:
-                    Assert.fail("Unexpected value: " + n);
-                    break;
-                }
+        this.server.registerHandlerVirtual("app.mydomain.fr", "*", (request, response, context) -> {
+
+            final int n = Integer.parseInt(request.getFirstHeader("X-Request").getValue());
+            switch (n) {
+            case 1:
+                // Assert Host is forwarded from URI
+                Assert.assertEquals("app.mydomain.fr", request
+                        .getFirstHeader("Host").getValue());
+
+                response.setCode(HttpStatus.SC_OK);
+                // Respond with Set-Cookie on virtual host domain. This
+                // should be valid.
+                response.addHeader(new BasicHeader("Set-Cookie",
+                        "name1=value1; domain=mydomain.fr; path=/"));
+                break;
+
+            case 2:
+                // Assert Host is still forwarded from URI
+                Assert.assertEquals("app.mydomain.fr", request
+                        .getFirstHeader("Host").getValue());
+
+                // We should get our cookie back.
+                Assert.assertNotNull("We must get a cookie header",
+                        request.getFirstHeader("Cookie"));
+                response.setCode(HttpStatus.SC_OK);
+                break;
+
+            case 3:
+                // Assert Host is forwarded from URI
+                Assert.assertEquals("app.mydomain.fr", request
+                        .getFirstHeader("Host").getValue());
+
+                response.setCode(HttpStatus.SC_OK);
+                break;
+            default:
+                Assert.fail("Unexpected value: " + n);
+                break;
             }
-
         });
 
         final HttpHost target = start();
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
index 93b763d..fb929d5 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestMalformedServerResponse.java
@@ -33,7 +33,6 @@ import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
-import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
@@ -43,10 +42,8 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpServerConnection;
 import org.apache.hc.core5.http.io.HttpConnectionFactory;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -91,28 +88,10 @@ public class TestMalformedServerResponse {
     public void testNoContentResponseWithGarbage() throws Exception {
         try (final HttpServer server = ServerBootstrap.bootstrap()
                 .setConnectionFactory(new BrokenServerConnectionFactory())
-                .register("/nostuff", new HttpRequestHandler() {
-
-                    @Override
-                    public void handle(
-                            final ClassicHttpRequest request,
-                            final ClassicHttpResponse response,
-                            final HttpContext context) throws HttpException, IOException {
-                        response.setCode(HttpStatus.SC_NO_CONTENT);
-                    }
-
-                })
-                .register("/stuff", new HttpRequestHandler() {
-
-                    @Override
-                    public void handle(
-                            final ClassicHttpRequest request,
-                            final ClassicHttpResponse response,
-                            final HttpContext context) throws HttpException, IOException {
-                        response.setCode(HttpStatus.SC_OK);
-                        response.setEntity(new StringEntity("Some important stuff"));
-                    }
-
+                .register("/nostuff", (request, response, context) -> response.setCode(HttpStatus.SC_NO_CONTENT))
+                .register("/stuff", (request, response, context) -> {
+                    response.setCode(HttpStatus.SC_OK);
+                    response.setEntity(new StringEntity("Some important stuff"));
                 })
                 .create()) {
             server.start();
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
index 6cc7fd8..1b0c24d 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestRedirects.java
@@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.sync;
 
 import java.io.IOException;
 import java.net.URI;
-import java.net.URISyntaxException;
 import java.util.Collections;
 import java.util.Queue;
 import java.util.concurrent.ConcurrentLinkedQueue;
@@ -47,7 +46,6 @@ import org.apache.hc.client5.http.protocol.RedirectLocations;
 import org.apache.hc.client5.testing.OldPathRedirectResolver;
 import org.apache.hc.client5.testing.classic.RedirectingDecorator;
 import org.apache.hc.client5.testing.redirect.Redirect;
-import org.apache.hc.client5.testing.redirect.RedirectResolver;
 import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
@@ -58,7 +56,6 @@ import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.ProtocolException;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.HttpServerRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
@@ -76,16 +73,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect300() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES)));
 
         final HttpClientContext context = HttpClientContext.create();
         final HttpGet httpget = new HttpGet("/oldlocation/100");
@@ -106,17 +96,10 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect300NoKeepAlive() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
-                                Redirect.ConnControl.CLOSE));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MULTIPLE_CHOICES,
+                        Redirect.ConnControl.CLOSE)));
 
         final HttpClientContext context = HttpClientContext.create();
         final HttpGet httpget = new HttpGet("/oldlocation/100");
@@ -137,16 +120,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect301() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_PERMANENTLY)));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -172,16 +148,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect302() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -200,27 +169,15 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect302NoLocation() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.startsWith("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
-                                }
-                                return null;
-                            }
-
-                        });
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.startsWith("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, null);
+                    }
+                    return null;
+                }));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -238,16 +195,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect303() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_SEE_OTHER)));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -266,16 +216,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect304() throws Exception {
-        this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
-
-            @Override
-            public void handle(final ClassicHttpRequest request,
-                               final ClassicHttpResponse response,
-                               final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_NOT_MODIFIED);
-                response.addHeader(HttpHeaders.LOCATION, "/random/100");
-            }
-
+        this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
+            response.setCode(HttpStatus.SC_NOT_MODIFIED);
+            response.addHeader(HttpHeaders.LOCATION, "/random/100");
         });
 
         final HttpHost target = start();
@@ -301,16 +244,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect305() throws Exception {
-        this.server.registerHandler("/oldlocation/*", new HttpRequestHandler() {
-
-            @Override
-            public void handle(final ClassicHttpRequest request,
-                               final ClassicHttpResponse response,
-                               final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_USE_PROXY);
-                response.addHeader(HttpHeaders.LOCATION, "/random/100");
-            }
-
+        this.server.registerHandler("/oldlocation/*", (request, response, context) -> {
+            response.setCode(HttpStatus.SC_USE_PROXY);
+            response.addHeader(HttpHeaders.LOCATION, "/random/100");
         });
 
         final HttpHost target = start();
@@ -336,16 +272,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testBasicRedirect307() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_TEMPORARY_REDIRECT)));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -364,17 +293,10 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected = ClientProtocolException.class)
     public void testMaxRedirectCheck() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
-                                HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+                        HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final RequestConfig config = RequestConfig.custom()
                 .setCircularRedirectsAllowed(true)
@@ -393,17 +315,10 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected = ClientProtocolException.class)
     public void testCircularRedirect() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
-                                HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/circular-oldlocation/", "/circular-oldlocation/",
+                        HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final RequestConfig config = RequestConfig.custom()
                 .setCircularRedirectsAllowed(false)
@@ -421,16 +336,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testPostRedirectSeeOther() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/echo", HttpStatus.SC_SEE_OTHER)));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -452,28 +360,16 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRelativeRedirect() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.startsWith("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
 
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.startsWith("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/random/100");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
-
-        });
+                    }
+                    return null;
+                }));
         final HttpClientContext context = HttpClientContext.create();
 
         final HttpGet httpget = new HttpGet("/oldlocation/stuff");
@@ -491,28 +387,16 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRelativeRedirect2() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/random/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
-
-                                }
-                                return null;
-                            }
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/random/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "100");
 
-                        });
-            }
-
-        });
+                    }
+                    return null;
+                }));
 
         final HttpClientContext context = HttpClientContext.create();
 
@@ -532,28 +416,16 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected = ClientProtocolException.class)
     public void testRejectBogusRedirectLocation() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
 
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "xxx://bogus");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
-
-        });
+                    }
+                    return null;
+                }));
 
         final HttpGet httpget = new HttpGet("/oldlocation");
 
@@ -568,28 +440,16 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test(expected = ClientProtocolException.class)
     public void testRejectInvalidRedirectLocation() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new RedirectResolver() {
-
-                            @Override
-                            public Redirect resolve(final URI requestUri) throws URISyntaxException {
-                                final String path = requestUri.getPath();
-                                if (path.equals("/oldlocation")) {
-                                    return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
-
-                                }
-                                return null;
-                            }
-
-                        });
-            }
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                requestUri -> {
+                    final String path = requestUri.getPath();
+                    if (path.equals("/oldlocation")) {
+                        return new Redirect(HttpStatus.SC_MOVED_TEMPORARILY, "/newlocation/?p=I have spaces");
 
-        });
+                    }
+                    return null;
+                }));
 
         final HttpGet httpget = new HttpGet("/oldlocation");
 
@@ -603,16 +463,9 @@ public class TestRedirects extends LocalServerTestBase {
 
     @Test
     public void testRedirectWithCookie() throws Exception {
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final CookieStore cookieStore = new BasicCookieStore();
 
@@ -644,16 +497,9 @@ public class TestRedirects extends LocalServerTestBase {
     public void testDefaultHeadersRedirect() throws Exception {
         this.clientBuilder.setDefaultHeaders(Collections.singletonList(new BasicHeader(HttpHeaders.USER_AGENT, "my-test-client")));
 
-        final HttpHost target = start(null, new Decorator<HttpServerRequestHandler>() {
-
-            @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler requestHandler) {
-                return new RedirectingDecorator(
-                        requestHandler,
-                        new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY));
-            }
-
-        });
+        final HttpHost target = start(null, requestHandler -> new RedirectingDecorator(
+                requestHandler,
+                new OldPathRedirectResolver("/oldlocation", "/random", HttpStatus.SC_MOVED_TEMPORARILY)));
 
         final HttpClientContext context = HttpClientContext.create();
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java
index 65e47d9..31b32b0 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestSSLSocketFactory.java
@@ -33,13 +33,10 @@ import java.net.Socket;
 import java.security.KeyManagementException;
 import java.security.KeyStoreException;
 import java.security.NoSuchAlgorithmException;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 
 import javax.net.ssl.HostnameVerifier;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
-import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.SSLSocket;
 
@@ -49,7 +46,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
 import org.apache.hc.client5.http.ssl.TrustAllStrategy;
 import org.apache.hc.client5.http.ssl.TrustSelfSignedStrategy;
 import org.apache.hc.client5.testing.SSLTestContexts;
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
@@ -190,14 +186,7 @@ public class TestSSLSocketFactory {
         // @formatter:off
         this.server = ServerBootstrap.bootstrap()
                 .setSslContext(SSLTestContexts.createServerSSLContext())
-                .setSslSetupHandler(new Callback<SSLParameters>() {
-
-                    @Override
-                    public void execute(final SSLParameters sslParameters) {
-                        sslParameters.setNeedClientAuth(true);
-                    }
-
-                })
+                .setSslSetupHandler(sslParameters -> sslParameters.setNeedClientAuth(true))
                 .create();
         // @formatter:on
         this.server.start();
@@ -252,14 +241,7 @@ public class TestSSLSocketFactory {
 
     @Test
     public void testSSLTrustVerificationOverrideWithCustsom() throws Exception {
-        final TrustStrategy trustStrategy = new TrustStrategy() {
-
-            @Override
-            public boolean isTrusted(final X509Certificate[] chain, final String authType) throws CertificateException {
-                return chain.length == 1;
-            }
-
-        };
+        final TrustStrategy trustStrategy = (chain, authType) -> chain.length == 1;
         testSSLTrustVerificationOverride(trustStrategy);
     }
 
@@ -307,14 +289,7 @@ public class TestSSLSocketFactory {
         // @formatter:off
         this.server = ServerBootstrap.bootstrap()
                 .setSslContext(SSLTestContexts.createServerSSLContext())
-                .setSslSetupHandler(new Callback<SSLParameters>() {
-
-                    @Override
-                    public void execute(final SSLParameters sslParameters) {
-                        sslParameters.setProtocols(new String[] {"SSLv3"});
-                    }
-
-                })
+                .setSslSetupHandler(sslParameters -> sslParameters.setProtocols(new String[] {"SSLv3"}))
                 .create();
         // @formatter:on
         this.server.start();
@@ -362,14 +337,7 @@ public class TestSSLSocketFactory {
         // @formatter:off
         this.server = ServerBootstrap.bootstrap()
                 .setSslContext(SSLTestContexts.createServerSSLContext())
-                .setSslSetupHandler(new Callback<SSLParameters>() {
-
-                    @Override
-                    public void execute(final SSLParameters sslParameters) {
-                        sslParameters.setProtocols(new String[] {cipherSuite});
-                    }
-
-                })
+                .setSslSetupHandler(sslParameters -> sslParameters.setProtocols(new String[] {cipherSuite}))
                 .create();
         // @formatter:on
         this.server.start();
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
index 418550f..1cf5a27 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestStatefulConnManagement.java
@@ -28,7 +28,6 @@ package org.apache.hc.client5.testing.sync;
 
 import java.io.IOException;
 
-import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.UserTokenHandler;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
@@ -80,14 +79,9 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
         this.connManager.setMaxTotal(workerCount);
         this.connManager.setDefaultMaxPerRoute(workerCount);
 
-        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
-
-            @Override
-            public Object getUserToken(final HttpRoute route, final HttpContext context) {
-                final String id = (String) context.getAttribute("user");
-                return id;
-            }
-
+        final UserTokenHandler userTokenHandler = (route, context) -> {
+            final String id = (String) context.getAttribute("user");
+            return id;
         };
         this.clientBuilder.setUserTokenHandler(userTokenHandler);
 
@@ -199,14 +193,7 @@ public class TestStatefulConnManagement extends LocalServerTestBase {
         this.connManager.setMaxTotal(maxConn);
         this.connManager.setDefaultMaxPerRoute(maxConn);
 
-        final UserTokenHandler userTokenHandler = new UserTokenHandler() {
-
-            @Override
-            public Object getUserToken(final HttpRoute route, final HttpContext context) {
-                return context.getAttribute("user");
-            }
-
-        };
+        final UserTokenHandler userTokenHandler = (route, context) -> context.getAttribute("user");
 
         this.clientBuilder.setUserTokenHandler(userTokenHandler);
 
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
index 71c47bc..58241d3 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/sync/TestWindowsNegotiateScheme.java
@@ -26,28 +26,20 @@
  */
 package org.apache.hc.client5.testing.sync;
 
-import java.io.IOException;
-
-import org.apache.hc.client5.http.auth.AuthScheme;
 import org.apache.hc.client5.http.auth.AuthSchemeFactory;
-import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.auth.StandardAuthScheme;
+import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.apache.hc.client5.http.impl.classic.HttpClientBuilder;
 import org.apache.hc.client5.http.impl.win.WinHttpClients;
 import org.apache.hc.client5.http.impl.win.WindowsNegotiateSchemeGetTokenFail;
-import org.apache.hc.core5.http.ClassicHttpRequest;
-import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.config.Registry;
 import org.apache.hc.core5.http.config.RegistryBuilder;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.junit.Assume;
 import org.junit.Test;
 
@@ -58,17 +50,9 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
 
     @Test(timeout=30000) // this timeout (in ms) needs to be extended if you're actively debugging the code
     public void testNoInfiniteLoopOnSPNOutsideDomain() throws Exception {
-        this.server.registerHandler("/", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
-                response.setCode(HttpStatus.SC_UNAUTHORIZED);
-            }
-
+        this.server.registerHandler("/", (request, response, context) -> {
+            response.addHeader(HttpHeaders.WWW_AUTHENTICATE, StandardAuthScheme.SPNEGO);
+            response.setCode(HttpStatus.SC_UNAUTHORIZED);
         });
         Assume.assumeTrue("Test can only be run on Windows", WinHttpClients.isWinAuthAvailable());
 
@@ -81,12 +65,7 @@ public class TestWindowsNegotiateScheme extends LocalServerTestBase {
         // you can contact the server that authenticated you." is associated with SEC_E_DOWNGRADE_DETECTED.
 
         final Registry<AuthSchemeFactory> authSchemeRegistry = RegistryBuilder.<AuthSchemeFactory>create()
-            .register(StandardAuthScheme.SPNEGO, new AuthSchemeFactory() {
-                @Override
-                public AuthScheme create(final HttpContext context) {
-                    return new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com");
-                }
-            }).build();
+            .register(StandardAuthScheme.SPNEGO, context -> new WindowsNegotiateSchemeGetTokenFail(StandardAuthScheme.SPNEGO, "HTTP/example.com")).build();
         final CloseableHttpClient customClient = HttpClientBuilder.create()
                 .setDefaultAuthSchemeRegistry(authSchemeRegistry).build();
 
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/Header.java b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/Header.java
index 3b737cf..149a560 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/Header.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/Header.java
@@ -55,11 +55,7 @@ public class Header implements Iterable<MimeField> {
             return;
         }
         final String key = field.getName().toLowerCase(Locale.ROOT);
-        List<MimeField> values = this.fieldMap.get(key);
-        if (values == null) {
-            values = new LinkedList<>();
-            this.fieldMap.put(key, values);
-        }
+        final List<MimeField> values = this.fieldMap.computeIfAbsent(key, k -> new LinkedList<>());
         values.add(field);
         this.fields.add(field);
     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/IdleConnectionEvictor.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/IdleConnectionEvictor.java
index 2950c2b..eeddc9a 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/IdleConnectionEvictor.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/IdleConnectionEvictor.java
@@ -54,23 +54,20 @@ public final class IdleConnectionEvictor {
         Args.notNull(connectionManager, "Connection manager");
         this.threadFactory = threadFactory != null ? threadFactory : new DefaultThreadFactory("idle-connection-evictor", true);
         final TimeValue localSleepTime = sleepTime != null ? sleepTime : TimeValue.ofSeconds(5);
-        this.thread = this.threadFactory.newThread(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    while (!Thread.currentThread().isInterrupted()) {
-                        localSleepTime.sleep();
-                        connectionManager.closeExpired();
-                        if (maxIdleTime != null) {
-                            connectionManager.closeIdle(maxIdleTime);
-                        }
+        this.thread = this.threadFactory.newThread(() -> {
+            try {
+                while (!Thread.currentThread().isInterrupted()) {
+                    localSleepTime.sleep();
+                    connectionManager.closeExpired();
+                    if (maxIdleTime != null) {
+                        connectionManager.closeIdle(maxIdleTime);
                     }
-                } catch (final InterruptedException ex) {
-                    Thread.currentThread().interrupt();
-                } catch (final Exception ex) {
                 }
-
+            } catch (final InterruptedException ex) {
+                Thread.currentThread().interrupt();
+            } catch (final Exception ex) {
             }
+
         });
     }
 
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Operations.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Operations.java
index da15e56..afa232b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Operations.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/Operations.java
@@ -41,14 +41,7 @@ import org.apache.hc.core5.concurrent.Cancellable;
  */
 public final class Operations {
 
-    private final static Cancellable NOOP_CANCELLABLE = new Cancellable() {
-
-        @Override
-        public boolean cancel() {
-            return false;
-        }
-
-    };
+    private final static Cancellable NOOP_CANCELLABLE = () -> false;
 
     /**
      * This class represents a {@link Future} in the completed state with a fixed result.
@@ -115,14 +108,7 @@ public final class Operations {
         if (future instanceof Cancellable) {
             return (Cancellable) future;
         }
-        return new Cancellable() {
-
-            @Override
-            public boolean cancel() {
-                return future.cancel(true);
-            }
-
-        };
+        return () -> future.cancel(true);
     }
 
 }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
index e3532c8..32c1020 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AbstractHttpAsyncClientBase.java
@@ -66,13 +66,7 @@ abstract class AbstractHttpAsyncClientBase extends CloseableHttpAsyncClient {
     @Override
     public final void start() {
         if (status.compareAndSet(Status.READY, Status.RUNNING)) {
-            executorService.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    ioReactor.start();
-                }
-            });
+            executorService.execute(ioReactor::start);
         }
     }
 
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncExecChainElement.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncExecChainElement.java
index 0bcbe0c..1e90995 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncExecChainElement.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/AsyncExecChainElement.java
@@ -51,19 +51,7 @@ class AsyncExecChainElement {
             final AsyncEntityProducer entityProducer,
             final AsyncExecChain.Scope scope,
             final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
-        handler.execute(request, entityProducer, scope, new AsyncExecChain() {
-
-            @Override
-            public void proceed(
-                    final HttpRequest request,
-                    final AsyncEntityProducer entityProducer,
-                    final AsyncExecChain.Scope scope,
-                    final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
-                next.execute(request, entityProducer, scope, asyncExecCallback);
-            }
-
-        }, asyncExecCallback);
-
+        handler.execute(request, entityProducer, scope, next != null ? next::execute : null, asyncExecCallback);
     }
 
     @Override
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
index 693af2f..6c2a0dc 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/H2AsyncClientBuilder.java
@@ -29,7 +29,6 @@ package org.apache.hc.client5.http.impl.async;
 
 import java.io.Closeable;
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
@@ -44,8 +43,8 @@ import org.apache.hc.client5.http.HttpRequestRetryStrategy;
 import org.apache.hc.client5.http.SchemePortResolver;
 import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.auth.AuthSchemeFactory;
-import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.cookie.BasicCookieStore;
 import org.apache.hc.client5.http.cookie.CookieSpecFactory;
@@ -75,24 +74,16 @@ import org.apache.hc.client5.http.routing.HttpRoutePlanner;
 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
 import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.concurrent.DefaultThreadFactory;
-import org.apache.hc.core5.function.Callback;
-import org.apache.hc.core5.function.Resolver;
 import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpRequestInterceptor;
 import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.config.NamedElementChain;
 import org.apache.hc.core5.http.config.RegistryBuilder;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
 import org.apache.hc.core5.http.protocol.RequestTargetHost;
@@ -107,7 +98,6 @@ import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.VersionInfo;
@@ -710,14 +700,7 @@ public class H2AsyncClientBuilder {
         final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
         final IOEventHandlerFactory ioEventHandlerFactory = new H2AsyncClientEventHandlerFactory(
                 new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
-                new HandlerFactory<AsyncPushConsumer>() {
-
-                    @Override
-                    public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
-                        return pushConsumerRegistry.get(request);
-                    }
-
-                },
+                (request, context) -> pushConsumerRegistry.get(request),
                 h2Config != null ? h2Config : H2Config.DEFAULT,
                 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT);
         final DefaultConnectingIOReactor ioReactor = new DefaultConnectingIOReactor(
@@ -727,14 +710,7 @@ public class H2AsyncClientBuilder {
                 LoggingIOSessionDecorator.INSTANCE,
                 LoggingExceptionCallback.INSTANCE,
                 null,
-                new Callback<IOSession>() {
-
-                    @Override
-                    public void execute(final IOSession ioSession) {
-                        ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
-                    }
-
-                });
+                ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE));
 
         if (execInterceptors != null) {
             for (final ExecInterceptorEntry entry: execInterceptors) {
@@ -808,14 +784,7 @@ public class H2AsyncClientBuilder {
         }
 
         final MultihomeConnectionInitiator connectionInitiator = new MultihomeConnectionInitiator(ioReactor, dnsResolver);
-        final H2ConnPool connPool = new H2ConnPool(connectionInitiator, new Resolver<HttpHost, InetSocketAddress>() {
-
-            @Override
-            public InetSocketAddress resolve(final HttpHost host) {
-                return null;
-            }
-
-        }, tlsStrategyCopy);
+        final H2ConnPool connPool = new H2ConnPool(connectionInitiator, host -> null, tlsStrategyCopy);
 
         List<Closeable> closeablesCopy = closeables != null ? new ArrayList<>(closeables) : null;
         if (closeablesCopy == null) {
@@ -824,14 +793,7 @@ public class H2AsyncClientBuilder {
         if (evictIdleConnections) {
             final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(connPool,
                     maxIdleTime != null ? maxIdleTime : TimeValue.ofSeconds(30L));
-            closeablesCopy.add(new Closeable() {
-
-                @Override
-                public void close() throws IOException {
-                    connectionEvictor.shutdown();
-                }
-
-            });
+            closeablesCopy.add(connectionEvictor::shutdown);
             connectionEvictor.start();
         }
         closeablesCopy.add(connPool);
@@ -852,12 +814,7 @@ public class H2AsyncClientBuilder {
     }
 
     private static String getProperty(final String key, final String defaultValue) {
-        return AccessController.doPrivileged(new PrivilegedAction<String>() {
-            @Override
-            public String run() {
-                return System.getProperty(key, defaultValue);
-            }
-        });
+        return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key, defaultValue));
     }
 
     static class IdleConnectionEvictor implements Closeable {
@@ -865,20 +822,17 @@ public class H2AsyncClientBuilder {
         private final Thread thread;
 
         public IdleConnectionEvictor(final H2ConnPool connPool, final TimeValue maxIdleTime) {
-            this.thread = new DefaultThreadFactory("idle-connection-evictor", true).newThread(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        while (!Thread.currentThread().isInterrupted()) {
-                            maxIdleTime.sleep();
-                            connPool.closeIdle(maxIdleTime);
-                        }
-                    } catch (final InterruptedException ex) {
-                        Thread.currentThread().interrupt();
-                    } catch (final Exception ex) {
+            this.thread = new DefaultThreadFactory("idle-connection-evictor", true).newThread(() -> {
+                try {
+                    while (!Thread.currentThread().isInterrupted()) {
+                        maxIdleTime.sleep();
+                        connPool.closeIdle(maxIdleTime);
                     }
-
+                } catch (final InterruptedException ex) {
+                    Thread.currentThread().interrupt();
+                } catch (final Exception ex) {
                 }
+
             });
         }
 
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
index 612f35d..18c100e 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClientBuilder.java
@@ -28,7 +28,6 @@
 package org.apache.hc.client5.http.impl.async;
 
 import java.io.Closeable;
-import java.io.IOException;
 import java.net.ProxySelector;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
@@ -45,8 +44,8 @@ import org.apache.hc.client5.http.SchemePortResolver;
 import org.apache.hc.client5.http.UserTokenHandler;
 import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.auth.AuthSchemeFactory;
-import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.config.RequestConfig;
 import org.apache.hc.client5.http.cookie.BasicCookieStore;
 import org.apache.hc.client5.http.cookie.CookieSpecFactory;
@@ -85,11 +84,8 @@ import org.apache.hc.core5.concurrent.DefaultThreadFactory;
 import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.Header;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpRequestInterceptor;
-import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.Http1Config;
@@ -97,11 +93,8 @@ import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.config.NamedElementChain;
 import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
 import org.apache.hc.core5.http.protocol.RequestTargetHost;
@@ -117,7 +110,6 @@ import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.VersionInfo;
@@ -857,12 +849,7 @@ public class HttpAsyncClientBuilder {
             if (proxy != null) {
                 routePlannerCopy = new DefaultProxyRoutePlanner(proxy, schemePortResolverCopy);
             } else if (systemProperties) {
-                final ProxySelector defaultProxySelector = AccessController.doPrivileged(new PrivilegedAction<ProxySelector>() {
-                    @Override
-                    public ProxySelector run() {
-                        return ProxySelector.getDefault();
-                    }
-                });
+                final ProxySelector defaultProxySelector = AccessController.doPrivileged((PrivilegedAction<ProxySelector>) ProxySelector::getDefault);
                 routePlannerCopy = new SystemDefaultRoutePlanner(
                         schemePortResolverCopy, defaultProxySelector);
             } else {
@@ -890,14 +877,7 @@ public class HttpAsyncClientBuilder {
                 if (connManagerCopy instanceof ConnPoolControl) {
                     final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
                             maxIdleTime,  maxIdleTime);
-                    closeablesCopy.add(new Closeable() {
-
-                        @Override
-                        public void close() throws IOException {
-                            connectionEvictor.shutdown();
-                        }
-
-                    });
+                    closeablesCopy.add(connectionEvictor::shutdown);
                     connectionEvictor.start();
                 }
             }
@@ -910,13 +890,7 @@ public class HttpAsyncClientBuilder {
                 if ("true".equalsIgnoreCase(s)) {
                     reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
                 } else {
-                    reuseStrategyCopy = new ConnectionReuseStrategy() {
-                        @Override
-                        public boolean keepAlive(
-                                final HttpRequest request, final HttpResponse response, final HttpContext context) {
-                            return false;
-                        }
-                    };
+                    reuseStrategyCopy = (request, response, context) -> false;
                 }
             } else {
                 reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
@@ -925,14 +899,7 @@ public class HttpAsyncClientBuilder {
         final AsyncPushConsumerRegistry pushConsumerRegistry = new AsyncPushConsumerRegistry();
         final IOEventHandlerFactory ioEventHandlerFactory = new HttpAsyncClientEventHandlerFactory(
                 new DefaultHttpProcessor(new H2RequestContent(), new H2RequestTargetHost(), new H2RequestConnControl()),
-                new HandlerFactory<AsyncPushConsumer>() {
-
-                    @Override
-                    public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
-                        return pushConsumerRegistry.get(request);
-                    }
-
-                },
+                (request, context) -> pushConsumerRegistry.get(request),
                 versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
                 h2Config != null ? h2Config : H2Config.DEFAULT,
                 h1Config != null ? h1Config : Http1Config.DEFAULT,
@@ -945,14 +912,7 @@ public class HttpAsyncClientBuilder {
                 LoggingIOSessionDecorator.INSTANCE,
                 ioReactorExceptionCallback != null ? ioReactorExceptionCallback : LoggingExceptionCallback.INSTANCE,
                 null,
-                new Callback<IOSession>() {
-
-                    @Override
-                    public void execute(final IOSession ioSession) {
-                        ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
-                    }
-
-                });
+                ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE));
 
         if (execInterceptors != null) {
             for (final ExecInterceptorEntry entry: execInterceptors) {
@@ -1033,12 +993,7 @@ public class HttpAsyncClientBuilder {
     }
 
     private String getProperty(final String key, final String defaultValue) {
-        return AccessController.doPrivileged(new PrivilegedAction<String>() {
-            @Override
-            public String run() {
-                return System.getProperty(key, defaultValue);
-            }
-        });
+        return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key, defaultValue));
     }
 
 }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
index 9c38f24..3e07327 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/HttpAsyncClients.java
@@ -35,16 +35,11 @@ import org.apache.hc.client5.http.impl.nio.PoolingAsyncClientConnectionManagerBu
 import org.apache.hc.client5.http.nio.AsyncClientConnectionManager;
 import org.apache.hc.client5.http.ssl.DefaultClientTlsStrategy;
 import org.apache.hc.core5.concurrent.DefaultThreadFactory;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.config.CharCodingConfig;
 import org.apache.hc.core5.http.config.Http1Config;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http.protocol.RequestUserAgent;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
@@ -157,14 +152,7 @@ public final class HttpAsyncClients {
         return createMinimalHttpAsyncClientImpl(
                 new HttpAsyncClientEventHandlerFactory(
                         createMinimalProtocolProcessor(),
-                        new HandlerFactory<AsyncPushConsumer>() {
-
-                            @Override
-                            public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
-                                return pushConsumerRegistry.get(request);
-                            }
-
-                        },
+                        (request, context) -> pushConsumerRegistry.get(request),
                         versionPolicy,
                         h2Config,
                         h1Config,
@@ -252,14 +240,7 @@ public final class HttpAsyncClients {
         return createMinimalHttp2AsyncClientImpl(
                 new H2AsyncClientEventHandlerFactory(
                         createMinimalProtocolProcessor(),
-                        new HandlerFactory<AsyncPushConsumer>() {
-
-                            @Override
-                            public AsyncPushConsumer create(final HttpRequest request, final HttpContext context) throws HttpException {
-                                return pushConsumerRegistry.get(request);
-                            }
-
-                        },
+                        (request, context) -> pushConsumerRegistry.get(request),
                         h2Config,
                         CharCodingConfig.DEFAULT),
                 pushConsumerRegistry,
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
index 6dac275..ae081db 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalAbstractHttpAsyncClient.java
@@ -70,7 +70,6 @@ import org.apache.hc.core5.http.nio.AsyncRequestProducer;
 import org.apache.hc.core5.http.nio.AsyncResponseConsumer;
 import org.apache.hc.core5.http.nio.DataStreamChannel;
 import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.nio.RequestChannel;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.support.BasicRequestBuilder;
 import org.apache.hc.core5.io.CloseMode;
@@ -176,181 +175,160 @@ abstract class InternalAbstractHttpAsyncClient extends AbstractHttpAsyncClientBa
                 throw new CancellationException("Request execution cancelled");
             }
             final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
-            requestProducer.sendRequest(new RequestChannel() {
+            requestProducer.sendRequest((request, entityDetails, c) -> {
 
-                @Override
-                public void sendRequest(
-                        final HttpRequest request,
-                        final EntityDetails entityDetails,
-                        final HttpContext context) throws HttpException, IOException {
-
-                    RequestConfig requestConfig = null;
-                    if (request instanceof Configurable) {
-                        requestConfig = ((Configurable) request).getConfig();
-                    }
-                    if (requestConfig != null) {
-                        clientContext.setRequestConfig(requestConfig);
-                    }
-                    final HttpRoute route = determineRoute(
-                            httpHost != null ? httpHost : RoutingSupport.determineHost(request),
-                            clientContext);
-                    final String exchangeId = ExecSupport.getNextExchangeId();
-                    if (LOG.isDebugEnabled()) {
-                        LOG.debug("{} preparing request execution", exchangeId);
-                    }
-                    final AsyncExecRuntime execRuntime = createAsyncExecRuntime(pushHandlerFactory);
-
-                    clientContext.setExchangeId(exchangeId);
-                    setupContext(clientContext);
-
-                    final AsyncExecChain.Scheduler scheduler = new AsyncExecChain.Scheduler() {
-
-                        @Override
-                        public void scheduleExecution(final HttpRequest request,
-                                                      final AsyncEntityProducer entityProducer,
-                                                      final AsyncExecChain.Scope scope,
-                                                      final AsyncExecCallback asyncExecCallback,
-                                                      final TimeValue delay) {
-                            executeScheduled(request, entityProducer, scope, asyncExecCallback, delay);
-                        }
-
-                    };
-
-                    final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
-                            clientContext, execRuntime, scheduler, new AtomicInteger(1));
-                    final AtomicBoolean outputTerminated = new AtomicBoolean(false);
-                    executeImmediate(
-                            BasicRequestBuilder.copy(request).build(),
-                            entityDetails != null ? new AsyncEntityProducer() {
-
-                                @Override
-                                public void releaseResources() {
-                                    requestProducer.releaseResources();
-                                }
-
-                                @Override
-                                public void failed(final Exception cause) {
-                                    requestProducer.failed(cause);
-                                }
-
-                                @Override
-                                public boolean isRepeatable() {
-                                    return requestProducer.isRepeatable();
-                                }
-
-                                @Override
-                                public long getContentLength() {
-                                    return entityDetails.getContentLength();
-                                }
-
-                                @Override
-                                public String getContentType() {
-                                    return entityDetails.getContentType();
-                                }
-
-                                @Override
-                                public String getContentEncoding() {
-                                    return entityDetails.getContentEncoding();
-                                }
-
-                                @Override
-                                public boolean isChunked() {
-                                    return entityDetails.isChunked();
-                                }
-
-                                @Override
-                                public Set<String> getTrailerNames() {
-                                    return entityDetails.getTrailerNames();
+                RequestConfig requestConfig = null;
+                if (request instanceof Configurable) {
+                    requestConfig = ((Configurable) request).getConfig();
+                }
+                if (requestConfig != null) {
+                    clientContext.setRequestConfig(requestConfig);
+                }
+                final HttpRoute route = determineRoute(
+                        httpHost != null ? httpHost : RoutingSupport.determineHost(request),
+                        clientContext);
+                final String exchangeId = ExecSupport.getNextExchangeId();
+                if (LOG.isDebugEnabled()) {
+                    LOG.debug("{} preparing request execution", exchangeId);
+                }
+                final AsyncExecRuntime execRuntime = createAsyncExecRuntime(pushHandlerFactory);
+
+                clientContext.setExchangeId(exchangeId);
+                setupContext(clientContext);
+
+                final AsyncExecChain.Scope scope = new AsyncExecChain.Scope(exchangeId, route, request, future,
+                        clientContext, execRuntime, this::executeScheduled, new AtomicInteger(1));
+                final AtomicBoolean outputTerminated = new AtomicBoolean(false);
+                executeImmediate(
+                        BasicRequestBuilder.copy(request).build(),
+                        entityDetails != null ? new AsyncEntityProducer() {
+
+                            @Override
+                            public void releaseResources() {
+                                requestProducer.releaseResources();
+                            }
+
+                            @Override
+                            public void failed(final Exception cause) {
+                                requestProducer.failed(cause);
+                            }
+
+                            @Override
+                            public boolean isRepeatable() {
+                                return requestProducer.isRepeatable();
+                            }
+
+                            @Override
+                            public long getContentLength() {
+                                return entityDetails.getContentLength();
+                            }
+
+                            @Override
+                            public String getContentType() {
+                                return entityDetails.getContentType();
+                            }
+
+                            @Override
+                            public String getContentEncoding() {
+                                return entityDetails.getContentEncoding();
+                            }
+
+                            @Override
+                            public boolean isChunked() {
+                                return entityDetails.isChunked();
+                            }
+
+                            @Override
+                            public Set<String> getTrailerNames() {
+                                return entityDetails.getTrailerNames();
+                            }
+
+                            @Override
+                            public int available() {
+                                return requestProducer.available();
+                            }
+
+                            @Override
+                            public void produce(final DataStreamChannel channel) throws IOException {
+                                if (outputTerminated.get()) {
+                                    channel.endStream();
+                                    return;
                                 }
-
-                                @Override
-                                public int available() {
-                                    return requestProducer.available();
+                                requestProducer.produce(channel);
+                            }
+
+                        } : null,
+                        scope,
+                        new AsyncExecCallback() {
+
+                            @Override
+                            public AsyncDataConsumer handleResponse(
+                                    final HttpResponse response,
+                                    final EntityDetails entityDetails) throws HttpException, IOException {
+                                if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
+                                    outputTerminated.set(true);
+                                    requestProducer.releaseResources();
                                 }
-
-                                @Override
-                                public void produce(final DataStreamChannel channel) throws IOException {
-                                    if (outputTerminated.get()) {
-                                        channel.endStream();
-                                        return;
-                                    }
-                                    requestProducer.produce(channel);
+                                responseConsumer.consumeResponse(response, entityDetails, c,
+                                        new FutureCallback<T>() {
+
+                                            @Override
+                                            public void completed(final T result) {
+                                                future.completed(result);
+                                            }
+
+                                            @Override
+                                            public void failed(final Exception ex) {
+                                                future.failed(ex);
+                                            }
+
+                                            @Override
+                                            public void cancelled() {
+                                                future.cancel();
+                                            }
+
+                                        });
+                                return entityDetails != null ? responseConsumer : null;
+                            }
+
+                            @Override
+                            public void handleInformationResponse(
+                                    final HttpResponse response) throws HttpException, IOException {
+                                responseConsumer.informationResponse(response, c);
+                            }
+
+                            @Override
+                            public void completed() {
+                                if (LOG.isDebugEnabled()) {
+                                    LOG.debug("{} message exchange successfully completed", exchangeId);
                                 }
-
-                            } : null,
-                            scope,
-                            new AsyncExecCallback() {
-
-                                @Override
-                                public AsyncDataConsumer handleResponse(
-                                        final HttpResponse response,
-                                        final EntityDetails entityDetails) throws HttpException, IOException {
-                                    if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
-                                        outputTerminated.set(true);
-                                        requestProducer.releaseResources();
-                                    }
-                                    responseConsumer.consumeResponse(response, entityDetails, context,
-                                            new FutureCallback<T>() {
-
-                                                @Override
-                                                public void completed(final T result) {
-                                                    future.completed(result);
-                                                }
-
-                                                @Override
-                                                public void failed(final Exception ex) {
-                                                    future.failed(ex);
-                                                }
-
-                                                @Override
-                                                public void cancelled() {
-                                                    future.cancel();
-                                                }
-
-                                            });
-                                    return entityDetails != null ? responseConsumer : null;
+                                try {
+                                    execRuntime.releaseEndpoint();
+                                } finally {
+                                    responseConsumer.releaseResources();
+                                    requestProducer.releaseResources();
                                 }
+                            }
 
-                                @Override
-                                public void handleInformationResponse(
-                                        final HttpResponse response) throws HttpException, IOException {
-                                    responseConsumer.informationResponse(response, context);
+                            @Override
+                            public void failed(final Exception cause) {
+                                if (LOG.isDebugEnabled()) {
+                                    LOG.debug("{} request failed: {}", exchangeId, cause.getMessage());
                                 }
-
-                                @Override
-                                public void completed() {
-                                    if (LOG.isDebugEnabled()) {
-                                        LOG.debug("{} message exchange successfully completed", exchangeId);
-                                    }
+                                try {
+                                    execRuntime.discardEndpoint();
+                                    responseConsumer.failed(cause);
+                                } finally {
                                     try {
-                                        execRuntime.releaseEndpoint();
+                                        future.failed(cause);
                                     } finally {
                                         responseConsumer.releaseResources();
                                         requestProducer.releaseResources();
                                     }
                                 }
+                            }
 
-                                @Override
-                                public void failed(final Exception cause) {
-                                    if (LOG.isDebugEnabled()) {
-                                        LOG.debug("{} request failed: {}", exchangeId, cause.getMessage());
-                                    }
-                                    try {
-                                        execRuntime.discardEndpoint();
-                                        responseConsumer.failed(cause);
-                                    } finally {
-                                        try {
-                                            future.failed(cause);
-                                        } finally {
-                                            responseConsumer.releaseResources();
-                                            requestProducer.releaseResources();
-                                        }
-                                    }
-                                }
-
-                            });
-                }
-
+                        });
             }, context);
         } catch (final HttpException | IOException | IllegalStateException ex) {
             future.failed(ex);
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
index 7d47c47..5d04b5e 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/InternalHttpAsyncExecRuntime.java
@@ -261,12 +261,9 @@ class InternalHttpAsyncExecRuntime implements AsyncExecRuntime {
             }
             endpoint.execute(id, exchangeHandler, context);
             if (context.getRequestConfig().isHardCancellationEnabled()) {
-                return new Cancellable() {
-                    @Override
-                    public boolean cancel() {
-                        exchangeHandler.cancel();
-                        return true;
-                    }
+                return () -> {
+                    exchangeHandler.cancel();
+                    return true;
                 };
             }
         } else {
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingAsyncClientExchangeHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingAsyncClientExchangeHandler.java
index 29d954d..954383f 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingAsyncClientExchangeHandler.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/LoggingAsyncClientExchangeHandler.java
@@ -33,7 +33,6 @@ import java.util.List;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.message.RequestLine;
 import org.apache.hc.core5.http.message.StatusLine;
@@ -69,20 +68,12 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
 
     @Override
     public void produceRequest(final RequestChannel channel, final HttpContext context) throws HttpException, IOException {
-        handler.produceRequest(new RequestChannel() {
-
-            @Override
-            public void sendRequest(
-                    final HttpRequest request,
-                    final EntityDetails entityDetails,
-                    final HttpContext context) throws HttpException, IOException {
-                if (log.isDebugEnabled()) {
-                    log.debug("{} send request {}, {}", exchangeId, new RequestLine(request),
-                            entityDetails != null ? "entity len " + entityDetails.getContentLength() : "null entity");
-                }
-                channel.sendRequest(request, entityDetails, context);
+        handler.produceRequest((request, entityDetails, context1) -> {
+            if (log.isDebugEnabled()) {
+                log.debug("{} send request {}, {}", exchangeId, new RequestLine(request),
+                        entityDetails != null ? "entity len " + entityDetails.getContentLength() : "null entity");
             }
-
+            channel.sendRequest(request, entityDetails, context1);
         }, context);
     }
 
@@ -94,7 +85,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
     @Override
     public void produce(final DataStreamChannel channel) throws IOException {
         if (log.isDebugEnabled()) {
-            log.debug("{} produce request data", exchangeId);
+            log.debug("{}: produce request data", exchangeId);
         }
         handler.produce(new DataStreamChannel() {
 
@@ -106,7 +97,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
             @Override
             public int write(final ByteBuffer src) throws IOException {
                 if (log.isDebugEnabled()) {
-                    log.debug("{} produce request data, len {} bytes", exchangeId, src.remaining());
+                    log.debug("{}: produce request data, len {} bytes", exchangeId, src.remaining());
                 }
                 return channel.write(src);
             }
@@ -114,7 +105,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
             @Override
             public void endStream() throws IOException {
                 if (log.isDebugEnabled()) {
-                    log.debug("{} end of request data", exchangeId);
+                    log.debug("{}: end of request data", exchangeId);
                 }
                 channel.endStream();
             }
@@ -122,7 +113,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
             @Override
             public void endStream(final List<? extends Header> trailers) throws IOException {
                 if (log.isDebugEnabled()) {
-                    log.debug("{} end of request data", exchangeId);
+                    log.debug("{}: end of request data", exchangeId);
                 }
                 channel.endStream(trailers);
             }
@@ -135,7 +126,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
             final HttpResponse response,
             final HttpContext context) throws HttpException, IOException {
         if (log.isDebugEnabled()) {
-            log.debug("{} information response {}", exchangeId, new StatusLine(response));
+            log.debug("{}: information response {}", exchangeId, new StatusLine(response));
         }
         handler.consumeInformation(response, context);
     }
@@ -146,7 +137,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
             final EntityDetails entityDetails,
             final HttpContext context) throws HttpException, IOException {
         if (log.isDebugEnabled()) {
-            log.debug("{} consume response {}, {}", exchangeId, new StatusLine(response), entityDetails != null ? "entity len " + entityDetails.getContentLength() : " null entity");
+            log.debug("{}: consume response {}, {}", exchangeId, new StatusLine(response), entityDetails != null ? "entity len " + entityDetails.getContentLength() : " null entity");
         }
         handler.consumeResponse(response, entityDetails, context);
     }
@@ -154,23 +145,18 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
 
     @Override
     public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-        handler.updateCapacity(new CapacityChannel() {
-
-            @Override
-            public void update(final int increment) throws IOException {
-                if (log.isDebugEnabled()) {
-                    log.debug("{} capacity update {}", exchangeId, increment);
-                }
-                capacityChannel.update(increment);
+        handler.updateCapacity(increment -> {
+            if (log.isDebugEnabled()) {
+                log.debug("{} capacity update {}", exchangeId, increment);
             }
-
+            capacityChannel.update(increment);
         });
     }
 
     @Override
     public void consume(final ByteBuffer src) throws IOException {
         if (log.isDebugEnabled()) {
-            log.debug("{} consume response data, len {} bytes", exchangeId, src.remaining());
+            log.debug("{}: consume response data, len {} bytes", exchangeId, src.remaining());
         }
         handler.consume(src);
     }
@@ -178,7 +164,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
     @Override
     public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
         if (log.isDebugEnabled()) {
-            log.debug("{} end of response data", exchangeId);
+            log.debug("{}: end of response data", exchangeId);
         }
         handler.streamEnd(trailers);
     }
@@ -186,7 +172,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
     @Override
     public void failed(final Exception cause) {
         if (log.isDebugEnabled()) {
-            log.debug("{} execution failed: {}", exchangeId, cause.getMessage());
+            log.debug("{}: execution failed: {}", exchangeId, cause.getMessage());
         }
         handler.failed(cause);
     }
@@ -194,7 +180,7 @@ final class LoggingAsyncClientExchangeHandler implements AsyncClientExchangeHand
     @Override
     public void cancel() {
         if (log.isDebugEnabled()) {
-            log.debug("{} execution cancelled", exchangeId);
+            log.debug("{}: execution cancelled", exchangeId);
         }
         handler.cancel();
     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
index cb67732..6d91ff8 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalH2AsyncClient.java
@@ -27,7 +27,6 @@
 package org.apache.hc.client5.http.impl.async;
 
 import java.io.IOException;
-import java.net.InetSocketAddress;
 import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.CancellationException;
@@ -47,13 +46,10 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.concurrent.Cancellable;
 import org.apache.hc.core5.concurrent.ComplexCancellable;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Callback;
-import org.apache.hc.core5.function.Resolver;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
@@ -106,31 +102,17 @@ public final class MinimalH2AsyncClient extends AbstractMinimalHttpAsyncClientBa
             final DnsResolver dnsResolver,
             final TlsStrategy tlsStrategy) {
         super(new DefaultConnectingIOReactor(
-                eventHandlerFactory,
-                reactorConfig,
-                workerThreadFactory,
-                LoggingIOSessionDecorator.INSTANCE,
-                LoggingExceptionCallback.INSTANCE,
-                null,
-                new Callback<IOSession>() {
-
-                    @Override
-                    public void execute(final IOSession ioSession) {
-                        ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE);
-                    }
-
-                }),
+                        eventHandlerFactory,
+                        reactorConfig,
+                        workerThreadFactory,
+                        LoggingIOSessionDecorator.INSTANCE,
+                        LoggingExceptionCallback.INSTANCE,
+                        null,
+                        ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.IMMEDIATE)),
                 pushConsumerRegistry,
                 threadFactory);
         this.connectionInitiator = new MultihomeConnectionInitiator(getConnectionInitiator(), dnsResolver);
-        this.connPool = new H2ConnPool(this.connectionInitiator, new Resolver<HttpHost, InetSocketAddress>() {
-
-            @Override
-            public InetSocketAddress resolve(final HttpHost object) {
-                return null;
-            }
-
-        }, tlsStrategy);
+        this.connPool = new H2ConnPool(this.connectionInitiator, object -> null, tlsStrategy);
     }
 
     @Override
@@ -144,137 +126,122 @@ public final class MinimalH2AsyncClient extends AbstractMinimalHttpAsyncClientBa
                 throw new CancellationException("Request execution cancelled");
             }
             final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
-            exchangeHandler.produceRequest(new RequestChannel() {
-
-                @Override
-                public void sendRequest(
-                        final HttpRequest request,
-                        final EntityDetails entityDetails,
-                        final HttpContext context) throws HttpException, IOException {
-                    RequestConfig requestConfig = null;
-                    if (request instanceof Configurable) {
-                        requestConfig = ((Configurable) request).getConfig();
-                    }
-                    if (requestConfig != null) {
-                        clientContext.setRequestConfig(requestConfig);
-                    } else {
-                        requestConfig = clientContext.getRequestConfig();
-                    }
-                    final Timeout connectTimeout = requestConfig.getConnectTimeout();
-                    final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
-
-                    final Future<IOSession> sessionFuture = connPool.getSession(target, connectTimeout,
-                        new FutureCallback<IOSession>() {
-
-                        @Override
-                        public void completed(final IOSession session) {
-                            final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
+            exchangeHandler.produceRequest((request, entityDetails, context1) -> {
+                RequestConfig requestConfig = null;
+                if (request instanceof Configurable) {
+                    requestConfig = ((Configurable) request).getConfig();
+                }
+                if (requestConfig != null) {
+                    clientContext.setRequestConfig(requestConfig);
+                } else {
+                    requestConfig = clientContext.getRequestConfig();
+                }
+                final Timeout connectTimeout = requestConfig.getConnectTimeout();
+                final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
 
-                                @Override
-                                public void releaseResources() {
-                                    exchangeHandler.releaseResources();
-                                }
+                final Future<IOSession> sessionFuture = connPool.getSession(target, connectTimeout,
+                    new FutureCallback<IOSession>() {
 
-                                @Override
-                                public void failed(final Exception cause) {
-                                    exchangeHandler.failed(cause);
-                                }
+                    @Override
+                    public void completed(final IOSession session) {
+                        final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
 
-                                @Override
-                                public void cancel() {
-                                    failed(new RequestFailedException("Request aborted"));
-                                }
+                            @Override
+                            public void releaseResources() {
+                                exchangeHandler.releaseResources();
+                            }
 
-                                @Override
-                                public void produceRequest(
-                                        final RequestChannel channel,
-                                        final HttpContext context) throws HttpException, IOException {
-                                    channel.sendRequest(request, entityDetails, context);
-                                }
+                            @Override
+                            public void failed(final Exception cause) {
+                                exchangeHandler.failed(cause);
+                            }
 
-                                @Override
-                                public int available() {
-                                    return exchangeHandler.available();
-                                }
+                            @Override
+                            public void cancel() {
+                                failed(new RequestFailedException("Request aborted"));
+                            }
 
-                                @Override
-                                public void produce(final DataStreamChannel channel) throws IOException {
-                                    exchangeHandler.produce(channel);
-                                }
+                            @Override
+                            public void produceRequest(
+                                    final RequestChannel channel,
+                                    final HttpContext context1) throws HttpException, IOException {
+                                channel.sendRequest(request, entityDetails, context1);
+                            }
 
-                                @Override
-                                public void consumeInformation(
-                                        final HttpResponse response,
-                                        final HttpContext context) throws HttpException, IOException {
-                                    exchangeHandler.consumeInformation(response, context);
-                                }
+                            @Override
+                            public int available() {
+                                return exchangeHandler.available();
+                            }
 
-                                @Override
-                                public void consumeResponse(
-                                        final HttpResponse response,
-                                        final EntityDetails entityDetails,
-                                        final HttpContext context) throws HttpException, IOException {
-                                    exchangeHandler.consumeResponse(response, entityDetails, context);
-                                }
+                            @Override
+                            public void produce(final DataStreamChannel channel) throws IOException {
+                                exchangeHandler.produce(channel);
+                            }
 
-                                @Override
-                                public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                                    exchangeHandler.updateCapacity(capacityChannel);
-                                }
+                            @Override
+                            public void consumeInformation(
+                                    final HttpResponse response,
+                                    final HttpContext context1) throws HttpException, IOException {
+                                exchangeHandler.consumeInformation(response, context1);
+                            }
 
-                                @Override
-                                public void consume(final ByteBuffer src) throws IOException {
-                                    exchangeHandler.consume(src);
-                                }
+                            @Override
+                            public void consumeResponse(
+                                    final HttpResponse response,
+                                    final EntityDetails entityDetails,
+                                    final HttpContext context1) throws HttpException, IOException {
+                                exchangeHandler.consumeResponse(response, entityDetails, context1);
+                            }
 
-                                @Override
-                                public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                                    exchangeHandler.streamEnd(trailers);
-                                }
+                            @Override
+                            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                                exchangeHandler.updateCapacity(capacityChannel);
+                            }
 
-                            };
-                            if (LOG.isDebugEnabled()) {
-                                final String exchangeId = ExecSupport.getNextExchangeId();
-                                LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
-                                session.enqueue(
-                                        new RequestExecutionCommand(
-                                                new LoggingAsyncClientExchangeHandler(LOG, exchangeId, internalExchangeHandler),
-                                                pushHandlerFactory,
-                                                cancellable,
-                                                clientContext),
-                                        Command.Priority.NORMAL);
-                            } else {
-                                session.enqueue(
-                                        new RequestExecutionCommand(
-                                                internalExchangeHandler,
-                                                pushHandlerFactory,
-                                                cancellable,
-                                                clientContext),
-                                        Command.Priority.NORMAL);
+                            @Override
+                            public void consume(final ByteBuffer src) throws IOException {
+                                exchangeHandler.consume(src);
                             }
-                        }
 
-                        @Override
-                        public void failed(final Exception ex) {
-                            exchangeHandler.failed(ex);
-                        }
+                            @Override
+                            public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                                exchangeHandler.streamEnd(trailers);
+                            }
 
-                        @Override
-                        public void cancelled() {
-                            exchangeHandler.cancel();
+                        };
+                        if (LOG.isDebugEnabled()) {
+                            final String exchangeId = ExecSupport.getNextExchangeId();
+                            LOG.debug("{} executing message exchange {}", exchangeId, ConnPoolSupport.getId(session));
+                            session.enqueue(
+                                    new RequestExecutionCommand(
+                                            new LoggingAsyncClientExchangeHandler(LOG, exchangeId, internalExchangeHandler),
+                                            pushHandlerFactory,
+                                            cancellable,
+                                            clientContext),
+                                    Command.Priority.NORMAL);
+                        } else {
+                            session.enqueue(
+                                    new RequestExecutionCommand(
+                                            internalExchangeHandler,
+                                            pushHandlerFactory,
+                                            cancellable,
+                                            clientContext),
+                                    Command.Priority.NORMAL);
                         }
+                    }
 
-                    });
-                    cancellable.setDependency(new Cancellable() {
-
-                        @Override
-                        public boolean cancel() {
-                            return sessionFuture.cancel(true);
-                        }
+                    @Override
+                    public void failed(final Exception ex) {
+                        exchangeHandler.failed(ex);
+                    }
 
-                    });
-                }
+                    @Override
+                    public void cancelled() {
+                        exchangeHandler.cancel();
+                    }
 
+                });
+                cancellable.setDependency(() -> sessionFuture.cancel(true));
             }, context);
         } catch (final HttpException | IOException | IllegalStateException ex) {
             exchangeHandler.failed(ex);
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
index bb5e696..3e959df 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/async/MinimalHttpAsyncClient.java
@@ -54,12 +54,10 @@ import org.apache.hc.core5.concurrent.Cancellable;
 import org.apache.hc.core5.concurrent.ComplexCancellable;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
@@ -78,7 +76,6 @@ import org.apache.hc.core5.reactor.Command;
 import org.apache.hc.core5.reactor.DefaultConnectingIOReactor;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.TimeValue;
@@ -116,20 +113,13 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
             final AsyncClientConnectionManager manager,
             final SchemePortResolver schemePortResolver) {
         super(new DefaultConnectingIOReactor(
-                eventHandlerFactory,
-                reactorConfig,
-                workerThreadFactory,
-                LoggingIOSessionDecorator.INSTANCE,
-                LoggingExceptionCallback.INSTANCE,
-                null,
-                new Callback<IOSession>() {
-
-                    @Override
-                    public void execute(final IOSession ioSession) {
-                        ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.NORMAL);
-                    }
-
-                }),
+                        eventHandlerFactory,
+                        reactorConfig,
+                        workerThreadFactory,
+                        LoggingIOSessionDecorator.INSTANCE,
+                        LoggingExceptionCallback.INSTANCE,
+                        null,
+                        ioSession -> ioSession.enqueue(new ShutdownCommand(CloseMode.GRACEFUL), Command.Priority.NORMAL)),
                 pushConsumerRegistry,
                 threadFactory);
         this.manager = manager;
@@ -259,180 +249,166 @@ public final class MinimalHttpAsyncClient extends AbstractMinimalHttpAsyncClient
                 throw new CancellationException("Request execution cancelled");
             }
             final HttpClientContext clientContext = context != null ? HttpClientContext.adapt(context) : HttpClientContext.create();
-            exchangeHandler.produceRequest(new RequestChannel() {
-
-                @Override
-                public void sendRequest(
-                        final HttpRequest request,
-                        final EntityDetails entityDetails,
-                        final HttpContext context) throws HttpException, IOException {
-                    RequestConfig requestConfig = null;
-                    if (request instanceof Configurable) {
-                        requestConfig = ((Configurable) request).getConfig();
-                    }
-                    if (requestConfig != null) {
-                        clientContext.setRequestConfig(requestConfig);
-                    } else {
-                        requestConfig = clientContext.getRequestConfig();
-                    }
-                    final Timeout connectionRequestTimeout = requestConfig.getConnectionRequestTimeout();
-                    final Timeout connectTimeout = requestConfig.getConnectTimeout();
-                    final Timeout responseTimeout = requestConfig.getResponseTimeout();
-                    final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
-
-                    final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(
-                            target,
-                            connectionRequestTimeout,
-                            connectTimeout,
-                            clientContext,
-                            new FutureCallback<AsyncConnectionEndpoint>() {
-
-                                @Override
-                                public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
-                                    final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
-                                    final AtomicInteger messageCountDown = new AtomicInteger(2);
-                                    final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
-
-                                        @Override
-                                        public void releaseResources() {
-                                            try {
-                                                exchangeHandler.releaseResources();
-                                            } finally {
-                                                endpoint.releaseAndDiscard();
-                                            }
-                                        }
-
-                                        @Override
-                                        public void failed(final Exception cause) {
-                                            try {
-                                                exchangeHandler.failed(cause);
-                                            } finally {
-                                                endpoint.releaseAndDiscard();
-                                            }
+            exchangeHandler.produceRequest((request, entityDetails, context1) -> {
+                RequestConfig requestConfig = null;
+                if (request instanceof Configurable) {
+                    requestConfig = ((Configurable) request).getConfig();
+                }
+                if (requestConfig != null) {
+                    clientContext.setRequestConfig(requestConfig);
+                } else {
+                    requestConfig = clientContext.getRequestConfig();
+                }
+                final Timeout connectionRequestTimeout = requestConfig.getConnectionRequestTimeout();
+                final Timeout connectTimeout = requestConfig.getConnectTimeout();
+                final Timeout responseTimeout = requestConfig.getResponseTimeout();
+                final HttpHost target = new HttpHost(request.getScheme(), request.getAuthority());
+
+                final Future<AsyncConnectionEndpoint> leaseFuture = leaseEndpoint(
+                        target,
+                        connectionRequestTimeout,
+                        connectTimeout,
+                        clientContext,
+                        new FutureCallback<AsyncConnectionEndpoint>() {
+
+                            @Override
+                            public void completed(final AsyncConnectionEndpoint connectionEndpoint) {
+                                final InternalAsyncClientEndpoint endpoint = new InternalAsyncClientEndpoint(connectionEndpoint);
+                                final AtomicInteger messageCountDown = new AtomicInteger(2);
+                                final AsyncClientExchangeHandler internalExchangeHandler = new AsyncClientExchangeHandler() {
+
+                                    @Override
+                                    public void releaseResources() {
+                                        try {
+                                            exchangeHandler.releaseResources();
+                                        } finally {
+                                            endpoint.releaseAndDiscard();
                                         }
+                                    }
 
-                                        @Override
-                                        public void cancel() {
-                                            failed(new RequestFailedException("Request aborted"));
+                                    @Override
+                                    public void failed(final Exception cause) {
+                                        try {
+                                            exchangeHandler.failed(cause);
+                                        } finally {
+                                            endpoint.releaseAndDiscard();
                                         }
+                                    }
 
-                                        @Override
-                                        public void produceRequest(
-                                                final RequestChannel channel,
-                                                final HttpContext context) throws HttpException, IOException {
-                                            channel.sendRequest(request, entityDetails, context);
-                                            if (entityDetails == null) {
-                                                messageCountDown.decrementAndGet();
-                                            }
-                                        }
+                                    @Override
+                                    public void cancel() {
+                                        failed(new RequestFailedException("Request aborted"));
+                                    }
 
-                                        @Override
-                                        public int available() {
-                                            return exchangeHandler.available();
+                                    @Override
+                                    public void produceRequest(
+                                            final RequestChannel channel,
+                                            final HttpContext context1) throws HttpException, IOException {
+                                        channel.sendRequest(request, entityDetails, context1);
+                                        if (entityDetails == null) {
+                                            messageCountDown.decrementAndGet();
                                         }
+                                    }
 
-                                        @Override
-                                        public void produce(final DataStreamChannel channel) throws IOException {
-                                            exchangeHandler.produce(new DataStreamChannel() {
+                                    @Override
+                                    public int available() {
+                                        return exchangeHandler.available();
+                                    }
 
-                                                @Override
-                                                public void requestOutput() {
-                                                    channel.requestOutput();
-                                                }
+                                    @Override
+                                    public void produce(final DataStreamChannel channel) throws IOException {
+                                        exchangeHandler.produce(new DataStreamChannel() {
 
-                                                @Override
-                                                public int write(final ByteBuffer src) throws IOException {
-                                                    return channel.write(src);
-                                                }
+                                            @Override
+                                            public void requestOutput() {
+                                                channel.requestOutput();
+                                            }
 
-                                                @Override
-                                                public void endStream(final List<? extends Header> trailers) throws IOException {
-                                                    channel.endStream(trailers);
-                                                    if (messageCountDown.decrementAndGet() <= 0) {
-                                                        endpoint.releaseAndReuse();
-                                                    }
-                                                }
+                                            @Override
+                                            public int write(final ByteBuffer src) throws IOException {
+                                                return channel.write(src);
+                                            }
 
-                                                @Override
-                                                public void endStream() throws IOException {
-                                                    channel.endStream();
-                                                    if (messageCountDown.decrementAndGet() <= 0) {
-                                                        endpoint.releaseAndReuse();
-                                                    }
+                                            @Override
+                                            public void endStream(final List<? extends Header> trailers) throws IOException {
+                                                channel.endStream(trailers);
+                                                if (messageCountDown.decrementAndGet() <= 0) {
+                                                    endpoint.releaseAndReuse();
                                                 }
-
-                                            });
-                                        }
-
-                                        @Override
-                                        public void consumeInformation(
-                                                final HttpResponse response,
-                                                final HttpContext context) throws HttpException, IOException {
-                                            exchangeHandler.consumeInformation(response, context);
-                                        }
-
-                                        @Override
-                                        public void consumeResponse(
-                                                final HttpResponse response,
-                                                final EntityDetails entityDetails,
-                                                final HttpContext context) throws HttpException, IOException {
-                                            exchangeHandler.consumeResponse(response, entityDetails, context);
-                                            if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
-                                                messageCountDown.decrementAndGet();
                                             }
-                                            if (entityDetails == null) {
+
+                                            @Override
+                                            public void endStream() throws IOException {
+                                                channel.endStream();
                                                 if (messageCountDown.decrementAndGet() <= 0) {
                                                     endpoint.releaseAndReuse();
                                                 }
                                             }
-                                        }
 
-                                        @Override
-                                        public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                                            exchangeHandler.updateCapacity(capacityChannel);
-                                        }
+                                        });
+                                    }
 
-                                        @Override
-                                        public void consume(final ByteBuffer src) throws IOException {
-                                            exchangeHandler.consume(src);
-                                        }
+                                    @Override
+                                    public void consumeInformation(
+                                            final HttpResponse response,
+                                            final HttpContext context1) throws HttpException, IOException {
+                                        exchangeHandler.consumeInformation(response, context1);
+                                    }
 
-                                        @Override
-                                        public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                                    @Override
+                                    public void consumeResponse(
+                                            final HttpResponse response,
+                                            final EntityDetails entityDetails,
+                                            final HttpContext context1) throws HttpException, IOException {
+                                        exchangeHandler.consumeResponse(response, entityDetails, context1);
+                                        if (response.getCode() >= HttpStatus.SC_CLIENT_ERROR) {
+                                            messageCountDown.decrementAndGet();
+                                        }
+                                        if (entityDetails == null) {
                                             if (messageCountDown.decrementAndGet() <= 0) {
                                                 endpoint.releaseAndReuse();
                                             }
-                                            exchangeHandler.streamEnd(trailers);
                                         }
+                                    }
 
-                                    };
-                                    if (responseTimeout != null) {
-                                        endpoint.setSocketTimeout(responseTimeout);
+                                    @Override
+                                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                                        exchangeHandler.updateCapacity(capacityChannel);
                                     }
-                                    endpoint.execute(internalExchangeHandler, pushHandlerFactory, clientContext);
-                                }
 
-                                @Override
-                                public void failed(final Exception ex) {
-                                    exchangeHandler.failed(ex);
-                                }
+                                    @Override
+                                    public void consume(final ByteBuffer src) throws IOException {
+                                        exchangeHandler.consume(src);
+                                    }
 
-                                @Override
-                                public void cancelled() {
-                                    exchangeHandler.cancel();
+                                    @Override
+                                    public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                                        if (messageCountDown.decrementAndGet() <= 0) {
+                                            endpoint.releaseAndReuse();
+                                        }
+                                        exchangeHandler.streamEnd(trailers);
+                                    }
+
+                                };
+                                if (responseTimeout != null) {
+                                    endpoint.setSocketTimeout(responseTimeout);
                                 }
+                                endpoint.execute(internalExchangeHandler, pushHandlerFactory, clientContext);
+                            }
 
-                            });
+                            @Override
+                            public void failed(final Exception ex) {
+                                exchangeHandler.failed(ex);
+                            }
 
-                    cancellable.setDependency(new Cancellable() {
+                            @Override
+                            public void cancelled() {
+                                exchangeHandler.cancel();
+                            }
 
-                        @Override
-                        public boolean cancel() {
-                            return leaseFuture.cancel(true);
-                        }
+                        });
 
-                    });
-                }
+                cancellable.setDependency(() -> leaseFuture.cancel(true));
             }, context);
 
         } catch (final HttpException | IOException | IllegalStateException ex) {
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/NTLMEngineImpl.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/NTLMEngineImpl.java
index 85e6320..f784d34 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/NTLMEngineImpl.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/auth/NTLMEngineImpl.java
@@ -1260,7 +1260,7 @@ final class NTLMEngineImpl implements NTLMEngine {
 
         Type1Message(final String domain, final String host, final Integer flags) {
             super();
-            this.flags = ((flags == null)?getDefaultFlags():flags);
+            this.flags = ((flags == null)?getDefaultFlags(): flags.intValue());
 
             // See HTTPCLIENT-1662
             final String unqualifiedHost = host;
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/AIMDBackoffManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/AIMDBackoffManager.java
index c22cb21..af9e5b8 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/AIMDBackoffManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/AIMDBackoffManager.java
@@ -91,11 +91,11 @@ public class AIMDBackoffManager implements BackoffManager {
             final int curr = connPerRoute.getMaxPerRoute(route);
             final Long lastUpdate = getLastUpdate(lastRouteBackoffs, route);
             final long now = clock.getCurrentTime();
-            if (now - lastUpdate.longValue() < coolDown.toMilliseconds()) {
+            if (now - lastUpdate < coolDown.toMilliseconds()) {
                 return;
             }
             connPerRoute.setMaxPerRoute(route, getBackedOffPoolSize(curr));
-            lastRouteBackoffs.put(route, Long.valueOf(now));
+            lastRouteBackoffs.put(route, now);
         }
     }
 
@@ -114,19 +114,19 @@ public class AIMDBackoffManager implements BackoffManager {
             final Long lastProbe = getLastUpdate(lastRouteProbes, route);
             final Long lastBackoff = getLastUpdate(lastRouteBackoffs, route);
             final long now = clock.getCurrentTime();
-            if (now - lastProbe.longValue() < coolDown.toMilliseconds()
-                || now - lastBackoff.longValue() < coolDown.toMilliseconds()) {
+            if (now - lastProbe < coolDown.toMilliseconds()
+                || now - lastBackoff < coolDown.toMilliseconds()) {
                 return;
             }
             connPerRoute.setMaxPerRoute(route, max);
-            lastRouteProbes.put(route, Long.valueOf(now));
+            lastRouteProbes.put(route, now);
         }
     }
 
     private Long getLastUpdate(final Map<HttpRoute, Long> updates, final HttpRoute route) {
         Long lastUpdate = updates.get(route);
         if (lastUpdate == null) {
-            lastUpdate = Long.valueOf(0L);
+            lastUpdate = 0L;
         }
         return lastUpdate;
     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecChainElement.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecChainElement.java
index ff13e9f..c3bd56c 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecChainElement.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ExecChainElement.java
@@ -48,16 +48,7 @@ class ExecChainElement {
     public ClassicHttpResponse execute(
             final ClassicHttpRequest request,
             final ExecChain.Scope scope) throws IOException, HttpException {
-        return handler.execute(request, scope, new ExecChain() {
-
-            @Override
-            public ClassicHttpResponse proceed(
-                    final ClassicHttpRequest request,
-                    final Scope scope) throws IOException, HttpException {
-                return next.execute(request, scope);
-            }
-
-        });
+        return handler.execute(request, scope, next != null ? next::execute : null);
     }
 
     @Override
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java
index 77252dd..3e0144b 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/HttpClientBuilder.java
@@ -28,7 +28,6 @@
 package org.apache.hc.client5.http.impl.classic;
 
 import java.io.Closeable;
-import java.io.IOException;
 import java.net.ProxySelector;
 import java.util.ArrayList;
 import java.util.Collection;
@@ -43,8 +42,8 @@ import org.apache.hc.client5.http.HttpRequestRetryStrategy;
 import org.apache.hc.client5.http.SchemePortResolver;
 import org.apache.hc.client5.http.UserTokenHandler;
 import org.apache.hc.client5.http.auth.AuthSchemeFactory;
-import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.CredentialsProvider;
+import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.classic.BackoffManager;
 import org.apache.hc.client5.http.classic.ConnectionBackoffStrategy;
 import org.apache.hc.client5.http.classic.ExecChainHandler;
@@ -87,9 +86,7 @@ import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpHost;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpRequestInterceptor;
-import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpResponseInterceptor;
 import org.apache.hc.core5.http.config.Lookup;
 import org.apache.hc.core5.http.config.NamedElementChain;
@@ -98,7 +95,6 @@ import org.apache.hc.core5.http.config.RegistryBuilder;
 import org.apache.hc.core5.http.impl.DefaultConnectionReuseStrategy;
 import org.apache.hc.core5.http.impl.io.HttpRequestExecutor;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpProcessorBuilder;
 import org.apache.hc.core5.http.protocol.RequestContent;
@@ -748,13 +744,7 @@ public class HttpClientBuilder {
                 if ("true".equalsIgnoreCase(s)) {
                     reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
                 } else {
-                    reuseStrategyCopy = new ConnectionReuseStrategy() {
-                        @Override
-                        public boolean keepAlive(
-                                final HttpRequest request, final HttpResponse response, final HttpContext context) {
-                            return false;
-                        }
-                    };
+                    reuseStrategyCopy = (request, response, context) -> false;
                 }
             } else {
                 reuseStrategyCopy = DefaultConnectionReuseStrategy.INSTANCE;
@@ -985,18 +975,13 @@ public class HttpClientBuilder {
                 if (connManagerCopy instanceof ConnPoolControl) {
                     final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor((ConnPoolControl<?>) connManagerCopy,
                             maxIdleTime, maxIdleTime);
-                    closeablesCopy.add(new Closeable() {
-
-                        @Override
-                        public void close() throws IOException {
-                            connectionEvictor.shutdown();
-                            try {
-                                connectionEvictor.awaitTermination(Timeout.ofSeconds(1));
-                            } catch (final InterruptedException interrupted) {
-                                Thread.currentThread().interrupt();
-                            }
+                    closeablesCopy.add(() -> {
+                        connectionEvictor.shutdown();
+                        try {
+                            connectionEvictor.awaitTermination(Timeout.ofSeconds(1));
+                        } catch (final InterruptedException interrupted) {
+                            Thread.currentThread().interrupt();
                         }
-
                     });
                     connectionEvictor.start();
                 }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ResponseEntityProxy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ResponseEntityProxy.java
index b70211e..9ea2d04 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ResponseEntityProxy.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/classic/ResponseEntityProxy.java
@@ -159,18 +159,15 @@ class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher
     public Supplier<List<? extends Header>> getTrailers() {
             try {
                 final InputStream underlyingStream = super.getContent();
-                return new Supplier<List<? extends Header>>() {
-                    @Override
-                    public List<? extends Header> get() {
-                        final Header[] footers;
-                        if (underlyingStream instanceof ChunkedInputStream) {
-                            final ChunkedInputStream chunkedInputStream = (ChunkedInputStream) underlyingStream;
-                            footers = chunkedInputStream.getFooters();
-                        } else {
-                            footers = new Header[0];
-                        }
-                        return Arrays.asList(footers);
+                return () -> {
+                    final Header[] footers;
+                    if (underlyingStream instanceof ChunkedInputStream) {
+                        final ChunkedInputStream chunkedInputStream = (ChunkedInputStream) underlyingStream;
+                        footers = chunkedInputStream.getFooters();
+                    } else {
+                        footers = new Header[0];
                     }
+                    return Arrays.asList(footers);
                 };
             } catch (final IOException e) {
                 throw new IllegalStateException("Unable to retrieve input stream", e);
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java
index 357f8a8..594a671 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/LaxExpiresHandler.java
@@ -147,7 +147,7 @@ public class LaxExpiresHandler extends AbstractCookieAttributeHandler implements
                     final Matcher matcher = MONTH_PATTERN.matcher(content);
                     if (matcher.matches()) {
                         foundMonth = true;
-                        month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT));
+                        month = MONTHS.get(matcher.group(1).toLowerCase(Locale.ROOT)).intValue();
                         continue;
                     }
                 }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java
index c815bc0..fb79434 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/cookie/RFC6265CookieSpec.java
@@ -212,7 +212,7 @@ public class RFC6265CookieSpec implements CookieSpec {
         if (cookies.size() > 1) {
             // Create a mutable copy and sort the copy.
             sortedCookies = new ArrayList<>(cookies);
-            Collections.sort(sortedCookies, CookiePriorityComparator.INSTANCE);
+            sortedCookies.sort(CookiePriorityComparator.INSTANCE);
         } else {
             sortedCookies = cookies;
         }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
index 584951a..dc59ce8 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/impl/nio/PoolingAsyncClientConnectionManager.java
@@ -49,7 +49,6 @@ import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.ProtocolVersion;
@@ -250,19 +249,14 @@ public class PoolingAsyncClientConnectionManager implements AsyncClientConnectio
                                     final TimeValue timeValue = PoolingAsyncClientConnectionManager.this.validateAfterInactivity;
                                     if (TimeValue.isNonNegative(timeValue) &&
                                             poolEntry.getUpdated() + timeValue.toMilliseconds() <= System.currentTimeMillis()) {
-                                        connection.submitCommand(new PingCommand(new BasicPingHandler(new Callback<Boolean>() {
-
-                                            @Override
-                                            public void execute(final Boolean result) {
-                                                if (result == null || !result) {
-                                                    if (LOG.isDebugEnabled()) {
-                                                        LOG.debug("{} connection {} is stale", id, ConnPoolSupport.getId(connection));
-                                                    }
-                                                    poolEntry.discardConnection(CloseMode.IMMEDIATE);
+                                        connection.submitCommand(new PingCommand(new BasicPingHandler(result -> {
+                                            if (result == null || !result) {
+                                                if (LOG.isDebugEnabled()) {
+                                                    LOG.debug("{} connection {} is stale", id, ConnPoolSupport.getId(connection));
                                                 }
-                                                leaseCompleted(poolEntry);
+                                                poolEntry.discardConnection(CloseMode.IMMEDIATE);
                                             }
-
+                                            leaseCompleted(poolEntry);
                                         })), Command.Priority.IMMEDIATE);
                                         return;
                                     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java
index 1c66bd0..82dbdbd 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/socket/PlainConnectionSocketFactory.java
@@ -81,12 +81,9 @@ public class PlainConnectionSocketFactory implements ConnectionSocketFactory {
             // Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
             // only to this library
             try {
-                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                    @Override
-                    public Object run() throws IOException {
-                        sock.connect(remoteAddress, TimeValue.isPositive(connectTimeout) ? connectTimeout.toMillisecondsIntBound() : 0);
-                        return null;
-                    }
+                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
+                    sock.connect(remoteAddress, TimeValue.isPositive(connectTimeout) ? connectTimeout.toMillisecondsIntBound() : 0);
+                    return null;
                 });
             } catch (final PrivilegedActionException e) {
                 Asserts.check(e.getCause() instanceof  IOException,
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java
index afcb712..474ab7d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/AbstractClientTlsStrategy.java
@@ -47,10 +47,7 @@ import org.apache.hc.core5.http.ssl.TlsCiphers;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
 import org.apache.hc.core5.http2.ssl.H2TlsSupport;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.SSLBufferMode;
-import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
-import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TlsDetails;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Args;
@@ -93,56 +90,46 @@ abstract class AbstractClientTlsStrategy implements TlsStrategy {
             final SocketAddress remoteAddress,
             final Object attachment,
             final Timeout handshakeTimeout) {
-        tlsSession.startTls(sslContext, host, sslBufferManagement, new SSLSessionInitializer() {
+        tlsSession.startTls(sslContext, host, sslBufferManagement, (endpoint, sslEngine) -> {
 
-            @Override
-            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
+            final HttpVersionPolicy versionPolicy = attachment instanceof HttpVersionPolicy ?
+                    (HttpVersionPolicy) attachment : HttpVersionPolicy.NEGOTIATE;
 
-                final HttpVersionPolicy versionPolicy = attachment instanceof HttpVersionPolicy ?
-                        (HttpVersionPolicy) attachment : HttpVersionPolicy.NEGOTIATE;
-
-                final SSLParameters sslParameters = sslEngine.getSSLParameters();
-                if (supportedProtocols != null) {
-                    sslParameters.setProtocols(supportedProtocols);
-                } else if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
-                    sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
-                }
-                if (supportedCipherSuites != null) {
-                    sslParameters.setCipherSuites(supportedCipherSuites);
-                } else if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
-                    sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
-                }
+            final SSLParameters sslParameters = sslEngine.getSSLParameters();
+            if (supportedProtocols != null) {
+                sslParameters.setProtocols(supportedProtocols);
+            } else if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
+                sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
+            }
+            if (supportedCipherSuites != null) {
+                sslParameters.setCipherSuites(supportedCipherSuites);
+            } else if (versionPolicy == HttpVersionPolicy.FORCE_HTTP_2) {
+                sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
+            }
 
-                if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
-                    H2TlsSupport.setEnableRetransmissions(sslParameters, false);
-                }
+            if (versionPolicy != HttpVersionPolicy.FORCE_HTTP_1) {
+                H2TlsSupport.setEnableRetransmissions(sslParameters, false);
+            }
 
-                applyParameters(sslEngine, sslParameters, H2TlsSupport.selectApplicationProtocols(attachment));
+            applyParameters(sslEngine, sslParameters, H2TlsSupport.selectApplicationProtocols(attachment));
 
-                initializeEngine(sslEngine);
+            initializeEngine(sslEngine);
 
-                if (LOG.isDebugEnabled()) {
-                    LOG.debug("Enabled protocols: {}", Arrays.asList(sslEngine.getEnabledProtocols()));
-                    LOG.debug("Enabled cipher suites:{}", Arrays.asList(sslEngine.getEnabledCipherSuites()));
-                }
+            if (LOG.isDebugEnabled()) {
+                LOG.debug("Enabled protocols: {}", Arrays.asList(sslEngine.getEnabledProtocols()));
+                LOG.debug("Enabled cipher suites:{}", Arrays.asList(sslEngine.getEnabledCipherSuites()));
             }
-
-        }, new SSLSessionVerifier() {
-
-            @Override
-            public TlsDetails verify(final NamedEndpoint endpoint, final SSLEngine sslEngine) throws SSLException {
-                verifySession(host.getHostName(), sslEngine.getSession());
-                final TlsDetails tlsDetails = createTlsDetails(sslEngine);
-                final String negotiatedCipherSuite = sslEngine.getSession().getCipherSuite();
-                if (tlsDetails != null && ApplicationProtocol.HTTP_2.id.equals(tlsDetails.getApplicationProtocol())) {
-                    if (TlsCiphers.isH2Blacklisted(negotiatedCipherSuite)) {
-                        throw new SSLHandshakeException("Cipher suite `" + negotiatedCipherSuite
-                            + "` does not provide adequate security for HTTP/2");
-                    }
+        }, (endpoint, sslEngine) -> {
+            verifySession(host.getHostName(), sslEngine.getSession());
+            final TlsDetails tlsDetails = createTlsDetails(sslEngine);
+            final String negotiatedCipherSuite = sslEngine.getSession().getCipherSuite();
+            if (tlsDetails != null && ApplicationProtocol.HTTP_2.id.equals(tlsDetails.getApplicationProtocol())) {
+                if (TlsCiphers.isH2Blacklisted(negotiatedCipherSuite)) {
+                    throw new SSLHandshakeException("Cipher suite `" + negotiatedCipherSuite
+                        + "` does not provide adequate security for HTTP/2");
                 }
-                return tlsDetails;
             }
-
+            return tlsDetails;
         }, handshakeTimeout);
         return true;
     }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ClientTlsStrategyBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ClientTlsStrategyBuilder.java
index 475a695..52657e3 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ClientTlsStrategyBuilder.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ClientTlsStrategyBuilder.java
@@ -171,14 +171,11 @@ public class ClientTlsStrategyBuilder {
         if (tlsDetailsFactory != null) {
             tlsDetailsFactoryCopy = tlsDetailsFactory;
         } else {
-            tlsDetailsFactoryCopy = new Factory<SSLEngine, TlsDetails>() {
-                @Override
-                public TlsDetails create(final SSLEngine sslEngine) {
-                    final SSLSession sslSession = sslEngine.getSession();
-                    final String applicationProtocol = ReflectionUtils.callGetter(sslEngine,
-                        "ApplicationProtocol", String.class);
-                    return new TlsDetails(sslSession, applicationProtocol);
-                }
+            tlsDetailsFactoryCopy = sslEngine -> {
+                final SSLSession sslSession = sslEngine.getSession();
+                final String applicationProtocol = ReflectionUtils.callGetter(sslEngine,
+                    "ApplicationProtocol", String.class);
+                return new TlsDetails(sslSession, applicationProtocol);
             };
         }
         return new DefaultClientTlsStrategy(
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ConscryptClientTlsStrategy.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ConscryptClientTlsStrategy.java
index e446b08..16d0e7d 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ConscryptClientTlsStrategy.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/ConscryptClientTlsStrategy.java
@@ -109,7 +109,7 @@ public class ConscryptClientTlsStrategy extends AbstractClientTlsStrategy {
         try {
             final Class<?> clazz = Class.forName("org.conscrypt.Conscrypt");
             final Method method = clazz.getMethod("isAvailable");
-            return (Boolean) method.invoke(null);
+            return ((Boolean) method.invoke(null)).booleanValue();
         } catch (final ClassNotFoundException | NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
             return false;
         }
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/HttpsSupport.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/HttpsSupport.java
index e958a34..7791643 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/HttpsSupport.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/HttpsSupport.java
@@ -50,14 +50,7 @@ public final class HttpsSupport {
     }
 
     private static String getProperty(final String key) {
-        return AccessController.doPrivileged(new PrivilegedAction<String>() {
-
-            @Override
-            public String run() {
-                return System.getProperty(key);
-            }
-
-        });
+        return AccessController.doPrivileged((PrivilegedAction<String>) () -> System.getProperty(key));
     }
 
     public static String[] getSystemProtocols() {
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
index 87db974..2a29e91 100644
--- a/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
+++ b/httpclient5/src/main/java/org/apache/hc/client5/http/ssl/SSLConnectionSocketFactory.java
@@ -213,12 +213,9 @@ public class SSLConnectionSocketFactory implements LayeredConnectionSocketFactor
             // Run this under a doPrivileged to support lib users that run under a SecurityManager this allows granting connect permissions
             // only to this library
             try {
-                AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
-                    @Override
-                    public Object run() throws IOException {
-                        sock.connect(remoteAddress, connectTimeout != null ? connectTimeout.toMillisecondsIntBound() : 0);
-                        return null;
-                    }
+                AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
+                    sock.connect(remoteAddress, connectTimeout != null ? connectTimeout.toMillisecondsIntBound() : 0);
+                    return null;
                 });
             } catch (final PrivilegedActionException e) {
                 Asserts.check(e.getCause() instanceof  IOException,
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/TestDecompressingEntity.java b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/TestDecompressingEntity.java
index 745d518..5384b6b 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/TestDecompressingEntity.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/TestDecompressingEntity.java
@@ -29,7 +29,6 @@ package org.apache.hc.client5.http.entity;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
-import java.io.IOException;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.zip.CRC32;
@@ -95,14 +94,7 @@ public class TestDecompressingEntity {
     static class ChecksumEntity extends DecompressingEntity {
 
         public ChecksumEntity(final HttpEntity wrapped, final Checksum checksum) {
-            super(wrapped, new InputStreamFactory() {
-
-                @Override
-                public InputStream create(final InputStream inStream) throws IOException {
-                    return new CheckedInputStream(inStream, checksum);
-                }
-
-            });
+            super(wrapped, inStream -> new CheckedInputStream(inStream, checksum));
         }
 
     }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
index 08128cc..34176e4 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientCustomSSL.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.http.examples;
 
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.concurrent.Future;
 
@@ -50,7 +49,6 @@ import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.ssl.SSLContexts;
-import org.apache.hc.core5.ssl.TrustStrategy;
 
 /**
  * This example demonstrates how to create secure connections with a custom SSL
@@ -61,16 +59,9 @@ public class AsyncClientCustomSSL {
     public static void main(final String[] args) throws Exception {
         // Trust standard CA and those trusted by our custom strategy
         final SSLContext sslcontext = SSLContexts.custom()
-                .loadTrustMaterial(new TrustStrategy() {
-
-                    @Override
-                    public boolean isTrusted(
-                            final X509Certificate[] chain,
-                            final String authType) throws CertificateException {
-                        final X509Certificate cert = chain[0];
-                        return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
-                    }
-
+                .loadTrustMaterial((chain, authType) -> {
+                    final X509Certificate cert = chain[0];
+                    return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
                 })
                 .build();
         final TlsStrategy tlsStrategy = ClientTlsStrategyBuilder.create()
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientH2ServerPush.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientH2ServerPush.java
index 7e3af51..2881d9b 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientH2ServerPush.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientH2ServerPush.java
@@ -35,14 +35,12 @@ import org.apache.hc.client5.http.async.methods.AbstractBinPushConsumer;
 import org.apache.hc.client5.http.async.methods.AbstractCharResponseConsumer;
 import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.message.StatusLine;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.support.BasicRequestBuilder;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
@@ -74,43 +72,36 @@ public class AsyncClientH2ServerPush {
 
         client.start();
 
-        client.register("*", new Supplier<AsyncPushConsumer>() {
+        client.register("*", () -> new AbstractBinPushConsumer() {
 
             @Override
-            public AsyncPushConsumer get() {
-                return new AbstractBinPushConsumer() {
-
-                    @Override
-                    protected void start(
-                            final HttpRequest promise,
-                            final HttpResponse response,
-                            final ContentType contentType) throws HttpException, IOException {
-                        System.out.println(promise.getPath() + " (push)->" + new StatusLine(response));
-                    }
-
-                    @Override
-                    protected int capacityIncrement() {
-                        return Integer.MAX_VALUE;
-                    }
+            protected void start(
+                    final HttpRequest promise,
+                    final HttpResponse response,
+                    final ContentType contentType) throws HttpException, IOException {
+                System.out.println(promise.getPath() + " (push)->" + new StatusLine(response));
+            }
 
-                    @Override
-                    protected void data(final ByteBuffer data, final boolean endOfStream) throws IOException {
-                    }
+            @Override
+            protected int capacityIncrement() {
+                return Integer.MAX_VALUE;
+            }
 
-                    @Override
-                    protected void completed() {
-                    }
+            @Override
+            protected void data(final ByteBuffer data, final boolean endOfStream) throws IOException {
+            }
 
-                    @Override
-                    public void failed(final Exception cause) {
-                        System.out.println("(push)->" + cause);
-                    }
+            @Override
+            protected void completed() {
+            }
 
-                    @Override
-                    public void releaseResources() {
-                    }
+            @Override
+            public void failed(final Exception cause) {
+                System.out.println("(push)->" + cause);
+            }
 
-                };
+            @Override
+            public void releaseResources() {
             }
 
         });
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
index 70d2344..1834794 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientInterceptors.java
@@ -33,9 +33,6 @@ import java.nio.charset.StandardCharsets;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.apache.hc.client5.http.async.AsyncExecCallback;
-import org.apache.hc.client5.http.async.AsyncExecChain;
-import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
@@ -55,7 +52,6 @@ import org.apache.hc.core5.http.impl.BasicEntityDetails;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.http.nio.AsyncDataConsumer;
-import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -93,29 +89,19 @@ public class AsyncClientInterceptors {
 
                 // Simulate a 404 response for some requests without passing the message down to the backend
 
-                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
-
-                    @Override
-                    public void execute(
-                            final HttpRequest request,
-                            final AsyncEntityProducer requestEntityProducer,
-                            final AsyncExecChain.Scope scope,
-                            final AsyncExecChain chain,
-                            final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
-                        final Header idHeader = request.getFirstHeader("request-id");
-                        if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
-                            final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
-                            final ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
-                            final AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
-                                    response,
-                                    new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
-                            asyncDataConsumer.consume(content);
-                            asyncDataConsumer.streamEnd(null);
-                        } else {
-                            chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
-                        }
+                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, requestEntityProducer, scope, chain, asyncExecCallback) -> {
+                    final Header idHeader = request.getFirstHeader("request-id");
+                    if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
+                        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
+                        final ByteBuffer content = ByteBuffer.wrap("bad luck".getBytes(StandardCharsets.US_ASCII));
+                        final AsyncDataConsumer asyncDataConsumer = asyncExecCallback.handleResponse(
+                                response,
+                                new BasicEntityDetails(content.remaining(), ContentType.TEXT_PLAIN));
+                        asyncDataConsumer.consume(content);
+                        asyncDataConsumer.streamEnd(null);
+                    } else {
+                        chain.proceed(request, requestEntityProducer, scope, asyncExecCallback);
                     }
-
                 })
 
                 .build();
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
index da832a3..09e9c45 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/AsyncClientMessageTrailers.java
@@ -27,12 +27,8 @@
 
 package org.apache.hc.client5.http.examples;
 
-import java.io.IOException;
 import java.util.concurrent.Future;
 
-import org.apache.hc.client5.http.async.AsyncExecCallback;
-import org.apache.hc.client5.http.async.AsyncExecChain;
-import org.apache.hc.client5.http.async.AsyncExecChainHandler;
 import org.apache.hc.client5.http.async.methods.SimpleHttpRequest;
 import org.apache.hc.client5.http.async.methods.SimpleHttpResponse;
 import org.apache.hc.client5.http.async.methods.SimpleRequestBuilder;
@@ -43,10 +39,7 @@ import org.apache.hc.client5.http.impl.async.CloseableHttpAsyncClient;
 import org.apache.hc.client5.http.impl.async.HttpAsyncClients;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.HttpException;
-import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.message.StatusLine;
-import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -66,23 +59,13 @@ public class AsyncClientMessageTrailers {
 
         final CloseableHttpAsyncClient client = HttpAsyncClients.custom()
                 .setIOReactorConfig(ioReactorConfig)
-                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new AsyncExecChainHandler() {
-
-                    @Override
-                    public void execute(
-                            final HttpRequest request,
-                            final AsyncEntityProducer entityProducer,
-                            final AsyncExecChain.Scope scope,
-                            final AsyncExecChain chain,
-                            final AsyncExecCallback asyncExecCallback) throws HttpException, IOException {
-                        // Send MD5 hash in a trailer by decorating the original entity producer
-                        chain.proceed(
-                                request,
-                                entityProducer != null ? new DigestingEntityProducer("MD5", entityProducer) : null,
-                                scope,
-                                asyncExecCallback);
-                    }
-
+                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, entityProducer, scope, chain, asyncExecCallback) -> {
+                    // Send MD5 hash in a trailer by decorating the original entity producer
+                    chain.proceed(
+                            request,
+                            entityProducer != null ? new DigestingEntityProducer("MD5", entityProducer) : null,
+                            scope,
+                            asyncExecCallback);
                 })
                 .build();
 
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java
index 20432d4..b9c2025 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientCustomSSL.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.http.examples;
 
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 
 import javax.net.ssl.SSLContext;
@@ -44,7 +43,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.ssl.TLS;
 import org.apache.hc.core5.ssl.SSLContexts;
-import org.apache.hc.core5.ssl.TrustStrategy;
 
 /**
  * This example demonstrates how to create secure connections with a custom SSL
@@ -55,16 +53,9 @@ public class ClientCustomSSL {
     public final static void main(final String[] args) throws Exception {
         // Trust standard CA and those trusted by our custom strategy
         final SSLContext sslcontext = SSLContexts.custom()
-                .loadTrustMaterial(new TrustStrategy() {
-
-                    @Override
-                    public boolean isTrusted(
-                            final X509Certificate[] chain,
-                            final String authType) throws CertificateException {
-                        final X509Certificate cert = chain[0];
-                        return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
-                    }
-
+                .loadTrustMaterial((chain, authType) -> {
+                    final X509Certificate cert = chain[0];
+                    return "CN=httpbin.org".equalsIgnoreCase(cert.getSubjectDN().getName());
                 })
                 .build();
         // Allow TLSv1.2 protocol only
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientInterceptors.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientInterceptors.java
index 340aa93..61514b0 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientInterceptors.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientInterceptors.java
@@ -30,14 +30,11 @@ package org.apache.hc.client5.http.examples;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicLong;
 
-import org.apache.hc.client5.http.classic.ExecChain;
-import org.apache.hc.client5.http.classic.ExecChainHandler;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.ChainElement;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
 import org.apache.hc.client5.http.impl.classic.HttpClients;
-import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EntityDetails;
@@ -77,24 +74,16 @@ public class ClientInterceptors {
 
                 // Simulate a 404 response for some requests without passing the message down to the backend
 
-                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", new ExecChainHandler() {
+                .addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "custom", (request, scope, chain) -> {
 
-                    @Override
-                    public ClassicHttpResponse execute(
-                            final ClassicHttpRequest request,
-                            final ExecChain.Scope scope,
-                            final ExecChain chain) throws IOException, HttpException {
-
-                        final Header idHeader = request.getFirstHeader("request-id");
-                        if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
-                            final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
-                            response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN));
-                            return response;
-                        } else {
-                            return chain.proceed(request, scope);
-                        }
+                    final Header idHeader = request.getFirstHeader("request-id");
+                    if (idHeader != null && "13".equalsIgnoreCase(idHeader.getValue())) {
+                        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_NOT_FOUND, "Oppsie");
+                        response.setEntity(new StringEntity("bad luck", ContentType.TEXT_PLAIN));
+                        return response;
+                    } else {
+                        return chain.proceed(request, scope);
                     }
-
                 })
                 .build()) {
 
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
index 0601c77..0f3b3aa 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithRequestFuture.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.client5.http.examples;
 
-import java.io.IOException;
 import java.util.concurrent.CancellationException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -41,7 +40,6 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
 import org.apache.hc.client5.http.io.HttpClientConnectionManager;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.io.HttpClientResponseHandler;
 
@@ -60,12 +58,9 @@ public class ClientWithRequestFuture {
         try (final FutureRequestExecutionService requestExecService = new FutureRequestExecutionService(
                 httpclient, execService)) {
             // Because things are asynchronous, you must provide a HttpClientResponseHandler
-            final HttpClientResponseHandler<Boolean> handler = new HttpClientResponseHandler<Boolean>() {
-                @Override
-                public Boolean handleResponse(final ClassicHttpResponse response) throws IOException {
-                    // simply return true if the status was OK
-                    return response.getCode() == HttpStatus.SC_OK;
-                }
+            final HttpClientResponseHandler<Boolean> handler = response -> {
+                // simply return true if the status was OK
+                return response.getCode() == HttpStatus.SC_OK;
             };
 
             // Simple request ...
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
index 1ea4d6f..d9a4406 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ClientWithResponseHandler.java
@@ -27,13 +27,10 @@
 
 package org.apache.hc.client5.http.examples;
 
-import java.io.IOException;
-
 import org.apache.hc.client5.http.ClientProtocolException;
 import org.apache.hc.client5.http.classic.methods.HttpGet;
 import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
 import org.apache.hc.client5.http.impl.classic.HttpClients;
-import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.ParseException;
@@ -53,24 +50,18 @@ public class ClientWithResponseHandler {
             System.out.println("Executing request " + httpget.getMethod() + " " + httpget.getUri());
 
             // Create a custom response handler
-            final HttpClientResponseHandler<String> responseHandler = new HttpClientResponseHandler<String>() {
-
-                @Override
-                public String handleResponse(
-                        final ClassicHttpResponse response) throws IOException {
-                    final int status = response.getCode();
-                    if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
-                        final HttpEntity entity = response.getEntity();
-                        try {
-                            return entity != null ? EntityUtils.toString(entity) : null;
-                        } catch (final ParseException ex) {
-                            throw new ClientProtocolException(ex);
-                        }
-                    } else {
-                        throw new ClientProtocolException("Unexpected response status: " + status);
+            final HttpClientResponseHandler<String> responseHandler = response -> {
+                final int status = response.getCode();
+                if (status >= HttpStatus.SC_SUCCESS && status < HttpStatus.SC_REDIRECTION) {
+                    final HttpEntity entity = response.getEntity();
+                    try {
+                        return entity != null ? EntityUtils.toString(entity) : null;
+                    } catch (final ParseException ex) {
+                        throw new ClientProtocolException(ex);
                     }
+                } else {
+                    throw new ClientProtocolException("Unexpected response status: " + status);
                 }
-
             };
             final String responseBody = httpclient.execute(httpget, responseHandler);
             System.out.println("----------------------------------------");
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ReactiveClientFullDuplexExchange.java b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ReactiveClientFullDuplexExchange.java
index 222ec0e..9bb6630 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ReactiveClientFullDuplexExchange.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/examples/ReactiveClientFullDuplexExchange.java
@@ -50,10 +50,7 @@ import org.apache.hc.core5.util.Timeout;
 import org.reactivestreams.Publisher;
 
 import io.reactivex.Flowable;
-import io.reactivex.Notification;
 import io.reactivex.Observable;
-import io.reactivex.functions.Consumer;
-import io.reactivex.functions.Function;
 
 /**
  * This example demonstrates a reactive, full-duplex HTTP/1.1 message exchange using RxJava.
@@ -92,21 +89,13 @@ public class ReactiveClientFullDuplexExchange {
         System.out.println();
 
         Observable.fromPublisher(streamingResponse.getBody())
-            .map(new Function<ByteBuffer, String>() {
-                @Override
-                public String apply(final ByteBuffer byteBuffer) throws Exception {
-                    final byte[] string = new byte[byteBuffer.remaining()];
-                    byteBuffer.get(string);
-                    return new String(string);
-                }
+            .map(byteBuffer -> {
+                final byte[] string = new byte[byteBuffer.remaining()];
+                byteBuffer.get(string);
+                return new String(string);
             })
             .materialize()
-            .forEach(new Consumer<Notification<String>>() {
-                @Override
-                public void accept(final Notification<String> byteBufferNotification) throws Exception {
-                    System.out.println(byteBufferNotification);
-                }
-            });
+            .forEach(System.out::println);
 
         requestFuture.get(1, TimeUnit.MINUTES);
 
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
index 0d977dc..7d0fc15 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/MockConnPoolControl.java
@@ -82,14 +82,14 @@ public final class MockConnPoolControl implements ConnPoolControl<HttpRoute> {
 
     @Override
     public void setMaxPerRoute(final HttpRoute route, final int max) {
-        this.maxPerHostMap.put(route, Integer.valueOf(max));
+        this.maxPerHostMap.put(route, max);
     }
 
     @Override
     public int getMaxPerRoute(final HttpRoute route) {
         final Integer max = this.maxPerHostMap.get(route);
         if (max != null) {
-            return max.intValue();
+            return max;
         } else {
             return this.defaultMax;
         }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
index 82dd8fe..29ad749 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestConnectExec.java
@@ -36,9 +36,9 @@ import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.RouteInfo;
 import org.apache.hc.client5.http.auth.AuthChallenge;
 import org.apache.hc.client5.http.auth.AuthScheme;
-import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.AuthScope;
 import org.apache.hc.client5.http.auth.ChallengeType;
+import org.apache.hc.client5.http.auth.StandardAuthScheme;
 import org.apache.hc.client5.http.auth.UsernamePasswordCredentials;
 import org.apache.hc.client5.http.classic.ExecChain;
 import org.apache.hc.client5.http.classic.ExecRuntime;
@@ -67,7 +67,6 @@ import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 @SuppressWarnings({"boxing","static-access"}) // test code
@@ -343,29 +342,17 @@ public class TestConnectExec {
 
         private boolean connected;
 
-        public Answer connectAnswer() {
-
-            return new Answer() {
-
-                @Override
-                public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                    connected = true;
-                    return null;
-                }
+        public Answer<?> connectAnswer() {
 
+            return invocationOnMock -> {
+                connected = true;
+                return null;
             };
         }
 
         public Answer<Boolean> isConnectedAnswer() {
 
-            return new Answer<Boolean>() {
-
-                @Override
-                public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                    return connected;
-                }
-
-            };
+            return invocationOnMock -> connected;
 
         }
     }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
index e7686ad..61d6b4b 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestFutureRequestExecutionService.java
@@ -45,14 +45,10 @@ import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuil
 import org.apache.hc.client5.http.io.HttpClientConnectionManager;
 import org.apache.hc.client5.http.protocol.HttpClientContext;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.HttpClientResponseHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.hamcrest.CoreMatchers;
 import org.junit.After;
 import org.junit.Assert;
@@ -76,23 +72,16 @@ public class TestFutureRequestExecutionService {
     @Before
     public void before() throws Exception {
         this.localServer = ServerBootstrap.bootstrap()
-                .register("/wait", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                try {
-                    while(blocked.get()) {
-                        Thread.sleep(10);
+                .register("/wait", (request, response, context) -> {
+                    try {
+                        while(blocked.get()) {
+                            Thread.sleep(10);
+                        }
+                    } catch (final InterruptedException e) {
+                        throw new IllegalStateException(e);
                     }
-                } catch (final InterruptedException e) {
-                    throw new IllegalStateException(e);
-                }
-                response.setCode(200);
-            }
-        }).create();
+                    response.setCode(200);
+                }).create();
 
         this.localServer.start();
         uri = "http://localhost:" + this.localServer.getLocalPort() + "/wait";
@@ -117,7 +106,7 @@ public class TestFutureRequestExecutionService {
     public void shouldExecuteSingleCall() throws InterruptedException, ExecutionException {
         final FutureTask<Boolean> task = httpAsyncClientWithFuture.execute(
             new HttpGet(uri), HttpClientContext.create(), new OkidokiHandler());
-        Assert.assertTrue("request should have returned OK", task.get().booleanValue());
+        Assert.assertTrue("request should have returned OK", task.get());
     }
 
     @Test
@@ -154,7 +143,7 @@ public class TestFutureRequestExecutionService {
         for (final Future<Boolean> task : tasks) {
             final Boolean b = task.get();
             Assert.assertNotNull(b);
-            Assert.assertTrue("request should have returned OK", b.booleanValue());
+            Assert.assertTrue("request should have returned OK", b);
         }
     }
 
@@ -173,7 +162,7 @@ public class TestFutureRequestExecutionService {
         for (final Future<Boolean> task : tasks) {
             final Boolean b = task.get();
             Assert.assertNotNull(b);
-            Assert.assertTrue("request should have returned OK", b.booleanValue());
+            Assert.assertTrue("request should have returned OK", b);
         }
     }
 
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpClientBuilderInterceptors.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpClientBuilderInterceptors.java
index 83f6928..bbce383 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpClientBuilderInterceptors.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpClientBuilderInterceptors.java
@@ -28,9 +28,6 @@ package org.apache.hc.client5.http.impl.classic;
 
 import java.io.IOException;
 
-import org.apache.hc.client5.http.classic.ExecChain;
-import org.apache.hc.client5.http.classic.ExecChainHandler;
-import org.apache.hc.client5.http.classic.ExecChain.Scope;
 import org.apache.hc.client5.http.classic.methods.HttpPost;
 import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManagerBuilder;
 import org.apache.hc.client5.http.io.HttpClientConnectionManager;
@@ -40,8 +37,6 @@ import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.CloseMode;
 import org.junit.After;
 import org.junit.Assert;
@@ -58,20 +53,13 @@ public class TestHttpClientBuilderInterceptors {
     @Before
     public void before() throws Exception {
         this.localServer = ServerBootstrap.bootstrap()
-                .register("/test", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                final Header testInterceptorHeader = request.getHeader("X-Test-Interceptor");
-                if (testInterceptorHeader != null) {
-                    response.setHeader(testInterceptorHeader);
-                }
-                response.setCode(200);
-            }
-        }).create();
+                .register("/test", (request, response, context) -> {
+                    final Header testInterceptorHeader = request.getHeader("X-Test-Interceptor");
+                    if (testInterceptorHeader != null) {
+                        response.setHeader(testInterceptorHeader);
+                    }
+                    response.setCode(200);
+                }).create();
 
         this.localServer.start();
         uri = "http://localhost:" + this.localServer.getLocalPort() + "/test";
@@ -80,16 +68,9 @@ public class TestHttpClientBuilderInterceptors {
                 .build();
         httpClient = HttpClientBuilder.create()
                 .setConnectionManager(cm)
-                .addExecInterceptorLast("test-interceptor", new ExecChainHandler() {
-
-                    @Override
-                    public ClassicHttpResponse execute(
-                            final ClassicHttpRequest request,
-                            final Scope scope,
-                            final ExecChain chain) throws IOException, HttpException {
-                        request.setHeader("X-Test-Interceptor", "active");
-                        return chain.proceed(request, scope);
-                    }
+                .addExecInterceptorLast("test-interceptor", (request, scope, chain) -> {
+                    request.setHeader("X-Test-Interceptor", "active");
+                    return chain.proceed(request, scope);
                 })
                 .build();
     }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpRequestRetryExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpRequestRetryExec.java
index 2c3e919..223de81 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpRequestRetryExec.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestHttpRequestRetryExec.java
@@ -55,8 +55,6 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
 
 @SuppressWarnings({"boxing","static-access"}) // test code
 public class TestHttpRequestRetryExec {
@@ -231,21 +229,16 @@ public class TestHttpRequestRetryExec {
 
         Mockito.when(chain.proceed(
                 Mockito.<ClassicHttpRequest>any(),
-                Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
-
-            @Override
-            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                final Object[] args = invocationOnMock.getArguments();
-                final ClassicHttpRequest wrapper = (ClassicHttpRequest) args[0];
-                final Header[] headers = wrapper.getHeaders();
-                Assert.assertEquals(2, headers.length);
-                Assert.assertEquals("this", headers[0].getValue());
-                Assert.assertEquals("that", headers[1].getValue());
-                wrapper.addHeader("Cookie", "monster");
-                throw new IOException("Ka-boom");
-            }
-
-        });
+                Mockito.<ExecChain.Scope>any())).thenAnswer(invocationOnMock -> {
+                    final Object[] args = invocationOnMock.getArguments();
+                    final ClassicHttpRequest wrapper = (ClassicHttpRequest) args[0];
+                    final Header[] headers = wrapper.getHeaders();
+                    Assert.assertEquals(2, headers.length);
+                    Assert.assertEquals("this", headers[0].getValue());
+                    Assert.assertEquals("that", headers[1].getValue());
+                    wrapper.addHeader("Cookie", "monster");
+                    throw new IOException("Ka-boom");
+                });
         Mockito.when(retryStrategy.retryRequest(
                 Mockito.<HttpRequest>any(),
                 Mockito.<IOException>any(),
@@ -304,17 +297,12 @@ public class TestHttpRequestRetryExec {
 
         Mockito.when(chain.proceed(
                 Mockito.<ClassicHttpRequest>any(),
-                Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<Object>() {
-
-            @Override
-            public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                final Object[] args = invocationOnMock.getArguments();
-                final ClassicHttpRequest req = (ClassicHttpRequest) args[0];
-                req.getEntity().writeTo(new ByteArrayOutputStream());
-                throw new IOException("Ka-boom");
-            }
-
-        });
+                Mockito.<ExecChain.Scope>any())).thenAnswer(invocationOnMock -> {
+                    final Object[] args = invocationOnMock.getArguments();
+                    final ClassicHttpRequest req = (ClassicHttpRequest) args[0];
+                    req.getEntity().writeTo(new ByteArrayOutputStream());
+                    throw new IOException("Ka-boom");
+                });
         Mockito.when(retryStrategy.retryRequest(
                 Mockito.<HttpRequest>any(),
                 Mockito.<IOException>any(),
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
index 1e12916..35e4ce4 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestMainClientExec.java
@@ -53,7 +53,6 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 @SuppressWarnings({"boxing","static-access"}) // test code
@@ -330,29 +329,17 @@ public class TestMainClientExec {
 
         private boolean connected;
 
-        public Answer connectAnswer() {
-
-            return new Answer() {
-
-                @Override
-                public Object answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                    connected = true;
-                    return null;
-                }
+        public Answer<?> connectAnswer() {
 
+            return invocationOnMock -> {
+                connected = true;
+                return null;
             };
         }
 
         public Answer<Boolean> isConnectedAnswer() {
 
-            return new Answer<Boolean>() {
-
-                @Override
-                public Boolean answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                    return connected;
-                }
-
-            };
+            return invocationOnMock -> connected;
 
         }
     }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
index f410d3d..c560bbc 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/classic/TestProtocolExec.java
@@ -70,7 +70,6 @@ import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.Mockito;
 import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
 import org.mockito.stubbing.Answer;
 
 @SuppressWarnings({"static-access"}) // test code
@@ -317,17 +316,12 @@ public class TestProtocolExec {
 
         Mockito.when(chain.proceed(
                 Mockito.same(request),
-                Mockito.<ExecChain.Scope>any())).thenAnswer(new Answer<HttpResponse>() {
-
-            @Override
-            public HttpResponse answer(final InvocationOnMock invocationOnMock) throws Throwable {
-                final Object[] args = invocationOnMock.getArguments();
-                final ClassicHttpRequest requestEE = (ClassicHttpRequest) args[0];
-                requestEE.getEntity().writeTo(new ByteArrayOutputStream());
-                return response1;
-            }
-
-        });
+                Mockito.<ExecChain.Scope>any())).thenAnswer((Answer<HttpResponse>) invocationOnMock -> {
+                    final Object[] args = invocationOnMock.getArguments();
+                    final ClassicHttpRequest requestEE = (ClassicHttpRequest) args[0];
+                    requestEE.getEntity().writeTo(new ByteArrayOutputStream());
+                    return response1;
+                });
 
         Mockito.when(targetAuthStrategy.select(
                 Mockito.eq(ChallengeType.TARGET),
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/routing/TestRouteTracker.java b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/routing/TestRouteTracker.java
index 8907bdd..ef4fd76 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/impl/routing/TestRouteTracker.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/impl/routing/TestRouteTracker.java
@@ -438,19 +438,19 @@ public class TestRouteTracker {
         Assert.assertTrue(hs.add(rt4));
         Assert.assertTrue(hs.add(rt6));
 
-        Assert.assertTrue(hc0.add(Integer.valueOf(rt0.hashCode())));
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt4.hashCode())));
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt6.hashCode())));
+        Assert.assertTrue(hc0.add(rt0.hashCode()));
+        Assert.assertTrue(hc4.add(rt4.hashCode()));
+        Assert.assertTrue(hc6.add(rt6.hashCode()));
 
         rt = (RouteTracker) rt0.clone();
         rt.connectTarget(false);
         Assert.assertTrue(hs.add(rt));
-        Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc0.add(rt.hashCode()));
 
         rt = (RouteTracker) rt0.clone();
         rt.connectTarget(true);
         Assert.assertTrue(hs.add(rt));
-        Assert.assertTrue(hc0.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc0.add(rt.hashCode()));
 
 
         // proxy (insecure) -> tunnel (insecure) -> layer (secure)
@@ -458,15 +458,15 @@ public class TestRouteTracker {
         rt.connectProxy(PROXY1, false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
         rt.tunnelTarget(false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
         rt.layerProtocol(true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
 
         // proxy (secure) -> tunnel (secure) -> layer (insecure)
@@ -474,15 +474,15 @@ public class TestRouteTracker {
         rt.connectProxy(PROXY1, true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
         rt.tunnelTarget(true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
         rt.layerProtocol(false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc4.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc4.add(rt.hashCode()));
 
 
         // PROXY1/i -> PROXY2/i -> tunnel/i -> layer/s
@@ -490,20 +490,20 @@ public class TestRouteTracker {
         rt.connectProxy(PROXY1, false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.tunnelProxy(PROXY2, false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.tunnelTarget(false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.layerProtocol(true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
 
         // PROXY1/s -> PROXY2/s -> tunnel/s -> layer/i
@@ -511,20 +511,20 @@ public class TestRouteTracker {
         rt.connectProxy(PROXY1, true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.tunnelProxy(PROXY2, true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.tunnelTarget(true);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.layerProtocol(false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
 
         // PROXY2/i -> PROXY1/i -> tunnel/i -> layer/s
@@ -532,7 +532,7 @@ public class TestRouteTracker {
         rt.connectProxy(PROXY2, false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
         // this is not guaranteed to be unique...
-        Assert.assertTrue(hc6.add(Integer.valueOf(rt.hashCode())));
+        Assert.assertTrue(hc6.add(rt.hashCode()));
 
         rt.tunnelProxy(PROXY1, false);
         Assert.assertTrue(hs.add((RouteTracker) rt.clone()));
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/routing/TestHttpRoute.java b/httpclient5/src/test/java/org/apache/hc/client5/http/routing/TestHttpRoute.java
index c541124..c1603c1 100644
--- a/httpclient5/src/test/java/org/apache/hc/client5/http/routing/TestHttpRoute.java
+++ b/httpclient5/src/test/java/org/apache/hc/client5/http/routing/TestHttpRoute.java
@@ -29,7 +29,6 @@ package org.apache.hc.client5.http.routing;
 
 import java.net.InetAddress;
 import java.util.HashSet;
-import java.util.Iterator;
 import java.util.Set;
 
 import org.apache.hc.client5.http.HttpRoute;
@@ -201,14 +200,14 @@ public class TestHttpRoute {
         // we can't test hashCode in general due to its dependency
         // on InetAddress and HttpHost, but we can check for the flags
         final Set<Integer> routecodes = new HashSet<>();
-        routecodes.add(Integer.valueOf(routefff.hashCode()));
-        routecodes.add(Integer.valueOf(routefft.hashCode()));
-        routecodes.add(Integer.valueOf(routeftf.hashCode()));
-        routecodes.add(Integer.valueOf(routeftt.hashCode()));
-        routecodes.add(Integer.valueOf(routetff.hashCode()));
-        routecodes.add(Integer.valueOf(routetft.hashCode()));
-        routecodes.add(Integer.valueOf(routettf.hashCode()));
-        routecodes.add(Integer.valueOf(routettt.hashCode()));
+        routecodes.add(routefff.hashCode());
+        routecodes.add(routefft.hashCode());
+        routecodes.add(routeftf.hashCode());
+        routecodes.add(routeftt.hashCode());
+        routecodes.add(routetff.hashCode());
+        routecodes.add(routetft.hashCode());
+        routecodes.add(routettf.hashCode());
+        routecodes.add(routettt.hashCode());
         Assert.assertEquals("some flagged routes have same hashCode",
                      8, routecodes.size());
 
@@ -394,9 +393,7 @@ public class TestHttpRoute {
         Assert.assertEquals("some routes are equal", 11, routes.size());
 
         // and a run of cloning over the set
-        final Iterator<HttpRoute> iter = routes.iterator();
-        while (iter.hasNext()) {
-            final HttpRoute origin = iter.next();
+        for (final HttpRoute origin : routes) {
             final HttpRoute cloned = (HttpRoute) origin.clone();
             Assert.assertEquals("clone of " + origin, origin, cloned);
             Assert.assertTrue("clone of " + origin, routes.contains(cloned));
diff --git a/pom.xml b/pom.xml
index 0b3fb32..a547b46 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,8 +60,8 @@
   </distributionManagement>
 
   <properties>
-    <maven.compiler.source>1.7</maven.compiler.source>
-    <maven.compiler.target>1.7</maven.compiler.target>
+    <maven.compiler.source>1.8</maven.compiler.source>
+    <maven.compiler.target>1.8</maven.compiler.target>
     <httpcore.version>5.1</httpcore.version>
     <log4j.version>2.9.1</log4j.version>
     <commons-codec.version>1.15</commons-codec.version>

Re: [httpcomponents-client] 01/04: Java 1.8 upgrade

Posted by Gary Gregory <ga...@gmail.com>.
Just FYI on the commit comment, the Java diamond operator is Java 7 not 8.

Gary

On Tue, Apr 27, 2021, 07:13 <ol...@apache.org> wrote:

> This is an automated email from the ASF dual-hosted git repository.
>
> olegk pushed a commit to branch 5.2.x
> in repository
> https://gitbox.apache.org/repos/asf/httpcomponents-client.git
>
> commit 3bb88a74d2f2336dcf47df37e46dc64da19a55e0
> Author: Oleg Kalnichevski <ol...@apache.org>
> AuthorDate: Sun Dec 20 15:22:42 2020 +0100
>
>     Java 1.8 upgrade
> ---
>  .../hc/client5/http/cache/HttpCacheEntry.java      |   2 +-
>  .../AbstractSerializingAsyncCacheStorage.java      |   2 +-
>  .../client5/http/impl/cache/AsyncCachingExec.java  | 154 +++------
>  .../http/impl/cache/BasicHttpAsyncCache.java       |  19 +-
>  .../hc/client5/http/impl/cache/BasicHttpCache.java |  19 +-
>  .../client5/http/impl/cache/BasicIdGenerator.java  |   2 +-
>  .../hc/client5/http/impl/cache/CachingExec.java    |  20 +-
>  .../impl/cache/CachingH2AsyncClientBuilder.java    |  20 +-
>  .../impl/cache/CachingHttpAsyncClientBuilder.java  |  20 +-
>  .../http/impl/cache/CachingHttpClientBuilder.java  |  20 +-
>  .../impl/cache/DefaultAsyncCacheInvalidator.java   |   2 +-
>  .../impl/cache/DefaultAsyncCacheRevalidator.java   |  99 +++---
>  .../http/impl/cache/DefaultCacheRevalidator.java   |  41 +--
>  .../hc/client5/http/impl/cache/WarningValue.java   |   4 +-
>  .../memcached/MemcachedHttpAsyncCacheStorage.java  |  62 ++--
>  .../hc/client5/http/cache/TestHttpCacheEntry.java  |   2 +-
>  .../http/impl/cache/AbstractProtocolTest.java      |   2 +-
>  .../TestAbstractSerializingAsyncCacheStorage.java  | 336
> ++++++-------------
>  .../cache/TestAbstractSerializingCacheStorage.java |  95 ++----
>  .../cache/TestCachedHttpResponseGenerator.java     |   2 +-
>  .../client5/http/impl/cache/TestCachingExec.java   |   2 +-
>  .../impl/cache/TestConditionalRequestBuilder.java  |  10 +-
>  .../cache/TestDefaultAsyncCacheInvalidator.java    |  37 +-
>  .../impl/cache/TestDefaultCacheInvalidator.java    |  22 +-
>  .../memcached/TestPrefixKeyHashingScheme.java      |   9 +-
>  .../org/apache/hc/client5/http/fluent/Request.java |   2 +-
>  .../examples/fluent/FluentResponseHandling.java    |  58 ++--
>  .../AbstractHttpAsyncClientAuthentication.java     | 182 ++--------
>  .../async/AbstractHttpAsyncFundamentalsTest.java   |  19 +-
>  .../async/AbstractHttpAsyncRedirectsTest.java      | 372
> ++++++---------------
>  .../AbstractHttpReactiveFundamentalsTest.java      |  19 +-
>  .../testing/async/AbstractServerTestBase.java      |  32 +-
>  .../testing/async/TestHttp1AsyncRedirects.java     |  47 +--
>  .../TestHttp1AsyncStatefulConnManagement.java      |  63 +---
>  .../async/TestHttp1ClientAuthentication.java       |  25 +-
>  .../hc/client5/testing/fluent/TestFluent.java      |  63 +---
>  .../testing/sync/TestClientAuthentication.java     |  74 +---
>  .../testing/sync/TestClientRequestExecution.java   |  13 +-
>  .../testing/sync/TestCookieVirtualHost.java        |  87 ++---
>  .../testing/sync/TestMalformedServerResponse.java  |  29 +-
>  .../hc/client5/testing/sync/TestRedirects.java     | 328
> +++++-------------
>  .../client5/testing/sync/TestSSLSocketFactory.java |  40 +--
>  .../testing/sync/TestStatefulConnManagement.java   |  21 +-
>  .../testing/sync/TestWindowsNegotiateScheme.java   |  31 +-
>  .../apache/hc/client5/http/entity/mime/Header.java |   6 +-
>  .../client5/http/impl/IdleConnectionEvictor.java   |  25 +-
>  .../apache/hc/client5/http/impl/Operations.java    |  18 +-
>  .../impl/async/AbstractHttpAsyncClientBase.java    |   8 +-
>  .../http/impl/async/AsyncExecChainElement.java     |  14 +-
>  .../http/impl/async/H2AsyncClientBuilder.java      |  76 +----
>  .../http/impl/async/HttpAsyncClientBuilder.java    |  59 +---
>  .../client5/http/impl/async/HttpAsyncClients.java  |  23 +-
>  .../async/InternalAbstractHttpAsyncClient.java     | 302 ++++++++---------
>  .../impl/async/InternalHttpAsyncExecRuntime.java   |   9 +-
>  .../async/LoggingAsyncClientExchangeHandler.java   |  52 ++-
>  .../http/impl/async/MinimalH2AsyncClient.java      | 243 ++++++--------
>  .../http/impl/async/MinimalHttpAsyncClient.java    | 292 ++++++++--------
>  .../hc/client5/http/impl/auth/NTLMEngineImpl.java  |   2 +-
>  .../http/impl/classic/AIMDBackoffManager.java      |  12 +-
>  .../http/impl/classic/ExecChainElement.java        |  11 +-
>  .../http/impl/classic/HttpClientBuilder.java       |  31 +-
>  .../http/impl/classic/ResponseEntityProxy.java     |  19 +-
>  .../http/impl/cookie/LaxExpiresHandler.java        |   2 +-
>  .../http/impl/cookie/RFC6265CookieSpec.java        |   2 +-
>  .../nio/PoolingAsyncClientConnectionManager.java   |  18 +-
>  .../http/socket/PlainConnectionSocketFactory.java  |   9 +-
>  .../http/ssl/AbstractClientTlsStrategy.java        |  75 ++---
>  .../client5/http/ssl/ClientTlsStrategyBuilder.java |  13 +-
>  .../http/ssl/ConscryptClientTlsStrategy.java       |   2 +-
>  .../apache/hc/client5/http/ssl/HttpsSupport.java   |   9 +-
>  .../http/ssl/SSLConnectionSocketFactory.java       |   9 +-
>  .../http/entity/TestDecompressingEntity.java       |  10 +-
>  .../http/examples/AsyncClientCustomSSL.java        |  15 +-
>  .../http/examples/AsyncClientH2ServerPush.java     |  55 ++-
>  .../http/examples/AsyncClientInterceptors.java     |  38 +--
>  .../http/examples/AsyncClientMessageTrailers.java  |  31 +-
>  .../hc/client5/http/examples/ClientCustomSSL.java  |  15 +-
>  .../client5/http/examples/ClientInterceptors.java  |  27 +-
>  .../http/examples/ClientWithRequestFuture.java     |  11 +-
>  .../http/examples/ClientWithResponseHandler.java   |  29 +-
>  .../examples/ReactiveClientFullDuplexExchange.java |  21 +-
>  .../http/impl/classic/MockConnPoolControl.java     |   4 +-
>  .../client5/http/impl/classic/TestConnectExec.java |  25 +-
>  .../classic/TestFutureRequestExecutionService.java |  35 +-
>  .../classic/TestHttpClientBuilderInterceptors.java |  39 +--
>  .../impl/classic/TestHttpRequestRetryExec.java     |  44 +--
>  .../http/impl/classic/TestMainClientExec.java      |  23 +-
>  .../http/impl/classic/TestProtocolExec.java        |  18 +-
>  .../http/impl/routing/TestRouteTracker.java        |  40 +--
>  .../hc/client5/http/routing/TestHttpRoute.java     |  21 +-
>  pom.xml                                            |   4 +-
>  91 files changed, 1385 insertions(+), 2969 deletions(-)
>
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
> index ff53120..8d071d6 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/cache/HttpCacheEntry.java
> @@ -124,7 +124,7 @@ public class HttpCacheEntry implements MessageHeaders,
> Serializable {
>       */
>      public HttpCacheEntry(final Date requestDate, final Date
> responseDate, final int status,
>              final Header[] responseHeaders, final Resource resource) {
> -        this(requestDate, responseDate, status, responseHeaders,
> resource, new HashMap<String,String>());
> +        this(requestDate, responseDate, status, responseHeaders,
> resource, new HashMap<>());
>      }
>
>      /**
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
> index 0263a6d..126192b 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AbstractSerializingAsyncCacheStorage.java
> @@ -187,7 +187,7 @@ public abstract class
> AbstractSerializingAsyncCacheStorage<T, CAS> implements Ht
>
>                                  @Override
>                                  public void completed(final Boolean
> result) {
> -                                    if (result) {
> +                                    if (result.booleanValue()) {
>                                          callback.completed(result);
>                                      } else {
>                                          if
> (!complexCancellable.isCancelled()) {
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
> index 93419a7..c9001b2 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/AsyncCachingExec.java
> @@ -57,7 +57,6 @@ import org.apache.hc.core5.annotation.ThreadingBehavior;
>  import org.apache.hc.core5.concurrent.CancellableDependency;
>  import org.apache.hc.core5.concurrent.ComplexFuture;
>  import org.apache.hc.core5.concurrent.FutureCallback;
> -import org.apache.hc.core5.function.Factory;
>  import org.apache.hc.core5.http.ContentType;
>  import org.apache.hc.core5.http.EntityDetails;
>  import org.apache.hc.core5.http.Header;
> @@ -102,14 +101,8 @@ class AsyncCachingExec extends CachingExecBase
> implements AsyncExecChainHandler
>          super(config);
>          this.responseCache = Args.notNull(cache, "Response cache");
>          this.cacheRevalidator = cacheRevalidator;
> -        this.conditionalRequestBuilder = new
> ConditionalRequestBuilder<>(new Factory<HttpRequest, HttpRequest>() {
> -
> -            @Override
> -            public HttpRequest create(final HttpRequest request) {
> -                return BasicRequestBuilder.copy(request).build();
> -            }
> -
> -        });
> +        this.conditionalRequestBuilder = new
> ConditionalRequestBuilder<>(request ->
> +                BasicRequestBuilder.copy(request).build());
>      }
>
>      AsyncCachingExec(
> @@ -675,14 +668,7 @@ class AsyncCachingExec extends CachingExecBase
> implements AsyncExecChainHandler
>                      cacheRevalidator.revalidateCacheEntry(
>                              responseCache.generateKey(target, request,
> entry),
>                              asyncExecCallback,
> -                            new
> DefaultAsyncCacheRevalidator.RevalidationCall() {
> -
> -                                @Override
> -                                public void execute(final
> AsyncExecCallback asyncExecCallback) {
> -                                    revalidateCacheEntry(target, request,
> entityProducer, fork, chain, asyncExecCallback, entry);
> -                                }
> -
> -                            });
> +                            asyncExecCallback1 ->
> revalidateCacheEntry(target, request, entityProducer, fork, chain,
> asyncExecCallback1, entry));
>                      triggerResponse(cacheResponse, scope,
> asyncExecCallback);
>                  } catch (final ResourceIOException ex) {
>                      asyncExecCallback.failed(ex);
> @@ -771,26 +757,12 @@ class AsyncCachingExec extends CachingExecBase
> implements AsyncExecChainHandler
>                      recordCacheUpdate(scope.clientContext);
>                  }
>                  if (statusCode == HttpStatus.SC_NOT_MODIFIED) {
> -                    return new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                        @Override
> -                        public void run() {
> -
> triggerUpdatedCacheEntryResponse(backendResponse, responseDate);
> -                        }
> -
> -                    });
> +                    return new
> AsyncExecCallbackWrapper(asyncExecCallback, () ->
> triggerUpdatedCacheEntryResponse(backendResponse, responseDate));
>                  }
>                  if (staleIfErrorAppliesTo(statusCode)
>                          && !staleResponseNotAllowed(request, cacheEntry,
> getCurrentDate())
>                          && validityPolicy.mayReturnStaleIfError(request,
> cacheEntry, responseDate)) {
> -                    return new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                        @Override
> -                        public void run() {
> -                            triggerResponseStaleCacheEntry();
> -                        }
> -
> -                    });
> +                    return new
> AsyncExecCallbackWrapper(asyncExecCallback,
> this::triggerResponseStaleCacheEntry);
>                  }
>                  return new BackendResponseHandler(target,
> conditionalRequest, requestDate, responseDate, scope, asyncExecCallback);
>              }
> @@ -809,57 +781,49 @@ class AsyncCachingExec extends CachingExecBase
> implements AsyncExecChainHandler
>                      final HttpRequest unconditional =
> conditionalRequestBuilder.buildUnconditionalRequest(
>
>  BasicRequestBuilder.copy(scope.originalRequest).build());
>
> -                    callback1 = new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> +                    callback1 = new
> AsyncExecCallbackWrapper(asyncExecCallback, () ->
> chainProceed(unconditional, entityProducer, scope, chain, new
> AsyncExecCallback() {
>
>                          @Override
> -                        public void run() {
> -                            chainProceed(unconditional, entityProducer,
> scope, chain, new AsyncExecCallback() {
> -
> -                                @Override
> -                                public AsyncDataConsumer handleResponse(
> -                                        final HttpResponse
> backendResponse2,
> -                                        final EntityDetails
> entityDetails) throws HttpException, IOException {
> -                                    final Date responseDate2 =
> getCurrentDate();
> -                                    final AsyncExecCallback callback2 =
> evaluateResponse(backendResponse2, responseDate2);
> -                                    callbackRef.set(callback2);
> -                                    return
> callback2.handleResponse(backendResponse2, entityDetails);
> -                                }
> -
> -                                @Override
> -                                public void
> handleInformationResponse(final HttpResponse response) throws
> HttpException, IOException {
> -                                    final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> -                                    if (callback2 != null) {
> -
> callback2.handleInformationResponse(response);
> -                                    } else {
> -
> asyncExecCallback.handleInformationResponse(response);
> -                                    }
> -                                }
> -
> -                                @Override
> -                                public void completed() {
> -                                    final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> -                                    if (callback2 != null) {
> -                                        callback2.completed();
> -                                    } else {
> -                                        asyncExecCallback.completed();
> -                                    }
> -                                }
> +                        public AsyncDataConsumer handleResponse(
> +                                final HttpResponse backendResponse2,
> +                                final EntityDetails entityDetails1)
> throws HttpException, IOException {
> +                            final Date responseDate2 = getCurrentDate();
> +                            final AsyncExecCallback callback2 =
> evaluateResponse(backendResponse2, responseDate2);
> +                            callbackRef.set(callback2);
> +                            return
> callback2.handleResponse(backendResponse2, entityDetails1);
> +                        }
>
> -                                @Override
> -                                public void failed(final Exception cause)
> {
> -                                    final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> -                                    if (callback2 != null) {
> -                                        callback2.failed(cause);
> -                                    } else {
> -                                        asyncExecCallback.failed(cause);
> -                                    }
> -                                }
> +                        @Override
> +                        public void handleInformationResponse(final
> HttpResponse response) throws HttpException, IOException {
> +                            final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> +                            if (callback2 != null) {
> +
> callback2.handleInformationResponse(response);
> +                            } else {
> +
> asyncExecCallback.handleInformationResponse(response);
> +                            }
> +                        }
>
> -                            });
> +                        @Override
> +                        public void completed() {
> +                            final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> +                            if (callback2 != null) {
> +                                callback2.completed();
> +                            } else {
> +                                asyncExecCallback.completed();
> +                            }
> +                        }
>
> +                        @Override
> +                        public void failed(final Exception cause) {
> +                            final AsyncExecCallback callback2 =
> callbackRef.getAndSet(null);
> +                            if (callback2 != null) {
> +                                callback2.failed(cause);
> +                            } else {
> +                                asyncExecCallback.failed(cause);
> +                            }
>                          }
>
> -                    });
> +                    }));
>                  } else {
>                      callback1 = evaluateResponse(backendResponse1,
> responseDate1);
>                  }
> @@ -1036,49 +1000,21 @@ class AsyncCachingExec extends CachingExecBase
> implements AsyncExecChainHandler
>                      final Header resultEtagHeader =
> backendResponse.getFirstHeader(HeaderConstants.ETAG);
>                      if (resultEtagHeader == null) {
>                          LOG.warn("304 response did not contain ETag");
> -                        callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                            @Override
> -                            public void run() {
> -                                callBackend(target, request,
> entityProducer, scope, chain, asyncExecCallback);
> -                            }
> -
> -                        });
> +                        callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target,
> request, entityProducer, scope, chain, asyncExecCallback));
>                      } else {
>                          final String resultEtag =
> resultEtagHeader.getValue();
>                          final Variant matchingVariant =
> variants.get(resultEtag);
>                          if (matchingVariant == null) {
>                              LOG.debug("304 response did not contain ETag
> matching one sent in If-None-Match");
> -                            callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                                @Override
> -                                public void run() {
> -                                    callBackend(target, request,
> entityProducer, scope, chain, asyncExecCallback);
> -                                }
> -
> -                            });
> +                            callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target,
> request, entityProducer, scope, chain, asyncExecCallback));
>                          } else {
>                              if
> (revalidationResponseIsTooOld(backendResponse, matchingVariant.getEntry()))
> {
>                                  final HttpRequest unconditional =
> conditionalRequestBuilder.buildUnconditionalRequest(
>
>  BasicRequestBuilder.copy(request).build());
>
>  scope.clientContext.setAttribute(HttpCoreContext.HTTP_REQUEST,
> unconditional);
> -                                callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                                    @Override
> -                                    public void run() {
> -                                        callBackend(target, request,
> entityProducer, scope, chain, asyncExecCallback);
> -                                    }
> -
> -                                });
> +                                callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, () -> callBackend(target,
> request, entityProducer, scope, chain, asyncExecCallback));
>                              } else {
> -                                callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, new Runnable() {
> -
> -                                    @Override
> -                                    public void run() {
> -
> updateVariantCacheEntry(backendResponse, responseDate, matchingVariant);
> -                                    }
> -
> -                                });
> +                                callback = new
> AsyncExecCallbackWrapper(asyncExecCallback, () ->
> updateVariantCacheEntry(backendResponse, responseDate, matchingVariant));
>                              }
>                          }
>                      }
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
> index 7ba4040..e3bf75b 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpAsyncCache.java
> @@ -34,7 +34,6 @@ import java.util.Set;
>  import org.apache.hc.client5.http.cache.HeaderConstants;
>  import org.apache.hc.client5.http.cache.HttpAsyncCacheInvalidator;
>  import org.apache.hc.client5.http.cache.HttpAsyncCacheStorage;
> -import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
>  import org.apache.hc.client5.http.cache.HttpCacheEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
>  import org.apache.hc.client5.http.cache.ResourceFactory;
> @@ -211,14 +210,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
>              @Override
>              public void completed(final Boolean result) {
>                  storage.updateEntry(cacheKey,
> -                        new HttpCacheCASOperation() {
> -
> -                            @Override
> -                            public HttpCacheEntry execute(final
> HttpCacheEntry existing) throws ResourceIOException {
> -                                return
> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing,
> entry, variantKey, variantCacheKey);
> -                            }
> -
> -                        },
> +                        existing ->
> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing,
> entry, variantKey, variantCacheKey),
>                          new FutureCallback<Boolean>() {
>
>                              @Override
> @@ -280,14 +272,7 @@ class BasicHttpAsyncCache implements HttpAsyncCache {
>          final String variantKey =
> cacheKeyGenerator.generateVariantKey(request, entry);
>          final String variantCacheKey = variant.getCacheKey();
>          return storage.updateEntry(cacheKey,
> -                new HttpCacheCASOperation() {
> -
> -                    @Override
> -                    public HttpCacheEntry execute(final HttpCacheEntry
> existing) throws ResourceIOException {
> -                        return
> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(),
> existing, entry, variantKey, variantCacheKey);
> -                    }
> -
> -                },
> +                existing ->
> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(),
> existing, entry, variantKey, variantCacheKey),
>                  new FutureCallback<Boolean>() {
>
>                      @Override
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
> index 11125d0..70e5272 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicHttpCache.java
> @@ -31,7 +31,6 @@ import java.util.HashMap;
>  import java.util.Map;
>
>  import org.apache.hc.client5.http.cache.HeaderConstants;
> -import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
>  import org.apache.hc.client5.http.cache.HttpCacheEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheInvalidator;
>  import org.apache.hc.client5.http.cache.HttpCacheStorage;
> @@ -163,14 +162,7 @@ class BasicHttpCache implements HttpCache {
>          final String variantCacheKey =
> cacheKeyGenerator.generateKey(host, req, entry);
>          storeEntry(variantCacheKey, entry);
>          try {
> -            storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
> -
> -                @Override
> -                public HttpCacheEntry execute(final HttpCacheEntry
> existing) throws ResourceIOException {
> -                    return
> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing,
> entry, variantKey, variantCacheKey);
> -                }
> -
> -            });
> +            storage.updateEntry(cacheKey, existing ->
> cacheUpdateHandler.updateParentCacheEntry(req.getRequestUri(), existing,
> entry, variantKey, variantCacheKey));
>          } catch (final HttpCacheUpdateException ex) {
>              if (LOG.isWarnEnabled()) {
>                  LOG.warn("Cannot update cache entry with key {}",
> cacheKey);
> @@ -194,14 +186,7 @@ class BasicHttpCache implements HttpCache {
>          final String variantCacheKey = variant.getCacheKey();
>
>          try {
> -            storage.updateEntry(cacheKey, new HttpCacheCASOperation() {
> -
> -                @Override
> -                public HttpCacheEntry execute(final HttpCacheEntry
> existing) throws ResourceIOException {
> -                    return
> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(),
> existing, entry, variantKey, variantCacheKey);
> -                }
> -
> -            });
> +            storage.updateEntry(cacheKey, existing ->
> cacheUpdateHandler.updateParentCacheEntry(request.getRequestUri(),
> existing, entry, variantKey, variantCacheKey));
>          } catch (final HttpCacheUpdateException ex) {
>              if (LOG.isWarnEnabled()) {
>                  LOG.warn("Cannot update cache entry with key {}",
> cacheKey);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
> index 80fdb6b..c49a36a 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/BasicIdGenerator.java
> @@ -66,7 +66,7 @@ class BasicIdGenerator {
>          buffer.append(System.currentTimeMillis());
>          buffer.append('.');
>          final Formatter formatter = new Formatter(buffer, Locale.ROOT);
> -        formatter.format("%1$016x-%2$08x", Long.valueOf(this.count),
> Integer.valueOf(rndnum));
> +        formatter.format("%1$016x-%2$08x", this.count, rndnum);
>          formatter.close();
>          buffer.append('.');
>          buffer.append(this.hostname);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
> index fa702e0..f2e4125 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingExec.java
> @@ -48,7 +48,6 @@ import org.apache.hc.client5.http.impl.ExecSupport;
>  import org.apache.hc.client5.http.protocol.HttpClientContext;
>  import org.apache.hc.client5.http.schedule.SchedulingStrategy;
>  import org.apache.hc.client5.http.utils.DateUtils;
> -import org.apache.hc.core5.function.Factory;
>  import org.apache.hc.core5.http.ClassicHttpRequest;
>  import org.apache.hc.core5.http.ClassicHttpResponse;
>  import org.apache.hc.core5.http.Header;
> @@ -111,14 +110,8 @@ class CachingExec extends CachingExecBase implements
> ExecChainHandler {
>          super(config);
>          this.responseCache = Args.notNull(cache, "Response cache");
>          this.cacheRevalidator = cacheRevalidator;
> -        this.conditionalRequestBuilder = new
> ConditionalRequestBuilder<>(new Factory<ClassicHttpRequest,
> ClassicHttpRequest>() {
> -
> -            @Override
> -            public ClassicHttpRequest create(final ClassicHttpRequest
> classicHttpRequest) {
> -                return
> ClassicRequestBuilder.copy(classicHttpRequest).build();
> -            }
> -
> -        });
> +        this.conditionalRequestBuilder = new
> ConditionalRequestBuilder<>(classicHttpRequest ->
> +
> ClassicRequestBuilder.copy(classicHttpRequest).build());
>      }
>
>      CachingExec(
> @@ -290,14 +283,7 @@ class CachingExec extends CachingExecBase implements
> ExecChainHandler {
>                      final SimpleHttpResponse response =
> generateCachedResponse(request, context, entry, now);
>                      cacheRevalidator.revalidateCacheEntry(
>                              responseCache.generateKey(target, request,
> entry),
> -                            new
> DefaultCacheRevalidator.RevalidationCall() {
> -
> -                        @Override
> -                        public ClassicHttpResponse execute() throws
> HttpException, IOException {
> -                            return revalidateCacheEntry(target, request,
> fork, chain, entry);
> -                        }
> -
> -                    });
> +                            () -> revalidateCacheEntry(target, request,
> fork, chain, entry));
>                      return convert(response, scope);
>                  }
>                  return revalidateCacheEntry(target, request, scope,
> chain, entry);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
> index e8b4b50..f468cfe 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingH2AsyncClientBuilder.java
> @@ -26,9 +26,7 @@
>   */
>  package org.apache.hc.client5.http.impl.cache;
>
> -import java.io.Closeable;
>  import java.io.File;
> -import java.io.IOException;
>  import java.util.concurrent.ScheduledExecutorService;
>  import java.util.concurrent.ScheduledThreadPoolExecutor;
>
> @@ -130,14 +128,7 @@ public class CachingH2AsyncClientBuilder extends
> H2AsyncClientBuilder {
>              } else {
>                  final ManagedHttpCacheStorage managedStorage = new
> ManagedHttpCacheStorage(config);
>                  if (this.deleteCache) {
> -                    addCloseable(new Closeable() {
> -
> -                        @Override
> -                        public void close() throws IOException {
> -                            managedStorage.shutdown();
> -                        }
> -
> -                    });
> +                    addCloseable(managedStorage::shutdown);
>                  } else {
>                      addCloseable(managedStorage);
>                  }
> @@ -153,14 +144,7 @@ public class CachingH2AsyncClientBuilder extends
> H2AsyncClientBuilder {
>          DefaultAsyncCacheRevalidator cacheRevalidator = null;
>          if (config.getAsynchronousWorkers() > 0) {
>              final ScheduledExecutorService executorService = new
> ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
> -            addCloseable(new Closeable() {
> -
> -                @Override
> -                public void close() throws IOException {
> -                    executorService.shutdownNow();
> -                }
> -
> -            });
> +            addCloseable(executorService::shutdownNow);
>              cacheRevalidator = new DefaultAsyncCacheRevalidator(
>                      executorService,
>                      this.schedulingStrategy != null ?
> this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
> index fe92f61..15dbe7c 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpAsyncClientBuilder.java
> @@ -26,9 +26,7 @@
>   */
>  package org.apache.hc.client5.http.impl.cache;
>
> -import java.io.Closeable;
>  import java.io.File;
> -import java.io.IOException;
>  import java.util.concurrent.ScheduledExecutorService;
>  import java.util.concurrent.ScheduledThreadPoolExecutor;
>
> @@ -130,14 +128,7 @@ public class CachingHttpAsyncClientBuilder extends
> HttpAsyncClientBuilder {
>              } else {
>                  final ManagedHttpCacheStorage managedStorage = new
> ManagedHttpCacheStorage(config);
>                  if (this.deleteCache) {
> -                    addCloseable(new Closeable() {
> -
> -                        @Override
> -                        public void close() throws IOException {
> -                            managedStorage.shutdown();
> -                        }
> -
> -                    });
> +                    addCloseable(managedStorage::shutdown);
>                  } else {
>                      addCloseable(managedStorage);
>                  }
> @@ -153,14 +144,7 @@ public class CachingHttpAsyncClientBuilder extends
> HttpAsyncClientBuilder {
>          DefaultAsyncCacheRevalidator cacheRevalidator = null;
>          if (config.getAsynchronousWorkers() > 0) {
>              final ScheduledExecutorService executorService = new
> ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
> -            addCloseable(new Closeable() {
> -
> -                @Override
> -                public void close() throws IOException {
> -                    executorService.shutdownNow();
> -                }
> -
> -            });
> +            addCloseable(executorService::shutdownNow);
>              cacheRevalidator = new DefaultAsyncCacheRevalidator(
>                      executorService,
>                      this.schedulingStrategy != null ?
> this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
> index 5d6bf91..f2b1e51 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/CachingHttpClientBuilder.java
> @@ -26,9 +26,7 @@
>   */
>  package org.apache.hc.client5.http.impl.cache;
>
> -import java.io.Closeable;
>  import java.io.File;
> -import java.io.IOException;
>  import java.util.concurrent.ScheduledExecutorService;
>  import java.util.concurrent.ScheduledThreadPoolExecutor;
>
> @@ -122,14 +120,7 @@ public class CachingHttpClientBuilder extends
> HttpClientBuilder {
>              } else {
>                  final ManagedHttpCacheStorage managedStorage = new
> ManagedHttpCacheStorage(config);
>                  if (this.deleteCache) {
> -                    addCloseable(new Closeable() {
> -
> -                        @Override
> -                        public void close() throws IOException {
> -                            managedStorage.shutdown();
> -                        }
> -
> -                    });
> +                    addCloseable(managedStorage::shutdown);
>                  } else {
>                      addCloseable(managedStorage);
>                  }
> @@ -145,14 +136,7 @@ public class CachingHttpClientBuilder extends
> HttpClientBuilder {
>          DefaultCacheRevalidator cacheRevalidator = null;
>          if (config.getAsynchronousWorkers() > 0) {
>              final ScheduledExecutorService executorService = new
> ScheduledThreadPoolExecutor(config.getAsynchronousWorkers());
> -            addCloseable(new Closeable() {
> -
> -                @Override
> -                public void close() throws IOException {
> -                    executorService.shutdownNow();
> -                }
> -
> -            });
> +            addCloseable(executorService::shutdownNow);
>              cacheRevalidator = new DefaultCacheRevalidator(
>                      executorService,
>                      this.schedulingStrategy != null ?
> this.schedulingStrategy : ImmediateSchedulingStrategy.INSTANCE);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
> index 4a57479..77b720b 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheInvalidator.java
> @@ -70,7 +70,7 @@ public class DefaultAsyncCacheInvalidator extends
> CacheInvalidatorBase implement
>              @Override
>              public void completed(final Boolean result) {
>                  if (LOG.isDebugEnabled()) {
> -                    if (result) {
> +                    if (result.booleanValue()) {
>                          LOG.debug("Cache entry with key {} successfully
> flushed", cacheKey);
>                      } else {
>                          LOG.debug("Cache entry with key {} could not be
> flushed", cacheKey);
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
> index 90718d8..43fab11 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultAsyncCacheRevalidator.java
> @@ -118,59 +118,52 @@ class DefaultAsyncCacheRevalidator extends
> CacheRevalidatorBase {
>              final String cacheKey ,
>              final AsyncExecCallback asyncExecCallback,
>              final RevalidationCall call) {
> -        scheduleRevalidation(cacheKey, new Runnable() {
> -
> -                        @Override
> -                        public void run() {
> -                            call.execute(new AsyncExecCallback() {
> -
> -                                private final
> AtomicReference<HttpResponse> responseRef = new AtomicReference<>(null);
> -
> -                                @Override
> -                                public AsyncDataConsumer handleResponse(
> -                                        final HttpResponse response,
> -                                        final EntityDetails
> entityDetails) throws HttpException, IOException {
> -                                    responseRef.set(response);
> -                                    return
> asyncExecCallback.handleResponse(response, entityDetails);
> -                                }
> -
> -                                @Override
> -                                public void handleInformationResponse(
> -                                        final HttpResponse response)
> throws HttpException, IOException {
> -
> asyncExecCallback.handleInformationResponse(response);
> -                                }
> -
> -                                @Override
> -                                public void completed() {
> -                                    final HttpResponse httpResponse =
> responseRef.getAndSet(null);
> -                                    if (httpResponse != null &&
> httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR &&
> !isStale(httpResponse)) {
> -                                        jobSuccessful(cacheKey);
> -                                    } else {
> -                                        jobFailed(cacheKey);
> -                                    }
> -                                    asyncExecCallback.completed();
> -                                }
> -
> -                                @Override
> -                                public void failed(final Exception cause)
> {
> -                                    if (cause instanceof IOException) {
> -                                        LOG.debug("Asynchronous
> revalidation failed due to I/O error", cause);
> -                                    } else if (cause instanceof
> HttpException) {
> -                                        LOG.error("HTTP protocol
> exception during asynchronous revalidation", cause);
> -                                    } else {
> -                                        LOG.error("Unexpected runtime
> exception thrown during asynchronous revalidation", cause);
> -                                    }
> -                                    try {
> -                                        jobFailed(cacheKey);
> -                                    } finally {
> -                                        asyncExecCallback.failed(cause);
> -                                    }
> -                                }
> -
> -                            });
> -                        }
> -
> -                    });
> +        scheduleRevalidation(cacheKey, () -> call.execute(new
> AsyncExecCallback() {
> +
> +            private final AtomicReference<HttpResponse> responseRef = new
> AtomicReference<>(null);
> +
> +            @Override
> +            public AsyncDataConsumer handleResponse(
> +                    final HttpResponse response,
> +                    final EntityDetails entityDetails) throws
> HttpException, IOException {
> +                responseRef.set(response);
> +                return asyncExecCallback.handleResponse(response,
> entityDetails);
> +            }
> +
> +            @Override
> +            public void handleInformationResponse(
> +                    final HttpResponse response) throws HttpException,
> IOException {
> +                asyncExecCallback.handleInformationResponse(response);
> +            }
> +
> +            @Override
> +            public void completed() {
> +                final HttpResponse httpResponse =
> responseRef.getAndSet(null);
> +                if (httpResponse != null && httpResponse.getCode() <
> HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
> +                    jobSuccessful(cacheKey);
> +                } else {
> +                    jobFailed(cacheKey);
> +                }
> +                asyncExecCallback.completed();
> +            }
> +
> +            @Override
> +            public void failed(final Exception cause) {
> +                if (cause instanceof IOException) {
> +                    LOG.debug("Asynchronous revalidation failed due to
> I/O error", cause);
> +                } else if (cause instanceof HttpException) {
> +                    LOG.error("HTTP protocol exception during
> asynchronous revalidation", cause);
> +                } else {
> +                    LOG.error("Unexpected runtime exception thrown during
> asynchronous revalidation", cause);
> +                }
> +                try {
> +                    jobFailed(cacheKey);
> +                } finally {
> +                    asyncExecCallback.failed(cause);
> +                }
> +            }
> +
> +        }));
>      }
>
>  }
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
> index 514b904..b4846aa 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/DefaultCacheRevalidator.java
> @@ -75,30 +75,25 @@ class DefaultCacheRevalidator extends
> CacheRevalidatorBase {
>      public void revalidateCacheEntry(
>              final String cacheKey,
>              final RevalidationCall call) {
> -        scheduleRevalidation(cacheKey, new Runnable() {
> +        scheduleRevalidation(cacheKey, () -> {
> +            try (ClassicHttpResponse httpResponse = call.execute()) {
> +                if (httpResponse.getCode() < HttpStatus.SC_SERVER_ERROR
> && !isStale(httpResponse)) {
> +                    jobSuccessful(cacheKey);
> +                } else {
> +                    jobFailed(cacheKey);
> +                }
> +            } catch (final IOException ex) {
> +                jobFailed(cacheKey);
> +                LOG.debug("Asynchronous revalidation failed due to I/O
> error", ex);
> +            } catch (final HttpException ex) {
> +                jobFailed(cacheKey);
> +                LOG.error("HTTP protocol exception during asynchronous
> revalidation", ex);
> +            } catch (final RuntimeException ex) {
> +                jobFailed(cacheKey);
> +                LOG.error("Unexpected runtime exception thrown during
> asynchronous revalidation", ex);
> +            }
>
> -                        @Override
> -                        public void run() {
> -                            try (ClassicHttpResponse httpResponse =
> call.execute()) {
> -                                if (httpResponse.getCode() <
> HttpStatus.SC_SERVER_ERROR && !isStale(httpResponse)) {
> -                                    jobSuccessful(cacheKey);
> -                                } else {
> -                                    jobFailed(cacheKey);
> -                                }
> -                            } catch (final IOException ex) {
> -                                jobFailed(cacheKey);
> -                                LOG.debug("Asynchronous revalidation
> failed due to I/O error", ex);
> -                            } catch (final HttpException ex) {
> -                                jobFailed(cacheKey);
> -                                LOG.error("HTTP protocol exception during
> asynchronous revalidation", ex);
> -                            } catch (final RuntimeException ex) {
> -                                jobFailed(cacheKey);
> -                                LOG.error("Unexpected runtime exception
> thrown during asynchronous revalidation", ex);
> -                            }
> -
> -                        }
> -
> -                    });
> +        });
>      }
>
>  }
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
> index 70747cf..905cf86 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/WarningValue.java
> @@ -358,10 +358,10 @@ class WarningValue {
>      @Override
>      public String toString() {
>          if (warnDate != null) {
> -            return String.format("%d %s %s \"%s\"",
> Integer.valueOf(warnCode),
> +            return String.format("%d %s %s \"%s\"", warnCode,
>                      warnAgent, warnText, DateUtils.formatDate(warnDate));
>          } else {
> -            return String.format("%d %s %s", Integer.valueOf(warnCode),
> warnAgent, warnText);
> +            return String.format("%d %s %s", warnCode, warnAgent,
> warnText);
>          }
>      }
>
> diff --git
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
> index 36d075c..b49d63f 100644
> ---
> a/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
> +++
> b/httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/memcached/MemcachedHttpAsyncCacheStorage.java
> @@ -47,11 +47,7 @@ import net.spy.memcached.CASResponse;
>  import net.spy.memcached.CASValue;
>  import net.spy.memcached.MemcachedClient;
>  import net.spy.memcached.internal.BulkFuture;
> -import net.spy.memcached.internal.BulkGetCompletionListener;
> -import net.spy.memcached.internal.BulkGetFuture;
> -import net.spy.memcached.internal.GetCompletionListener;
>  import net.spy.memcached.internal.GetFuture;
> -import net.spy.memcached.internal.OperationCompletionListener;
>  import net.spy.memcached.internal.OperationFuture;
>
>  /**
> @@ -160,21 +156,16 @@ public class MemcachedHttpAsyncCacheStorage extends
> AbstractBinaryAsyncCacheStor
>      }
>
>      private <T> Cancellable operation(final OperationFuture<T>
> operationFuture, final FutureCallback<T> callback) {
> -        operationFuture.addListener(new OperationCompletionListener() {
> -
> -            @Override
> -            public void onComplete(final OperationFuture<?> future)
> throws Exception {
> -                try {
> -                    callback.completed(operationFuture.get());
> -                } catch (final ExecutionException ex) {
> -                    if (ex.getCause() instanceof Exception) {
> -                        callback.failed((Exception) ex.getCause());
> -                    } else {
> -                        callback.failed(ex);
> -                    }
> +        operationFuture.addListener(future -> {
> +            try {
> +                callback.completed(operationFuture.get());
> +            } catch (final ExecutionException ex) {
> +                if (ex.getCause() instanceof Exception) {
> +                    callback.failed((Exception) ex.getCause());
> +                } else {
> +                    callback.failed(ex);
>                  }
>              }
> -
>          });
>          return Operations.cancellable(operationFuture);
>      }
> @@ -187,21 +178,16 @@ public class MemcachedHttpAsyncCacheStorage extends
> AbstractBinaryAsyncCacheStor
>      @Override
>      protected Cancellable restore(final String storageKey, final
> FutureCallback<byte[]> callback) {
>          final GetFuture<Object> getFuture = client.asyncGet(storageKey);
> -        getFuture.addListener(new GetCompletionListener() {
> -
> -            @Override
> -            public void onComplete(final GetFuture<?> future) throws
> Exception {
> -                try {
> -                    callback.completed(castAsByteArray(getFuture.get()));
> -                } catch (final ExecutionException ex) {
> -                    if (ex.getCause() instanceof Exception) {
> -                        callback.failed((Exception) ex.getCause());
> -                    } else {
> -                        callback.failed(ex);
> -                    }
> +        getFuture.addListener(future -> {
> +            try {
> +                callback.completed(castAsByteArray(getFuture.get()));
> +            } catch (final ExecutionException ex) {
> +                if (ex.getCause() instanceof Exception) {
> +                    callback.failed((Exception) ex.getCause());
> +                } else {
> +                    callback.failed(ex);
>                  }
>              }
> -
>          });
>          return Operations.cancellable(getFuture);
>      }
> @@ -242,17 +228,13 @@ public class MemcachedHttpAsyncCacheStorage extends
> AbstractBinaryAsyncCacheStor
>      @Override
>      protected Cancellable bulkRestore(final Collection<String>
> storageKeys, final FutureCallback<Map<String, byte[]>> callback) {
>          final BulkFuture<Map<String, Object>> future =
> client.asyncGetBulk(storageKeys);
> -        future.addListener(new BulkGetCompletionListener() {
> -
> -            @Override
> -            public void onComplete(final BulkGetFuture<?> future) throws
> Exception {
> -                final Map<String, ?> storageObjectMap = future.get();
> -                final Map<String, byte[]> resultMap = new
> HashMap<>(storageObjectMap.size());
> -                for (final Map.Entry<String, ?> resultEntry:
> storageObjectMap.entrySet()) {
> -                    resultMap.put(resultEntry.getKey(),
> castAsByteArray(resultEntry.getValue()));
> -                }
> -                callback.completed(resultMap);
> +        future.addListener(future1 -> {
> +            final Map<String, ?> storageObjectMap = future1.get();
> +            final Map<String, byte[]> resultMap = new
> HashMap<>(storageObjectMap.size());
> +            for (final Map.Entry<String, ?> resultEntry:
> storageObjectMap.entrySet()) {
> +                resultMap.put(resultEntry.getKey(),
> castAsByteArray(resultEntry.getValue()));
>              }
> +            callback.completed(resultMap);
>          });
>          return Operations.cancellable(future);
>      }
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
> index 88b8cbc..791ae61 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/cache/TestHttpCacheEntry.java
> @@ -217,7 +217,7 @@ public class TestHttpCacheEntry {
>      public void canProvideVariantMap() {
>          new HttpCacheEntry(new Date(), new Date(), HttpStatus.SC_OK,
>                  new Header[]{}, mockResource,
> -                new HashMap<String,String>());
> +                new HashMap<>());
>      }
>
>      @Test
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
> index 8d83f7f..67e75a2 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/AbstractProtocolTest.java
> @@ -155,7 +155,7 @@ public abstract class AbstractProtocolTest {
>
>  EasyMock.expect(mockCache.getCacheEntry(EasyMock.isA(HttpHost.class),
> EasyMock.isA(HttpRequest.class)))
>              .andReturn(null).anyTimes();
>
>  EasyMock.expect(mockCache.getVariantCacheEntriesWithEtags(EasyMock.isA(HttpHost.class),
> EasyMock.isA(HttpRequest.class)))
> -            .andReturn(new HashMap<String,Variant>()).anyTimes();
> +            .andReturn(new HashMap<>()).anyTimes();
>
>          mockCache.flushCacheEntriesFor(EasyMock.isA(HttpHost.class),
> EasyMock.isA(HttpRequest.class));
>          EasyMock.expectLastCall().anyTimes();
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
> index f0b1ad6..1692054 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingAsyncCacheStorage.java
> @@ -35,7 +35,6 @@ import java.util.HashMap;
>  import java.util.Map;
>  import java.util.concurrent.atomic.AtomicInteger;
>
> -import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
>  import org.apache.hc.client5.http.cache.HttpCacheEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
> @@ -52,7 +51,6 @@ import org.mockito.ArgumentCaptor;
>  import org.mockito.ArgumentMatchers;
>  import org.mockito.Mock;
>  import org.mockito.Mockito;
> -import org.mockito.invocation.InvocationOnMock;
>  import org.mockito.junit.MockitoJUnitRunner;
>  import org.mockito.stubbing.Answer;
>
> @@ -90,16 +88,11 @@ public class TestAbstractSerializingAsyncCacheStorage {
>          Mockito.when(impl.store(
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> -                callback.completed(true);
> -                return cancellable;
> -            }
> -
> -        });
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> +                    callback.completed(true);
> +                    return cancellable;
> +                });
>
>          impl.putEntry(key, value, operationCallback);
>
> @@ -114,15 +107,10 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          final String key = "foo";
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
> -        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> -                callback.completed(null);
> -                return cancellable;
> -            }
> -
> +        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +            final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> +            callback.completed(null);
> +            return cancellable;
>          });
>
>          impl.getEntry(key, cacheEntryCallback);
> @@ -138,15 +126,10 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
> -        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> -                callback.completed(serialize(key, value));
> -                return cancellable;
> -            }
> -
> +        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +            final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> +            callback.completed(serialize(key, value));
> +            return cancellable;
>          });
>
>          impl.getEntry(key, cacheEntryCallback);
> @@ -162,15 +145,10 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          final String key = "foo";
>          final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
> -        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> -                callback.completed(serialize("not-foo", value));
> -                return cancellable;
> -            }
> -
> +        Mockito.when(impl.restore(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<byte[]>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +            final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> +            callback.completed(serialize("not-foo", value));
> +            return cancellable;
>          });
>
>          impl.getEntry(key, cacheEntryCallback);
> @@ -187,16 +165,11 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
>          Mockito.when(impl.delete(
>                  ArgumentMatchers.eq("bar"),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(1);
> -                callback.completed(true);
> -                return cancellable;
> -            }
> -
> -        });
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(1);
> +                    callback.completed(true);
> +                    return cancellable;
> +                });
>          impl.removeEntry(key, operationCallback);
>
>          Mockito.verify(impl).delete("bar", operationCallback);
> @@ -209,38 +182,23 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          final HttpCacheEntry updatedValue =
> HttpTestUtils.makeCacheEntry();
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
> -        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> -                callback.completed(null);
> -                return cancellable;
> -            }
> -
> +        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +            final FutureCallback<byte[]> callback =
> invocation.getArgument(1);
> +            callback.completed(null);
> +            return cancellable;
>          });
>          Mockito.when(impl.store(
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> -                callback.completed(true);
> -                return cancellable;
> -            }
> -
> -        });
> -
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                Assert.assertThat(existing, CoreMatchers.nullValue());
> -                return updatedValue;
> -            }
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> +                    callback.completed(true);
> +                    return cancellable;
> +                });
>
> +        impl.updateEntry(key, existing -> {
> +            Assert.assertThat(existing, CoreMatchers.nullValue());
> +            return updatedValue;
>          }, operationCallback);
>
>          Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any());
> @@ -255,40 +213,23 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>          final HttpCacheEntry updatedValue =
> HttpTestUtils.makeCacheEntry();
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
> -        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<String> callback =
> invocation.getArgument(1);
> -                callback.completed("stuff");
> -                return cancellable;
> -            }
> -
> +        Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +            final FutureCallback<String> callback =
> invocation.getArgument(1);
> +            callback.completed("stuff");
> +            return cancellable;
>          });
>
>  Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key,
> existingValue));
>          Mockito.when(impl.updateCAS(
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.eq("stuff"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> -                callback.completed(true);
> -                return cancellable;
> -            }
> -
> -        });
> -
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> +                    callback.completed(true);
> +                    return cancellable;
> +                });
>
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                return updatedValue;
> -            }
> -
> -        }, operationCallback);
> +        impl.updateEntry(key, existing -> updatedValue,
> operationCallback);
>
>          Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any());
>          Mockito.verify(impl).getStorageObject("stuff");
> @@ -304,39 +245,24 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
>          Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
> -                new Answer<Cancellable>() {
> -
> -                    @Override
> -                    public Cancellable answer(final InvocationOnMock
> invocation) throws Throwable {
> -                        final FutureCallback<String> callback =
> invocation.getArgument(1);
> -                        callback.completed("stuff");
> -                        return cancellable;
> -                    }
> -
> +                (Answer<Cancellable>) invocation -> {
> +                    final FutureCallback<String> callback =
> invocation.getArgument(1);
> +                    callback.completed("stuff");
> +                    return cancellable;
>                  });
>
>  Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo",
> existingValue));
>          Mockito.when(impl.store(
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> -                callback.completed(true);
> -                return cancellable;
> -            }
> -
> -        });
> -
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                Assert.assertThat(existing, CoreMatchers.nullValue());
> -                return updatedValue;
> -            }
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(2);
> +                    callback.completed(true);
> +                    return cancellable;
> +                });
>
> +        impl.updateEntry(key, existing -> {
> +            Assert.assertThat(existing, CoreMatchers.nullValue());
> +            return updatedValue;
>          }, operationCallback);
>
>          Mockito.verify(impl).getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any());
> @@ -355,15 +281,10 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
>          Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
> -                new Answer<Cancellable>() {
> -
> -                    @Override
> -                    public Cancellable answer(final InvocationOnMock
> invocation) throws Throwable {
> -                        final FutureCallback<String> callback =
> invocation.getArgument(1);
> -                        callback.completed("stuff");
> -                        return cancellable;
> -                    }
> -
> +                (Answer<Cancellable>) invocation -> {
> +                    final FutureCallback<String> callback =
> invocation.getArgument(1);
> +                    callback.completed("stuff");
> +                    return cancellable;
>                  });
>
>  Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key,
> existingValue));
>          final AtomicInteger count = new AtomicInteger(0);
> @@ -371,29 +292,17 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.eq("stuff"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> -                if (count.incrementAndGet() == 1) {
> -                    callback.completed(false);
> -                } else {
> -                    callback.completed(true);
> -                }
> -                return cancellable;
> -            }
> -
> -        });
> -
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                return updatedValue;
> -            }
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> +                    if (count.incrementAndGet() == 1) {
> +                        callback.completed(false);
> +                    } else {
> +                        callback.completed(true);
> +                    }
> +                    return cancellable;
> +                });
>
> -        }, operationCallback);
> +        impl.updateEntry(key, existing -> updatedValue,
> operationCallback);
>
>          Mockito.verify(impl,
> Mockito.times(2)).getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any());
>          Mockito.verify(impl, Mockito.times(2)).getStorageObject("stuff");
> @@ -410,15 +319,10 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>
>          Mockito.when(impl.digestToStorageKey(key)).thenReturn("bar");
>          Mockito.when(impl.getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any())).thenAnswer(
> -                new Answer<Cancellable>() {
> -
> -                    @Override
> -                    public Cancellable answer(final InvocationOnMock
> invocation) throws Throwable {
> -                        final FutureCallback<String> callback =
> invocation.getArgument(1);
> -                        callback.completed("stuff");
> -                        return cancellable;
> -                    }
> -
> +                (Answer<Cancellable>) invocation -> {
> +                    final FutureCallback<String> callback =
> invocation.getArgument(1);
> +                    callback.completed("stuff");
> +                    return cancellable;
>                  });
>
>  Mockito.when(impl.getStorageObject("stuff")).thenReturn(serialize(key,
> existingValue));
>          final AtomicInteger count = new AtomicInteger(0);
> @@ -426,29 +330,17 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>                  ArgumentMatchers.eq("bar"),
>                  ArgumentMatchers.eq("stuff"),
>                  ArgumentMatchers.<byte[]>any(),
> -
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer(new
> Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> -                if (count.incrementAndGet() <= 3) {
> -                    callback.completed(false);
> -                } else {
> -                    callback.completed(true);
> -                }
> -                return cancellable;
> -            }
> -
> -        });
> -
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                return updatedValue;
> -            }
> +
> ArgumentMatchers.<FutureCallback<Boolean>>any())).thenAnswer((Answer<Cancellable>)
> invocation -> {
> +                    final FutureCallback<Boolean> callback =
> invocation.getArgument(3);
> +                    if (count.incrementAndGet() <= 3) {
> +                        callback.completed(false);
> +                    } else {
> +                        callback.completed(true);
> +                    }
> +                    return cancellable;
> +                });
>
> -        }, operationCallback);
> +        impl.updateEntry(key, existing -> updatedValue,
> operationCallback);
>
>          Mockito.verify(impl,
> Mockito.times(3)).getForUpdateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.<FutureCallback<String>>any());
>          Mockito.verify(impl, Mockito.times(3)).getStorageObject("stuff");
> @@ -472,23 +364,19 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>
>          when(impl.bulkRestore(
>                  ArgumentMatchers.<String>anyCollection(),
> -                ArgumentMatchers.<FutureCallback<Map<String,
> byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final Collection<String> keys = invocation.getArgument(0);
> -                final FutureCallback<Map<String, byte[]>> callback =
> invocation.getArgument(1);
> -                final Map<String, byte[]> resultMap = new HashMap<>();
> -                if (keys.contains(storageKey1)) {
> -                    resultMap.put(storageKey1, serialize(key1, value1));
> -                }
> -                if (keys.contains(storageKey2)) {
> -                    resultMap.put(storageKey2, serialize(key2, value2));
> -                }
> -                callback.completed(resultMap);
> -                return cancellable;
> -            }
> -        });
> +                ArgumentMatchers.<FutureCallback<Map<String,
> byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
> +                    final Collection<String> keys =
> invocation.getArgument(0);
> +                    final FutureCallback<Map<String, byte[]>> callback =
> invocation.getArgument(1);
> +                    final Map<String, byte[]> resultMap = new HashMap<>();
> +                    if (keys.contains(storageKey1)) {
> +                        resultMap.put(storageKey1, serialize(key1,
> value1));
> +                    }
> +                    if (keys.contains(storageKey2)) {
> +                        resultMap.put(storageKey2, serialize(key2,
> value2));
> +                    }
> +                    callback.completed(resultMap);
> +                    return cancellable;
> +                });
>
>          impl.getEntries(Arrays.asList(key1, key2),
> bulkCacheEntryCallback);
>          final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor
> = ArgumentCaptor.forClass(Map.class);
> @@ -521,23 +409,19 @@ public class
> TestAbstractSerializingAsyncCacheStorage {
>
>          when(impl.bulkRestore(
>                  ArgumentMatchers.<String>anyCollection(),
> -                ArgumentMatchers.<FutureCallback<Map<String,
> byte[]>>>any())).thenAnswer(new Answer<Cancellable>() {
> -
> -            @Override
> -            public Cancellable answer(final InvocationOnMock invocation)
> throws Throwable {
> -                final Collection<String> keys = invocation.getArgument(0);
> -                final FutureCallback<Map<String, byte[]>> callback =
> invocation.getArgument(1);
> -                final Map<String, byte[]> resultMap = new HashMap<>();
> -                if (keys.contains(storageKey1)) {
> -                    resultMap.put(storageKey1, serialize(key1, value1));
> -                }
> -                if (keys.contains(storageKey2)) {
> -                    resultMap.put(storageKey2, serialize("not foo",
> value2));
> -                }
> -                callback.completed(resultMap);
> -                return cancellable;
> -            }
> -        });
> +                ArgumentMatchers.<FutureCallback<Map<String,
> byte[]>>>any())).thenAnswer((Answer<Cancellable>) invocation -> {
> +                    final Collection<String> keys =
> invocation.getArgument(0);
> +                    final FutureCallback<Map<String, byte[]>> callback =
> invocation.getArgument(1);
> +                    final Map<String, byte[]> resultMap = new HashMap<>();
> +                    if (keys.contains(storageKey1)) {
> +                        resultMap.put(storageKey1, serialize(key1,
> value1));
> +                    }
> +                    if (keys.contains(storageKey2)) {
> +                        resultMap.put(storageKey2, serialize("not foo",
> value2));
> +                    }
> +                    callback.completed(resultMap);
> +                    return cancellable;
> +                });
>
>          impl.getEntries(Arrays.asList(key1, key2),
> bulkCacheEntryCallback);
>          final ArgumentCaptor<Map<String, HttpCacheEntry>> argumentCaptor
> = ArgumentCaptor.forClass(Map.class);
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
> index 5fd0b03..1cbbaae 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestAbstractSerializingCacheStorage.java
> @@ -35,7 +35,6 @@ import java.util.Collection;
>  import java.util.HashMap;
>  import java.util.Map;
>
> -import org.apache.hc.client5.http.cache.HttpCacheCASOperation;
>  import org.apache.hc.client5.http.cache.HttpCacheEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheStorageEntry;
>  import org.apache.hc.client5.http.cache.HttpCacheUpdateException;
> @@ -48,7 +47,6 @@ import org.mockito.Answers;
>  import org.mockito.ArgumentCaptor;
>  import org.mockito.ArgumentMatchers;
>  import org.mockito.Mockito;
> -import org.mockito.invocation.InvocationOnMock;
>  import org.mockito.stubbing.Answer;
>
>  @SuppressWarnings("boxing") // test code
> @@ -143,14 +141,9 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.digestToStorageKey(key)).thenReturn("bar");
>          when(impl.getForUpdateCAS("bar")).thenReturn(null);
>
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                Assert.assertThat(existing, CoreMatchers.nullValue());
> -                return updatedValue;
> -            }
> -
> +        impl.updateEntry(key, existing -> {
> +            Assert.assertThat(existing, CoreMatchers.nullValue());
> +            return updatedValue;
>          });
>
>          verify(impl).getForUpdateCAS("bar");
> @@ -168,14 +161,7 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.getStorageObject("stuff")).thenReturn(serialize(key,
> existingValue));
>          when(impl.updateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.eq("stuff"),
> ArgumentMatchers.<byte[]>any())).thenReturn(true);
>
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                return updatedValue;
> -            }
> -
> -        });
> +        impl.updateEntry(key, existing -> updatedValue);
>
>          verify(impl).getForUpdateCAS("bar");
>          verify(impl).getStorageObject("stuff");
> @@ -193,14 +179,9 @@ public class TestAbstractSerializingCacheStorage {
>
>  when(impl.getStorageObject("stuff")).thenReturn(serialize("not-foo",
> existingValue));
>          when(impl.updateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.eq("stuff"),
> ArgumentMatchers.<byte[]>any())).thenReturn(true);
>
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                Assert.assertThat(existing, CoreMatchers.nullValue());
> -                return updatedValue;
> -            }
> -
> +        impl.updateEntry(key, existing -> {
> +            Assert.assertThat(existing, CoreMatchers.nullValue());
> +            return updatedValue;
>          });
>
>          verify(impl).getForUpdateCAS("bar");
> @@ -219,14 +200,7 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.getStorageObject("stuff")).thenReturn(serialize(key,
> existingValue));
>          when(impl.updateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.eq("stuff"),
> ArgumentMatchers.<byte[]>any())).thenReturn(false, true);
>
> -        impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -            @Override
> -            public HttpCacheEntry execute(final HttpCacheEntry existing)
> throws ResourceIOException {
> -                return updatedValue;
> -            }
> -
> -        });
> +        impl.updateEntry(key, existing -> updatedValue);
>
>          verify(impl, Mockito.times(2)).getForUpdateCAS("bar");
>          verify(impl, Mockito.times(2)).getStorageObject("stuff");
> @@ -245,14 +219,7 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.updateCAS(ArgumentMatchers.eq("bar"),
> ArgumentMatchers.eq("stuff"),
> ArgumentMatchers.<byte[]>any())).thenReturn(false, false, false, true);
>
>          try {
> -            impl.updateEntry(key, new HttpCacheCASOperation() {
> -
> -                @Override
> -                public HttpCacheEntry execute(final HttpCacheEntry
> existing) throws ResourceIOException {
> -                    return updatedValue;
> -                }
> -
> -            });
> +            impl.updateEntry(key, existing -> updatedValue);
>              Assert.fail("HttpCacheUpdateException expected");
>          } catch (final HttpCacheUpdateException ignore) {
>          }
> @@ -274,20 +241,16 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
>          when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
>
> -
> when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new
> Answer<Map<String, byte[]>>() {
> -
> -            @Override
> -            public Map<String, byte[]> answer(final InvocationOnMock
> invocation) throws Throwable {
> -                final Collection<String> keys = invocation.getArgument(0);
> -                final Map<String, byte[]> resultMap = new HashMap<>();
> -                if (keys.contains(storageKey1)) {
> -                    resultMap.put(storageKey1, serialize(key1, value1));
> -                }
> -                if (keys.contains(storageKey2)) {
> -                    resultMap.put(storageKey2, serialize(key2, value2));
> -                }
> -                return resultMap;
> +
> when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String,
> byte[]>>) invocation -> {
> +            final Collection<String> keys = invocation.getArgument(0);
> +            final Map<String, byte[]> resultMap = new HashMap<>();
> +            if (keys.contains(storageKey1)) {
> +                resultMap.put(storageKey1, serialize(key1, value1));
>              }
> +            if (keys.contains(storageKey2)) {
> +                resultMap.put(storageKey2, serialize(key2, value2));
> +            }
> +            return resultMap;
>          });
>
>          final Map<String, HttpCacheEntry> entryMap =
> impl.getEntries(Arrays.asList(key1, key2));
> @@ -312,20 +275,16 @@ public class TestAbstractSerializingCacheStorage {
>          when(impl.digestToStorageKey(key1)).thenReturn(storageKey1);
>          when(impl.digestToStorageKey(key2)).thenReturn(storageKey2);
>
> -
> when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer(new
> Answer<Map<String, byte[]>>() {
> -
> -            @Override
> -            public Map<String, byte[]> answer(final InvocationOnMock
> invocation) throws Throwable {
> -                final Collection<String> keys = invocation.getArgument(0);
> -                final Map<String, byte[]> resultMap = new HashMap<>();
> -                if (keys.contains(storageKey1)) {
> -                    resultMap.put(storageKey1, serialize(key1, value1));
> -                }
> -                if (keys.contains(storageKey2)) {
> -                    resultMap.put(storageKey2, serialize("not foo",
> value2));
> -                }
> -                return resultMap;
> +
> when(impl.bulkRestore(ArgumentMatchers.<String>anyCollection())).thenAnswer((Answer<Map<String,
> byte[]>>) invocation -> {
> +            final Collection<String> keys = invocation.getArgument(0);
> +            final Map<String, byte[]> resultMap = new HashMap<>();
> +            if (keys.contains(storageKey1)) {
> +                resultMap.put(storageKey1, serialize(key1, value1));
> +            }
> +            if (keys.contains(storageKey2)) {
> +                resultMap.put(storageKey2, serialize("not foo", value2));
>              }
> +            return resultMap;
>          });
>
>          final Map<String, HttpCacheEntry> entryMap =
> impl.getEntries(Arrays.asList(key1, key2));
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
> index ace354b..66aa443 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachedHttpResponseGenerator.java
> @@ -55,7 +55,7 @@ public class TestCachedHttpResponseGenerator {
>
>      @Before
>      public void setUp() {
> -        entry = HttpTestUtils.makeCacheEntry(new HashMap<String,
> String>());
> +        entry = HttpTestUtils.makeCacheEntry(new HashMap<>());
>          request = HttpTestUtils.makeDefaultRequest();
>          mockValidityPolicy = mock(CacheValidityPolicy.class);
>          impl = new CachedHttpResponseGenerator(mockValidityPolicy);
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
> index 171da3e..8ec3db6 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestCachingExec.java
> @@ -170,7 +170,7 @@ public class TestCachingExec extends
> TestCachingExecChain {
>          mockImplMethods(CALL_BACKEND);
>          requestPolicyAllowsCaching(true);
>          getCacheEntryReturns(null);
> -        getVariantCacheEntriesReturns(new HashMap<String,Variant>());
> +        getVariantCacheEntriesReturns(new HashMap<>());
>
>          requestIsFatallyNonCompliant(null);
>
> diff --git
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
> index 186b886..58ca6a0 100644
> ---
> a/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
> +++
> b/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestConditionalRequestBuilder.java
> @@ -34,7 +34,6 @@ import java.util.Map;
>  import org.apache.hc.client5.http.cache.HeaderConstants;
>  import org.apache.hc.client5.http.cache.HttpCacheEntry;
>  import org.apache.hc.client5.http.utils.DateUtils;
> -import org.apache.hc.core5.function.Factory;
>  import org.apache.hc.core5.http.Header;
>  import org