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/03/11 22:12:24 UTC

[httpcomponents-core] branch master updated (f136e59 -> 5db3bc3)

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

olegk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-core.git.


    from f136e59  Upgraded API compatibility level to 5.1
     new d60962b  Upgraded project version to 5.2-alpha1-SNAPSHOT
     new da924c8  Upgrade to Java 1.8
     new 319b4ef  Replaced Clirr with JApiCmp
     new ffa201f  Added default `ConnectionAcceptor#listen` method that takes an optional attachment as a parameter
     new b5b2f09  TLS upgrade and TLS strategy APIs redesign
     new 5db3bc3  Protocol upgrade APIs redesign

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .travis.yml                                        |   4 -
 README.md                                          |   2 +-
 httpcore5-h2/pom.xml                               |  32 +-
 .../hc/core5/http2/hpack/OutboundDynamicTable.java |   6 +-
 .../http2/impl/DefaultH2RequestConverter.java      |  43 +-
 .../impl/nio/AbstractH2StreamMultiplexer.java      |  13 +-
 .../http2/impl/nio/ClientH2StreamHandler.java      |  12 +-
 .../http2/impl/nio/ClientH2UpgradeHandler.java     |  62 +-
 .../impl/nio/ClientHttpProtocolNegotiator.java     |   1 +
 .../nio/ClientHttpProtocolNegotiatorFactory.java   |  14 +-
 .../impl/nio/H2OnlyClientProtocolNegotiator.java   |  13 +-
 .../http2/impl/nio/ServerH2UpgradeHandler.java     |  62 +-
 .../impl/nio/ServerHttpProtocolNegotiator.java     |   1 +
 .../nio/ServerHttpProtocolNegotiatorFactory.java   |  12 +-
 .../http2/impl/nio/bootstrap/H2AsyncRequester.java |  60 ++
 .../nio/bootstrap/H2MultiplexingRequester.java     | 168 +++--
 .../H2MultiplexingRequesterBootstrap.java          |  12 +-
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  11 +-
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  41 +-
 .../apache/hc/core5/http2/nio/pool/H2ConnPool.java |  26 +-
 .../http2/ssl/ConscryptClientTlsStrategy.java      |  31 +-
 .../http2/ssl/ConscryptServerTlsStrategy.java      |  32 +-
 .../hc/core5/http2/ssl/ConscryptSupport.java       |  53 +-
 .../hc/core5/http2/ssl/H2ClientTlsStrategy.java    |  31 +-
 .../hc/core5/http2/ssl/H2ServerTlsStrategy.java    |  32 +-
 .../apache/hc/core5/http2/ssl/H2TlsSupport.java    |  25 +-
 .../H2ConscriptRequestExecutionExample.java        |  13 +-
 .../core5/http2/examples/H2FileServerExample.java  |  15 +-
 .../http2/examples/H2FullDuplexClientExample.java  |  11 +-
 .../http2/examples/H2FullDuplexServerExample.java  | 187 +++--
 .../hc/core5/http2/examples/H2GreetingServer.java  |  26 +-
 .../examples/H2MultiStreamExecutionExample.java    |  11 +-
 .../http2/examples/H2RequestExecutionExample.java  |  11 +-
 .../examples/H2TlsAlpnRequestExecutionExample.java |  38 +-
 .../examples/H2ViaHttp1ProxyExecutionExample.java  | 233 ++++++
 .../http2/impl/TestDefaultH2RequestConverter.java  |   2 +-
 .../http2/impl/TestDefaultH2ResponseConverter.java |   2 +-
 httpcore5-reactive/pom.xml                         |  32 +-
 .../core5/reactive/ReactiveResponseConsumer.java   |   4 +-
 .../reactive/ReactiveServerExchangeHandler.java    |  15 +-
 .../core5/reactive/TestReactiveDataConsumer.java   |  27 +-
 .../examples/ReactiveFullDuplexClientExample.java  |  41 +-
 .../examples/ReactiveFullDuplexServerExample.java  |  61 +-
 httpcore5-testing/pom.xml                          |   7 +-
 .../apache/hc/core5/benchmark/HttpBenchmark.java   | 251 +++----
 .../org/apache/hc/core5/testing/SocksProxy.java    |  56 +-
 .../core5/testing/framework/TestingFramework.java  |   3 +-
 .../apache/hc/core5/testing/nio/H2TestServer.java  |  27 +-
 .../hc/core5/testing/nio/Http1TestServer.java      |  18 +-
 .../core5/testing/reactive/ReactiveTestUtils.java  |  12 +-
 .../hc/core5/benchmark/BenchmarkToolTest.java      |   4 +-
 .../testing/classic/ClassicIntegrationTest.java    | 328 +++------
 .../classic/ClassicServerAndRequesterTest.java     |  41 +-
 .../classic/ClassicServerBootstrapFilterTest.java  |  16 +-
 .../testing/classic/ClassicTLSIntegrationTest.java |  40 +-
 ...gResponseOutOfOrderStrategyIntegrationTest.java |  28 +-
 .../compatibility/http2/H2CompatibilityTest.java   |  59 +-
 .../nio/AsyncServerBootstrapFilterTest.java        |  33 +-
 .../apache/hc/core5/testing/nio/H2AlpnTest.java    |  11 +-
 .../hc/core5/testing/nio/H2IntegrationTest.java    | 366 +++-------
 .../testing/nio/H2ProtocolNegotiationTest.java     |  11 +-
 .../nio/H2ServerAndMultiplexingRequesterTest.java  |  11 +-
 .../testing/nio/H2ServerAndRequesterTest.java      |  13 +-
 .../testing/nio/H2ServerBootstrapFiltersTest.java  |  33 +-
 .../hc/core5/testing/nio/H2TLSIntegrationTest.java |  99 +--
 .../core5/testing/nio/Http1AuthenticationTest.java |  11 +-
 .../hc/core5/testing/nio/Http1IntegrationTest.java | 794 +++++++--------------
 .../testing/nio/Http1ServerAndRequesterTest.java   |  66 +-
 .../testing/nio/JSSEProviderIntegrationTest.java   |  55 +-
 .../core5/testing/reactive/ReactiveClientTest.java |  41 +-
 httpcore5/pom.xml                                  |  57 +-
 .../apache/hc/core5/concurrent/ComplexFuture.java  |   9 +-
 .../impl/bootstrap/AsyncRequesterBootstrap.java    |   4 +-
 .../http/impl/bootstrap/AsyncServerBootstrap.java  |  38 +-
 .../http/impl/bootstrap/HttpAsyncRequester.java    | 236 +++---
 .../core5/http/impl/bootstrap/HttpRequester.java   |   9 +-
 .../hc/core5/http/impl/bootstrap/HttpServer.java   |   4 +-
 .../http/impl/bootstrap/RequesterBootstrap.java    |   4 +-
 .../core5/http/impl/bootstrap/ServerBootstrap.java |  12 +-
 .../impl/nio/ClientHttp1IOEventHandlerFactory.java |  10 +-
 .../http/impl/nio/ClientHttp1StreamHandler.java    |  12 +-
 .../impl/nio/ServerHttp1IOEventHandlerFactory.java |  22 +-
 .../hc/core5/http/io/entity/HttpEntities.java      |   9 +-
 .../io/support/HttpServerFilterChainElement.java   |  11 +-
 .../hc/core5/http/nio/command/ShutdownCommand.java |   9 +-
 ...Consumer.java => DiscardingEntityConsumer.java} |  10 +-
 .../core5/http/nio/entity/NoopEntityConsumer.java  |   3 +
 .../core5/http/nio/ssl/BasicClientTlsStrategy.java |  20 +-
 .../core5/http/nio/ssl/BasicServerTlsStrategy.java |  20 +-
 .../apache/hc/core5/http/nio/ssl/TlsStrategy.java  |  32 +-
 .../apache/hc/core5/http/nio/ssl/TlsSupport.java   |  21 +-
 .../nio/ssl/TlsUpgradeCapable.java}                |  13 +-
 .../support/AbstractAsyncRequesterConsumer.java    |   9 +-
 .../nio/support/AbstractAsyncResponseConsumer.java |   9 +-
 .../nio/support/AsyncServerFilterChainElement.java |  13 +-
 .../http/nio/support/BasicRequestConsumer.java     |   9 +-
 .../http/nio/support/BasicResponseConsumer.java    |   9 +-
 .../classic/AbstractClassicEntityConsumer.java     |  25 +-
 .../classic/AbstractClassicEntityProducer.java     |  21 +-
 .../AbstractClassicServerExchangeHandler.java      |  29 +-
 .../http/protocol/RequestHandlerRegistry.java      |  18 +-
 .../java/org/apache/hc/core5/net/URIBuilder.java   |   8 +-
 .../java/org/apache/hc/core5/pool/LaxConnPool.java |  22 +-
 .../org/apache/hc/core5/pool/StrictConnPool.java   |  22 +-
 .../hc/core5/reactor/AbstractIOSessionPool.java    |  31 +-
 .../hc/core5/reactor/ConnectionAcceptor.java       |  18 +
 .../core5/reactor/DefaultListeningIOReactor.java   |   9 +-
 .../hc/core5/reactor/InternalDataChannel.java      |  79 +-
 .../apache/hc/core5/reactor/ProtocolIOSession.java |  24 +
 ...lerFactory.java => ProtocolUpgradeHandler.java} |  13 +-
 .../hc/core5/reactor/SingleCoreIOReactor.java      |  38 +-
 .../apache/hc/core5/reactor/ssl/SSLIOSession.java  |  16 +-
 .../core5/reactor/ssl/TransportSecurityLayer.java  |  29 +
 .../org/apache/hc/core5/util/ReflectionUtils.java  |   9 +-
 .../hc/core5/concurrent/TestBasicFuture.java       |  68 +-
 .../http/examples/AsyncFileServerExample.java      |  17 +-
 .../examples/AsyncFullDuplexClientExample.java     |  23 +-
 .../examples/AsyncFullDuplexServerExample.java     | 187 +++--
 .../AsyncPipelinedRequestExecutionExample.java     |  11 +-
 .../examples/AsyncRequestExecutionExample.java     |  11 +-
 .../http/examples/AsyncReverseProxyExample.java    |  25 +-
 .../http/examples/AsyncServerFilterExample.java    |  75 +-
 .../http/examples/ClassicFileServerExample.java    |   9 +-
 .../http/examples/ClassicPostExecutionExample.java |  14 +-
 .../http/examples/ClassicReverseProxyExample.java  |  11 +-
 .../http/examples/ClassicServerFilterExample.java  |  75 +-
 .../hc/core5/http/impl/io/TestChunkCoding.java     |  13 +-
 .../hc/core5/http/impl/io/TestHttpService.java     |  36 +-
 .../http/io/entity/TestSerializableEntity.java     |   4 +-
 .../nio/support/classic/TestSharedInputBuffer.java | 110 +--
 .../support/classic/TestSharedOutputBuffer.java    |  83 +--
 .../http/protocol/TestRequestHandlerRegistry.java  |  10 +-
 .../org/apache/hc/core5/net/TestURIBuilder.java    |   2 +-
 .../org/apache/hc/core5/pool/TestLaxConnPool.java  |   4 +-
 .../org/apache/hc/core5/pool/TestPoolEntry.java    |   9 +-
 .../apache/hc/core5/pool/TestStrictConnPool.java   |  29 +-
 .../core5/reactor/TestAbstractIOSessionPool.java   |  60 +-
 .../apache/hc/core5/ssl/TestSSLContextBuilder.java | 167 ++---
 .../java/org/apache/hc/core5/util/TestArgs.java    |   2 +-
 .../java/org/apache/hc/core5/util/TestAsserts.java |   4 +-
 pom.xml                                            | 114 +--
 141 files changed, 2587 insertions(+), 3573 deletions(-)
 copy httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/PathEntity.java => httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2UpgradeHandler.java (52%)
 copy httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/PathEntity.java => httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2UpgradeHandler.java (52%)
 create mode 100644 httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ViaHttp1ProxyExecutionExample.java
 copy httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/{NoopEntityConsumer.java => DiscardingEntityConsumer.java} (90%)
 copy httpcore5/src/main/java/org/apache/hc/core5/{reactor/IOEventHandlerFactory.java => http/nio/ssl/TlsUpgradeCapable.java} (77%)
 copy httpcore5/src/main/java/org/apache/hc/core5/reactor/{IOEventHandlerFactory.java => ProtocolUpgradeHandler.java} (76%)


[httpcomponents-core] 01/06: Upgraded project version to 5.2-alpha1-SNAPSHOT

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d60962b000f38af8c35d9bdba87c5095a5e32578
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sat Dec 5 13:56:56 2020 +0100

    Upgraded project version to 5.2-alpha1-SNAPSHOT
---
 httpcore5-h2/pom.xml       | 32 +++++++++++++++++++++++---
 httpcore5-reactive/pom.xml | 32 +++++++++++++++++++++++---
 httpcore5-testing/pom.xml  |  7 +++---
 httpcore5/pom.xml          | 57 ++++++++++++++++++++++++++++++++++++----------
 pom.xml                    | 37 ++++--------------------------
 5 files changed, 111 insertions(+), 54 deletions(-)

diff --git a/httpcore5-h2/pom.xml b/httpcore5-h2/pom.xml
index 775b6ab..7bcd21f 100644
--- a/httpcore5-h2/pom.xml
+++ b/httpcore5-h2/pom.xml
@@ -23,16 +23,18 @@
    individuals on behalf of the Apache Software Foundation.  For more
    information on the Apache Software Foundation, please see
    <http://www.apache.org />.
- --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.httpcomponents.core5</groupId>
     <artifactId>httpcore5-parent</artifactId>
-    <version>5.1.1-SNAPSHOT</version>
+    <version>5.2-alpha1-SNAPSHOT</version>
   </parent>
   <artifactId>httpcore5-h2</artifactId>
   <name>Apache HttpComponents Core HTTP/2</name>
   <description>Apache HttpComponents HTTP/2 Core Components</description>
+  <url>https://hc.apache.org/httpcomponents-core-5.1.x/</url>
+  <packaging>jar</packaging>
 
   <properties>
     <Automatic-Module-Name>org.apache.httpcomponents.core5.httpcore5.h2</Automatic-Module-Name>
@@ -76,6 +78,31 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-resources</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/site/examples</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/test/java/org/apache/hc/core5/http2/examples</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
   <reporting>
     <plugins>
       <plugin>
@@ -84,7 +111,6 @@
         <reportSets>
           <reportSet>
             <reports>
-              <report>index</report>
               <report>dependencies</report>
               <report>dependency-info</report>
               <report>summary</report>
diff --git a/httpcore5-reactive/pom.xml b/httpcore5-reactive/pom.xml
index 14a4d23..e47eba8 100644
--- a/httpcore5-reactive/pom.xml
+++ b/httpcore5-reactive/pom.xml
@@ -27,13 +27,15 @@
   <parent>
     <artifactId>httpcore5-parent</artifactId>
     <groupId>org.apache.httpcomponents.core5</groupId>
-    <version>5.1.1-SNAPSHOT</version>
+    <version>5.2-alpha1-SNAPSHOT</version>
   </parent>
   <modelVersion>4.0.0</modelVersion>
 
   <artifactId>httpcore5-reactive</artifactId>
   <name>Apache HttpComponents Core Reactive Extensions</name>
   <description>Apache HttpComponents Reactive Streams Bindings</description>
+  <url>https://hc.apache.org/httpcomponents-core-5.1.x/</url>
+  <packaging>jar</packaging>
 
   <properties>
     <Automatic-Module-Name>org.apache.httpcomponents.core5.httpcore5.reactive</Automatic-Module-Name>
@@ -48,7 +50,7 @@
     <dependency>
       <groupId>org.reactivestreams</groupId>
       <artifactId>reactive-streams</artifactId>
-      <version>1.0.3</version>
+      <version>1.0.2</version>
     </dependency>
     <dependency>
       <groupId>junit</groupId>
@@ -63,6 +65,31 @@
     </dependency>
   </dependencies>
 
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-resources</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/site/examples</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/test/java/org/apache/hc/core5/reactive/examples</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
+    </plugins>
+  </build>
+
   <reporting>
     <plugins>
       <plugin>
@@ -71,7 +98,6 @@
         <reportSets>
           <reportSet>
             <reports>
-              <report>index</report>
               <report>dependencies</report>
               <report>dependency-info</report>
               <report>summary</report>
diff --git a/httpcore5-testing/pom.xml b/httpcore5-testing/pom.xml
index 30687be..14a59b0 100644
--- a/httpcore5-testing/pom.xml
+++ b/httpcore5-testing/pom.xml
@@ -23,16 +23,18 @@
    individuals on behalf of the Apache Software Foundation.  For more
    information on the Apache Software Foundation, please see
    <http://www.apache.org />.
- --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.httpcomponents.core5</groupId>
     <artifactId>httpcore5-parent</artifactId>
-    <version>5.1.1-SNAPSHOT</version>
+    <version>5.2-alpha1-SNAPSHOT</version>
   </parent>
   <artifactId>httpcore5-testing</artifactId>
   <name>Apache HttpComponents Core Integration Tests</name>
   <description>Apache HttpComponents HTTP/2 and HTTP/1.1 core component integration tests</description>
+  <url>https://hc.apache.org/httpcomponents-core-5.1.x/</url>
+  <packaging>jar</packaging>
 
   <properties>
     <Automatic-Module-Name>org.apache.httpcomponents.core5.httpcore5.testing</Automatic-Module-Name>
@@ -166,7 +168,6 @@
         <reportSets>
           <reportSet>
             <reports>
-              <report>index</report>
               <report>dependencies</report>
               <report>dependency-info</report>
               <report>summary</report>
diff --git a/httpcore5/pom.xml b/httpcore5/pom.xml
index fb69920..1d50b09 100644
--- a/httpcore5/pom.xml
+++ b/httpcore5/pom.xml
@@ -23,17 +23,19 @@
    individuals on behalf of the Apache Software Foundation.  For more
    information on the Apache Software Foundation, please see
    <http://www.apache.org />.
- --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>org.apache.httpcomponents.core5</groupId>
     <artifactId>httpcore5-parent</artifactId>
-    <version>5.1.1-SNAPSHOT</version>
+    <version>5.2-alpha1-SNAPSHOT</version>
   </parent>
   <artifactId>httpcore5</artifactId>
   <name>Apache HttpComponents Core HTTP/1.1</name>
   <inceptionYear>2005</inceptionYear>
   <description>Apache HttpComponents HTTP/1.1 core components</description>
+  <url>https://hc.apache.org/httpcomponents-core-5.1.x/</url>
+  <packaging>jar</packaging>
 
   <properties>
     <Automatic-Module-Name>org.apache.httpcomponents.core5.httpcore5</Automatic-Module-Name>
@@ -68,15 +70,6 @@
   </dependencies>
 
   <build>
-    <resources>
-      <resource>
-        <directory>src/main/resources</directory>
-        <filtering>true</filtering>
-        <includes>
-          <include>**/*.properties</include>
-        </includes>
-      </resource>
-    </resources>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
@@ -89,7 +82,48 @@
           </execution>
         </executions>
       </plugin>
+      <plugin>
+        <groupId>org.apache.rat</groupId>
+        <artifactId>apache-rat-plugin</artifactId>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>check</goal>
+            </goals>
+          </execution>
+        </executions>
+      </plugin>
+      <plugin>
+        <artifactId>maven-resources-plugin</artifactId>
+        <executions>
+          <execution>
+            <id>copy-resources</id>
+            <phase>pre-site</phase>
+            <goals>
+              <goal>copy-resources</goal>
+            </goals>
+            <configuration>
+              <outputDirectory>${basedir}/target/site/examples</outputDirectory>
+              <resources>
+                <resource>
+                  <directory>src/test/java/org/apache/hc/core5/http/examples</directory>
+                </resource>
+              </resources>
+            </configuration>
+          </execution>
+        </executions>
+      </plugin>
     </plugins>
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <includes>
+            <include>**/*.properties</include>
+        </includes>
+      </resource>
+    </resources>
   </build>
 
   <reporting>
@@ -100,7 +134,6 @@
         <reportSets>
           <reportSet>
             <reports>
-              <report>index</report>
               <report>dependencies</report>
               <report>dependency-info</report>
               <report>summary</report>
diff --git a/pom.xml b/pom.xml
index 1fbf1f7..fa8dbfc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,7 +23,7 @@
    individuals on behalf of the Apache Software Foundation.  For more
    information on the Apache Software Foundation, please see
    <http://www.apache.org />.
- --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ --><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
   <parent>
     <groupId>org.apache.httpcomponents</groupId>
     <artifactId>httpcomponents-parent</artifactId>
@@ -33,9 +33,9 @@
   <groupId>org.apache.httpcomponents.core5</groupId>
   <artifactId>httpcore5-parent</artifactId>
   <name>Apache HttpComponents Core Parent</name>
-  <version>5.1.1-SNAPSHOT</version>
+  <version>5.2-alpha1-SNAPSHOT</version>
   <description>Apache HttpComponents Core is a library of components for building HTTP enabled services</description>
-  <url>https://hc.apache.org/httpcomponents-core-5.1.x/${project.version}/</url>
+  <url>https://hc.apache.org/httpcomponents-core-5.1.x/</url>
   <inceptionYear>2005</inceptionYear>
   <packaging>pom</packaging>
 
@@ -48,17 +48,9 @@
     <connection>scm:git:https://gitbox.apache.org/repos/asf/httpcomponents-core.git</connection>
     <developerConnection>scm:git:https://gitbox.apache.org/repos/asf/httpcomponents-core.git</developerConnection>
     <url>https://github.com/apache/httpcomponents-core/tree/${project.scm.tag}</url>
-    <tag>5.1.1-SNAPSHOT</tag>
+    <tag>5.2.x</tag>
   </scm>
 
-  <distributionManagement>
-    <site>
-      <id>apache.website</id>
-      <name>Apache HttpComponents Website</name>
-      <url>scm:svn:https://svn.apache.org/repos/asf/httpcomponents/site/components/httpcomponents-core-5.1.x/LATEST/</url>
-    </site>
-  </distributionManagement>
-
   <modules>
     <module>httpcore5</module>
     <module>httpcore5-h2</module>
@@ -209,7 +201,6 @@
         <reportSets>
           <reportSet>
             <reports>
-              <report>index</report>
               <report>dependency-info</report>
               <report>dependency-management</report>
               <report>issue-management</report>
@@ -230,31 +221,11 @@
             <link>${project.url}/httpcore5/apidocs/</link>
             <link>${project.url}/httpcore5-h2/apidocs/</link>
           </links>
-          <notimestamp>true</notimestamp>
-          <groups>
-            <group>
-              <title>Apache HttpCore HTTP/1.1</title>
-              <packages>org.apache.hc.core5*</packages>
-            </group>
-            <group>
-              <title>Apache HttpCore HTTP/2</title>
-              <packages>org.apache.hc.core5.http2*</packages>
-            </group>
-            <group>
-              <title>Apache HttpCore Reactive Streams Bindings</title>
-              <packages>org.apache.hc.core5.reactive*</packages>
-            </group>
-            <group>
-              <title>Apache HttpCore Testing</title>
-              <packages>org.apache.hc.core5.testing*:org.apache.hc.core5.benchmark*</packages>
-            </group>
-          </groups>
         </configuration>
         <reportSets>
           <reportSet>
             <reports>
               <report>javadoc</report>
-              <report>aggregate</report>
             </reports>
           </reportSet>
         </reportSets>


[httpcomponents-core] 06/06: Protocol upgrade APIs redesign

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 5db3bc3eb9107253f3169d3028305d5f99e71e3b
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Thu Dec 17 20:59:03 2020 +0100

    Protocol upgrade APIs redesign
---
 .../http2/impl/nio/ClientH2UpgradeHandler.java     |  69 ++++++
 .../impl/nio/ClientHttpProtocolNegotiator.java     |   1 +
 .../impl/nio/H2OnlyClientProtocolNegotiator.java   |  13 +-
 .../http2/impl/nio/ServerH2UpgradeHandler.java     |  69 ++++++
 .../impl/nio/ServerHttpProtocolNegotiator.java     |   1 +
 .../http2/impl/nio/bootstrap/H2AsyncRequester.java |  60 ++++++
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |   4 +-
 .../examples/H2ViaHttp1ProxyExecutionExample.java  | 233 +++++++++++++++++++++
 .../http/impl/bootstrap/HttpAsyncRequester.java    |  66 +++++-
 .../nio/ssl/TlsUpgradeCapable.java}                |  15 +-
 .../hc/core5/reactor/InternalDataChannel.java      |  24 +++
 .../apache/hc/core5/reactor/ProtocolIOSession.java |  24 +++
 ...lIOSession.java => ProtocolUpgradeHandler.java} |  17 +-
 13 files changed, 579 insertions(+), 17 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2UpgradeHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2UpgradeHandler.java
new file mode 100644
index 0000000..ee548f8
--- /dev/null
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2UpgradeHandler.java
@@ -0,0 +1,69 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http2.impl.nio;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.reactor.ProtocolUpgradeHandler;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Protocol upgrade handler that upgrades the underlying {@link ProtocolIOSession}
+ * to HTTP/2 in case of a successful protocol negotiation.
+ *
+ * @since 5.2
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
+@Internal
+public class ClientH2UpgradeHandler implements ProtocolUpgradeHandler {
+
+    private final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory;
+
+    public ClientH2UpgradeHandler(final ClientH2StreamMultiplexerFactory http2StreamHandlerFactory) {
+        this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
+    }
+
+    @Override
+    public void upgrade(final ProtocolIOSession ioSession, final FutureCallback<ProtocolIOSession> callback) {
+        final HttpConnectionEventHandler protocolNegotiator = new H2OnlyClientProtocolNegotiator(
+                ioSession, http2StreamHandlerFactory, true, callback);
+        ioSession.upgrade(protocolNegotiator);
+        try {
+            protocolNegotiator.connected(ioSession);
+        } catch (final IOException ex) {
+            protocolNegotiator.exception(ioSession, ex);
+        }
+    }
+
+}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
index a1a7f4b..9c2152f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiator.java
@@ -95,6 +95,7 @@ public class ClientHttpProtocolNegotiator extends ProtocolNegotiatorBase {
     private void startHttp1() throws IOException {
         final ByteBuffer data = inBuf != null ? inBuf.data() : null;
         startProtocol(new ClientHttp1IOEventHandler(http1StreamHandlerFactory.create(ioSession)), data);
+        ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ClientH2UpgradeHandler(http2StreamHandlerFactory));
         if (inBuf != null) {
             inBuf.clear();
         }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
index a4f7df5..388e034 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/H2OnlyClientProtocolNegotiator.java
@@ -34,6 +34,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
 
 import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.impl.nio.BufferedData;
 import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
@@ -56,6 +57,7 @@ public class H2OnlyClientProtocolNegotiator extends ProtocolNegotiatorBase {
     private final AtomicBoolean initialized;
 
     private volatile ByteBuffer preface;
+    private volatile BufferedData inBuf;
 
     public H2OnlyClientProtocolNegotiator(
             final ProtocolIOSession ioSession,
@@ -103,7 +105,11 @@ public class H2OnlyClientProtocolNegotiator extends ProtocolNegotiatorBase {
         if (!preface.hasRemaining()) {
             session.clearEvent(SelectionKey.OP_WRITE);
             final ClientH2StreamMultiplexer streamMultiplexer = http2StreamHandlerFactory.create(ioSession);
-            startProtocol(new ClientH2IOEventHandler(streamMultiplexer), null);
+            final ByteBuffer data = inBuf != null ? inBuf.data() : null;
+            startProtocol(new ClientH2IOEventHandler(streamMultiplexer), data);
+            if (inBuf != null) {
+                inBuf.clear();
+            }
             preface = null;
         }
     }
@@ -130,7 +136,10 @@ public class H2OnlyClientProtocolNegotiator extends ProtocolNegotiatorBase {
     @Override
     public void inputReady(final IOSession session, final ByteBuffer src) throws IOException {
         if (src != null) {
-            throw new ProtocolNegotiationException("Unexpected input");
+            if (inBuf == null) {
+                inBuf = BufferedData.allocate(src.remaining());
+            }
+            inBuf.put(src);
         }
         if (preface != null) {
             writeOutPreface(session);
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2UpgradeHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2UpgradeHandler.java
new file mode 100644
index 0000000..181a465
--- /dev/null
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerH2UpgradeHandler.java
@@ -0,0 +1,69 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.hc.core5.http2.impl.nio;
+
+import java.io.IOException;
+
+import org.apache.hc.core5.annotation.Contract;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.annotation.ThreadingBehavior;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.http.impl.nio.HttpConnectionEventHandler;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.reactor.ProtocolUpgradeHandler;
+import org.apache.hc.core5.util.Args;
+
+/**
+ * Protocol upgrade handler that upgrades the underlying {@link ProtocolIOSession}
+ * to HTTP/2 in case of a successful protocol negotiation.
+ *
+ * @since 5.2
+ */
+@Contract(threading = ThreadingBehavior.IMMUTABLE_CONDITIONAL)
+@Internal
+public class ServerH2UpgradeHandler implements ProtocolUpgradeHandler {
+
+    private final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory;
+
+    public ServerH2UpgradeHandler(final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory) {
+        this.http2StreamHandlerFactory = Args.notNull(http2StreamHandlerFactory, "HTTP/2 stream handler factory");
+    }
+
+    @Override
+    public void upgrade(final ProtocolIOSession ioSession, final FutureCallback<ProtocolIOSession> callback) {
+        final HttpConnectionEventHandler protocolNegotiator = new H2OnlyServerHttpProtocolNegotiator(
+                ioSession, http2StreamHandlerFactory, callback);
+        ioSession.upgrade(protocolNegotiator);
+        try {
+            protocolNegotiator.connected(ioSession);
+        } catch (final IOException ex) {
+            protocolNegotiator.exception(ioSession, ex);
+        }
+    }
+
+}
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
index 8d9aed2..f6febff 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiator.java
@@ -96,6 +96,7 @@ public class ServerHttpProtocolNegotiator extends ProtocolNegotiatorBase {
                 tlsDetails != null ? URIScheme.HTTPS.id : URIScheme.HTTP.id,
                 ioSession);
         startProtocol(new ServerHttp1IOEventHandler(http1StreamHandler), data);
+        ioSession.registerProtocol(ApplicationProtocol.HTTP_2.id, new ServerH2UpgradeHandler(http2StreamHandlerFactory));
     }
 
     private void startHttp2(final ByteBuffer data) throws IOException {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
index de22471..e88a11f 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2AsyncRequester.java
@@ -30,18 +30,24 @@ package org.apache.hc.core5.http2.impl.nio.bootstrap;
 import java.util.concurrent.Future;
 
 import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.concurrent.CallbackContribution;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.ssl.ApplicationProtocol;
+import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.pool.ManagedConnPool;
 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.reactor.IOSessionListener;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.reactor.ssl.TlsDetails;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -70,6 +76,27 @@ public class H2AsyncRequester extends HttpAsyncRequester {
         this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
     }
 
+    /**
+     * Use {@link H2RequesterBootstrap} to create instances of this class.
+     *
+     * @since 5.2
+     */
+    @Internal
+    public H2AsyncRequester(
+            final HttpVersionPolicy versionPolicy,
+            final IOReactorConfig ioReactorConfig,
+            final IOEventHandlerFactory eventHandlerFactory,
+            final Decorator<IOSession> ioSessionDecorator,
+            final Callback<Exception> exceptionCallback,
+            final IOSessionListener sessionListener,
+            final ManagedConnPool<HttpHost, IOSession> connPool,
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
+        super(ioReactorConfig, eventHandlerFactory, ioSessionDecorator, exceptionCallback, sessionListener, connPool,
+                tlsStrategy, handshakeTimeout);
+        this.versionPolicy = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
+    }
+
     @Override
     protected Future<AsyncClientEndpoint> doConnect(
             final HttpHost host,
@@ -79,4 +106,37 @@ public class H2AsyncRequester extends HttpAsyncRequester {
         return super.doConnect(host, timeout, attachment != null ? attachment : versionPolicy, callback);
     }
 
+    @Override
+    protected void doTlsUpgrade(final ProtocolIOSession ioSession,
+                                final NamedEndpoint endpoint,
+                                final FutureCallback<ProtocolIOSession> callback) {
+        super.doTlsUpgrade(ioSession, endpoint, new CallbackContribution<ProtocolIOSession>(callback) {
+
+            @Override
+            public void completed(final ProtocolIOSession protocolSession) {
+                final boolean switchProtocol;
+                switch (versionPolicy) {
+                    case FORCE_HTTP_2:
+                        switchProtocol = true;
+                        break;
+                    case NEGOTIATE:
+                        final TlsDetails tlsDetails = protocolSession.getTlsDetails();
+                        final String appProtocol = tlsDetails != null ? tlsDetails.getApplicationProtocol() : null;
+                        switchProtocol = ApplicationProtocol.HTTP_2.id.equals(appProtocol);
+                        break;
+                    default:
+                        switchProtocol = false;
+                }
+                if (switchProtocol) {
+                    protocolSession.switchProtocol(ApplicationProtocol.HTTP_2.id, callback);
+                } else {
+                    if (callback != null) {
+                        callback.completed(protocolSession);
+                    }
+                }
+            }
+
+        });
+    }
+
 }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index ab94662..dc5883c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -348,7 +348,9 @@ public class H2RequesterBootstrap {
                 ioSessionDecorator,
                 exceptionCallback,
                 sessionListener,
-                connPool);
+                connPool,
+                actualTlsStrategy,
+                handshakeTimeout);
     }
 
 }
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ViaHttp1ProxyExecutionExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ViaHttp1ProxyExecutionExample.java
new file mode 100644
index 0000000..9f2e1fd
--- /dev/null
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ViaHttp1ProxyExecutionExample.java
@@ -0,0 +1,233 @@
+/*
+ * ====================================================================
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+package org.apache.hc.core5.http2.examples;
+
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.hc.core5.concurrent.ComplexFuture;
+import org.apache.hc.core5.concurrent.FutureCallback;
+import org.apache.hc.core5.concurrent.FutureContribution;
+import org.apache.hc.core5.http.Header;
+import org.apache.hc.core5.http.HttpConnection;
+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.Message;
+import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.impl.Http1StreamListener;
+import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
+import org.apache.hc.core5.http.message.BasicHttpRequest;
+import org.apache.hc.core5.http.message.RequestLine;
+import org.apache.hc.core5.http.message.StatusLine;
+import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
+import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
+import org.apache.hc.core5.http.nio.ssl.TlsUpgradeCapable;
+import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
+import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
+import org.apache.hc.core5.http2.HttpVersionPolicy;
+import org.apache.hc.core5.http2.config.H2Config;
+import org.apache.hc.core5.http2.frame.RawFrame;
+import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
+import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
+import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.util.Timeout;
+
+/**
+ * Example of asynchronous HTTP/2 request execution via a HTTP/1.1 proxy.
+ */
+public class H2ViaHttp1ProxyExecutionExample {
+
+    public static void main(final String[] args) throws Exception {
+
+        // Create and start requester
+        final H2Config h2Config = H2Config.custom()
+                .setPushEnabled(false)
+                .build();
+
+        final HttpAsyncRequester requester = H2RequesterBootstrap.bootstrap()
+                .setH2Config(h2Config)
+                .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
+                .setStreamListener(new Http1StreamListener() {
+
+                    @Override
+                    public void onRequestHead(final HttpConnection connection, final HttpRequest request) {
+                        System.out.println(connection.getRemoteAddress() + " " + new RequestLine(request));
+                    }
+
+                    @Override
+                    public void onResponseHead(final HttpConnection connection, final HttpResponse response) {
+                        System.out.println(connection.getRemoteAddress() + " " + new StatusLine(response));
+                    }
+
+                    @Override
+                    public void onExchangeComplete(final HttpConnection connection, final boolean keepAlive) {
+                        if (keepAlive) {
+                            System.out.println(connection.getRemoteAddress() + " exchange completed (connection kept alive)");
+                        } else {
+                            System.out.println(connection.getRemoteAddress() + " exchange completed (connection closed)");
+                        }
+                    }
+
+                })
+                .setStreamListener(new H2StreamListener() {
+
+                    @Override
+                    public void onHeaderInput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
+                        for (int i = 0; i < headers.size(); i++) {
+                            System.out.println(connection.getRemoteAddress() + " (" + streamId + ") << " + headers.get(i));
+                        }
+                    }
+
+                    @Override
+                    public void onHeaderOutput(final HttpConnection connection, final int streamId, final List<? extends Header> headers) {
+                        for (int i = 0; i < headers.size(); i++) {
+                            System.out.println(connection.getRemoteAddress() + " (" + streamId + ") >> " + headers.get(i));
+                        }
+                    }
+
+                    @Override
+                    public void onFrameInput(final HttpConnection connection, final int streamId, final RawFrame frame) {
+                    }
+
+                    @Override
+                    public void onFrameOutput(final HttpConnection connection, final int streamId, final RawFrame frame) {
+                    }
+
+                    @Override
+                    public void onInputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
+                    }
+
+                    @Override
+                    public void onOutputFlowControl(final HttpConnection connection, final int streamId, final int delta, final int actualSize) {
+                    }
+
+                })
+                .create();
+
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
+        requester.start();
+
+        final HttpHost proxy = new HttpHost("localhost", 8888);
+        final HttpHost target = new HttpHost("https", "nghttp2.org");
+
+        final ComplexFuture<AsyncClientEndpoint> tunnelFuture = new ComplexFuture<>(null);
+        tunnelFuture.setDependency(requester.connect(
+                proxy,
+                Timeout.ofSeconds(30),
+                null,
+                new FutureContribution<AsyncClientEndpoint>(tunnelFuture) {
+
+                    @Override
+                    public void completed(final AsyncClientEndpoint endpoint) {
+                        if (endpoint instanceof TlsUpgradeCapable) {
+                            final HttpRequest connect = new BasicHttpRequest(Method.CONNECT, proxy, target.toHostString());
+                            endpoint.execute(
+                                    new BasicRequestProducer(connect, null),
+                                    new BasicResponseConsumer<>(new NoopEntityConsumer()),
+                                    new FutureContribution<Message<HttpResponse, Void>>(tunnelFuture) {
+
+                                        @Override
+                                        public void completed(final Message<HttpResponse, Void> message) {
+                                            final HttpResponse response = message.getHead();
+                                            if (response.getCode() == HttpStatus.SC_OK) {
+                                                ((TlsUpgradeCapable) endpoint).tlsUpgrade(
+                                                        target,
+                                                        new FutureContribution<ProtocolIOSession>(tunnelFuture) {
+
+                                                            @Override
+                                                            public void completed(final ProtocolIOSession protocolSession) {
+                                                                System.out.println("Tunnel to " + target + " via " + proxy + " established");
+                                                                tunnelFuture.completed(endpoint);
+                                                            }
+
+                                                        });
+                                            } else {
+                                                tunnelFuture.failed(new HttpException("Tunnel refused: " + new StatusLine(response)));
+                                            }
+                                        }
+
+                                    });
+                        } else {
+                            tunnelFuture.failed(new IllegalStateException("TLS upgrade not supported"));
+                        }
+                    }
+
+                }));
+
+        final String[] requestUris = new String[] {"/httpbin/ip", "/httpbin/user-agent", "/httpbin/headers"};
+        final AsyncClientEndpoint endpoint = tunnelFuture.get(1, TimeUnit.MINUTES);
+        try {
+            final CountDownLatch latch = new CountDownLatch(requestUris.length);
+            for (final String requestUri : requestUris) {
+                endpoint.execute(
+                        new BasicRequestProducer(Method.GET, target, requestUri),
+                        new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
+                        new FutureCallback<Message<HttpResponse, String>>() {
+
+                            @Override
+                            public void completed(final Message<HttpResponse, String> message) {
+                                final HttpResponse response = message.getHead();
+                                final String body = message.getBody();
+                                System.out.println(requestUri + "->" + response.getCode());
+                                System.out.println(body);
+                                latch.countDown();
+                            }
+
+                            @Override
+                            public void failed(final Exception ex) {
+                                System.out.println(requestUri + "->" + ex);
+                                latch.countDown();
+                            }
+
+                            @Override
+                            public void cancelled() {
+                                System.out.println(requestUri + " cancelled");
+                                latch.countDown();
+                            }
+
+                        });
+            }
+
+            latch.await();
+        } finally {
+            endpoint.releaseAndDiscard();
+        }
+
+        System.out.println("Shutting down I/O reactor");
+        requester.initiateShutdown();
+    }
+
+}
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
index 6ebe715..c87b2d4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
@@ -36,6 +36,7 @@ import java.util.concurrent.atomic.AtomicReference;
 
 import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.concurrent.BasicFuture;
+import org.apache.hc.core5.concurrent.CallbackContribution;
 import org.apache.hc.core5.concurrent.ComplexFuture;
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.concurrent.FutureContribution;
@@ -61,10 +62,13 @@ import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.nio.RequestChannel;
 import org.apache.hc.core5.http.nio.command.RequestExecutionCommand;
 import org.apache.hc.core5.http.nio.command.ShutdownCommand;
+import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+import org.apache.hc.core5.http.nio.ssl.TlsUpgradeCapable;
 import org.apache.hc.core5.http.nio.support.BasicClientExchangeHandler;
 import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.CloseMode;
+import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.net.URIAuthority;
 import org.apache.hc.core5.pool.ConnPoolControl;
 import org.apache.hc.core5.pool.ManagedConnPool;
@@ -77,6 +81,8 @@ 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.reactor.IOSessionListener;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
+import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Args;
 import org.apache.hc.core5.util.TimeValue;
 import org.apache.hc.core5.util.Timeout;
@@ -89,9 +95,13 @@ import org.apache.hc.core5.util.Timeout;
 public class HttpAsyncRequester extends AsyncRequester implements ConnPoolControl<HttpHost> {
 
     private final ManagedConnPool<HttpHost, IOSession> connPool;
+    private final TlsStrategy tlsStrategy;
+    private final Timeout handshakeTimeout;
 
     /**
      * Use {@link AsyncRequesterBootstrap} to create instances of this class.
+     *
+     * @since 5.2
      */
     @Internal
     public HttpAsyncRequester(
@@ -100,10 +110,29 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
             final Decorator<IOSession> ioSessionDecorator,
             final Callback<Exception> exceptionCallback,
             final IOSessionListener sessionListener,
-            final ManagedConnPool<HttpHost, IOSession> connPool) {
+            final ManagedConnPool<HttpHost, IOSession> connPool,
+            final TlsStrategy tlsStrategy,
+            final Timeout handshakeTimeout) {
         super(eventHandlerFactory, ioReactorConfig, ioSessionDecorator, exceptionCallback, sessionListener,
                 ShutdownCommand.GRACEFUL_IMMEDIATE_CALLBACK, DefaultAddressResolver.INSTANCE);
         this.connPool = Args.notNull(connPool, "Connection pool");
+        this.tlsStrategy = tlsStrategy;
+        this.handshakeTimeout = handshakeTimeout;
+    }
+
+    /**
+     * Use {@link AsyncRequesterBootstrap} to create instances of this class.
+     */
+    @Internal
+    public HttpAsyncRequester(
+            final IOReactorConfig ioReactorConfig,
+            final IOEventHandlerFactory eventHandlerFactory,
+            final Decorator<IOSession> ioSessionDecorator,
+            final Callback<Exception> exceptionCallback,
+            final IOSessionListener sessionListener,
+            final ManagedConnPool<HttpHost, IOSession> connPool) {
+        this(ioReactorConfig, eventHandlerFactory, ioSessionDecorator, exceptionCallback, sessionListener, connPool,
+                null, null);
     }
 
     @Override
@@ -403,7 +432,31 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
         return execute(requestProducer, responseConsumer, null, timeout, null, callback);
     }
 
-    private class InternalAsyncClientEndpoint extends AsyncClientEndpoint {
+    protected void doTlsUpgrade(
+            final ProtocolIOSession ioSession,
+            final NamedEndpoint endpoint,
+            final FutureCallback<ProtocolIOSession> callback) {
+        if (tlsStrategy != null) {
+            tlsStrategy.upgrade(ioSession,
+                    endpoint,
+                    null,
+                    handshakeTimeout,
+                    new CallbackContribution<TransportSecurityLayer>(callback) {
+
+                        @Override
+                        public void completed(final TransportSecurityLayer transportSecurityLayer) {
+                            if (callback != null) {
+                                callback.completed(ioSession);
+                            }
+                        }
+
+                    });
+        } else {
+            throw new IllegalStateException("TLS upgrade not supported");
+        }
+    }
+
+    private class InternalAsyncClientEndpoint extends AsyncClientEndpoint implements TlsUpgradeCapable {
 
         final AtomicReference<PoolEntry<HttpHost, IOSession>> poolEntryRef;
 
@@ -471,6 +524,15 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
             }
         }
 
+        @Override
+        public void tlsUpgrade(final NamedEndpoint endpoint, final FutureCallback<ProtocolIOSession> callback) {
+            final IOSession ioSession = getIOSession();
+            if (ioSession instanceof ProtocolIOSession) {
+                doTlsUpgrade((ProtocolIOSession) ioSession, endpoint, callback);
+            } else {
+                throw new IllegalStateException("TLS upgrade not supported");
+            }
+        }
     }
 
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsUpgradeCapable.java
similarity index 76%
copy from httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
copy to httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsUpgradeCapable.java
index 35e8e29..23ee3bd 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsUpgradeCapable.java
@@ -25,18 +25,21 @@
  *
  */
 
-package org.apache.hc.core5.reactor;
+package org.apache.hc.core5.http.nio.ssl;
 
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.net.NamedEndpoint;
-import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
+import org.apache.hc.core5.reactor.ProtocolIOSession;
 
 /**
- * TLS capable, protocol upgradable {@link IOSession}.
+ * Capability to upgrade to TLS.
  *
- * @since 5.0
+ * @since 5.2
  */
-public interface ProtocolIOSession extends IOSession, TransportSecurityLayer {
+@Internal
+public interface TlsUpgradeCapable {
 
-    NamedEndpoint getInitialEndpoint();
+    void tlsUpgrade(NamedEndpoint endpoint, final FutureCallback<ProtocolIOSession> callback);
 
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index e292a69..570b2c6 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -32,7 +32,10 @@ import java.net.SocketAddress;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
 import java.nio.channels.SelectionKey;
+import java.util.Locale;
 import java.util.Queue;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.concurrent.locks.Lock;
@@ -50,6 +53,7 @@ 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;
 import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.Timeout;
 
@@ -63,6 +67,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
     private final AtomicReference<SSLIOSession> tlsSessionRef;
     private final AtomicReference<IOSession> currentSessionRef;
     private final AtomicReference<FutureCallback<TransportSecurityLayer>> tlsHandshakeCallbackRef;
+    private final ConcurrentMap<String, ProtocolUpgradeHandler> protocolUpgradeHandlerMap;
     private final AtomicBoolean closed;
 
     InternalDataChannel(
@@ -80,6 +85,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
         this.currentSessionRef = new AtomicReference<>(
                 ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession);
         this.tlsHandshakeCallbackRef = new AtomicReference<>(null);
+        this.protocolUpgradeHandlerMap = new ConcurrentHashMap<>();
         this.closed = new AtomicBoolean(false);
     }
 
@@ -404,6 +410,24 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
     }
 
     @Override
+    public void switchProtocol(final String protocolId, final FutureCallback<ProtocolIOSession> callback) {
+        Args.notEmpty(protocolId, "Application protocol ID");
+        final ProtocolUpgradeHandler upgradeHandler = protocolUpgradeHandlerMap.get(protocolId.toLowerCase(Locale.ROOT));
+        if (upgradeHandler != null) {
+            upgradeHandler.upgrade(this, callback);
+        } else {
+            throw new IllegalStateException("Unsupported protocol: " + protocolId);
+        }
+    }
+
+    @Override
+    public void registerProtocol(final String protocolId, final ProtocolUpgradeHandler upgradeHandler) {
+        Args.notEmpty(protocolId, "Application protocol ID");
+        Args.notNull(upgradeHandler, "Protocol upgrade handler");
+        protocolUpgradeHandlerMap.put(protocolId.toLowerCase(Locale.ROOT), upgradeHandler);
+    }
+
+    @Override
     public String toString() {
         final IOSession currentSession = currentSessionRef.get();
         if (currentSession != null) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
index 35e8e29..cebfb06 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
@@ -27,6 +27,7 @@
 
 package org.apache.hc.core5.reactor;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 
@@ -37,6 +38,29 @@ import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
  */
 public interface ProtocolIOSession extends IOSession, TransportSecurityLayer {
 
+    /**
+     * Switches this I/O session to the application protocol with the given ID.
+     * @param protocolId the application protocol ID
+     * @param callback the result callback
+     * @throws UnsupportedOperationException if application protocol switch
+     * is not supported.
+     */
+    default void switchProtocol(String protocolId, FutureCallback<ProtocolIOSession> callback) throws UnsupportedOperationException {
+        throw new UnsupportedOperationException("Protocol switch not supported");
+    }
+
+    /**
+     * Registers protocol upgrade handler with the given application protocol ID.
+     *
+     * @since 5.2
+     * @param protocolId the application protocol ID
+     * @param upgradeHandler the upgrade handler.
+     *
+     * @since 5.2
+     */
+    default void registerProtocol(String protocolId, ProtocolUpgradeHandler upgradeHandler) {
+    }
+
     NamedEndpoint getInitialEndpoint();
 
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolUpgradeHandler.java
similarity index 72%
copy from httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
copy to httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolUpgradeHandler.java
index 35e8e29..fef4bb7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ProtocolUpgradeHandler.java
@@ -27,16 +27,21 @@
 
 package org.apache.hc.core5.reactor;
 
-import org.apache.hc.core5.net.NamedEndpoint;
-import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
+import org.apache.hc.core5.annotation.Internal;
+import org.apache.hc.core5.concurrent.FutureCallback;
 
 /**
- * TLS capable, protocol upgradable {@link IOSession}.
+ * Application protocol upgrade handler. This routine can be used to upgrade
+ * I/O sessions to a new application protocol.
  *
- * @since 5.0
+ * @since 5.2
  */
-public interface ProtocolIOSession extends IOSession, TransportSecurityLayer {
+@Internal
+public interface ProtocolUpgradeHandler {
 
-    NamedEndpoint getInitialEndpoint();
+    /**
+     * Upgrades application protocol of the given I/O session.
+     */
+    void upgrade(ProtocolIOSession ioSession, FutureCallback<ProtocolIOSession> callback);
 
 }


[httpcomponents-core] 04/06: Added default `ConnectionAcceptor#listen` method that takes an optional attachment as a parameter

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit ffa201f1451182d9532b35d5cc039a54fda78fc2
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Dec 6 11:04:29 2020 +0100

    Added default `ConnectionAcceptor#listen` method that takes an optional attachment as a parameter
---
 .../apache/hc/core5/reactor/ConnectionAcceptor.java    | 18 ++++++++++++++++++
 pom.xml                                                |  7 +++++++
 2 files changed, 25 insertions(+)

diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ConnectionAcceptor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ConnectionAcceptor.java
index e98eb61..07d601b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ConnectionAcceptor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ConnectionAcceptor.java
@@ -48,6 +48,24 @@ public interface ConnectionAcceptor {
      * dispatcher.
      *
      * @param address the socket address to listen on.
+     * @param attachment the attachment object.
+     * @param callback the result callback.
+     * @return listener endpoint.
+     *
+     * @since 5.2
+     */
+    default Future<ListenerEndpoint> listen(
+            SocketAddress address, Object attachment, FutureCallback<ListenerEndpoint> callback) {
+        return listen(address, callback);
+    }
+
+    /**
+     * Opens a new listener endpoint with the given socket address. Once
+     * the endpoint is fully initialized it starts accepting incoming
+     * connections and propagates I/O activity notifications to the I/O event
+     * dispatcher.
+     *
+     * @param address the socket address to listen on.
      * @param callback the result callback.
      * @return listener endpoint.
      */
diff --git a/pom.xml b/pom.xml
index 3c77ced..3c2c615 100644
--- a/pom.xml
+++ b/pom.xml
@@ -176,6 +176,13 @@
           <parameter>
             <breakBuildOnBinaryIncompatibleModifications>true</breakBuildOnBinaryIncompatibleModifications>
             <breakBuildOnSourceIncompatibleModifications>true</breakBuildOnSourceIncompatibleModifications>
+            <overrideCompatibilityChangeParameters>
+              <overrideCompatibilityChangeParameter>
+                <compatibilityChange>METHOD_NEW_DEFAULT</compatibilityChange>
+                <binaryCompatible>true</binaryCompatible>
+                <sourceCompatible>true</sourceCompatible>
+              </overrideCompatibilityChangeParameter>
+            </overrideCompatibilityChangeParameters>
             <excludes>
               <exclude>@org.apache.hc.core5.annotation.Internal</exclude>
             </excludes>


[httpcomponents-core] 03/06: Replaced Clirr with JApiCmp

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 319b4ef34452d1a270ba0e9f86f912e3f382146c
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sat Dec 5 16:27:33 2020 +0100

    Replaced Clirr with JApiCmp
---
 pom.xml | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 59 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index 6af4857..3c77ced 100644
--- a/pom.xml
+++ b/pom.xml
@@ -156,11 +156,39 @@
         </executions>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>clirr-maven-plugin</artifactId>
+        <groupId>com.github.siom79.japicmp</groupId>
+        <artifactId>japicmp-maven-plugin</artifactId>
+        <version>0.14.4</version>
         <configuration>
-          <comparisonVersion>${api.comparison.version}</comparisonVersion>
+          <oldVersion>
+            <dependency>
+              <groupId>${project.groupId}</groupId>
+              <artifactId>${project.artifactId}</artifactId>
+              <version>${api.comparison.version}</version>
+              <type>jar</type>
+            </dependency>
+          </oldVersion>
+          <newVersion>
+            <file>
+              <path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
+            </file>
+          </newVersion>
+          <parameter>
+            <breakBuildOnBinaryIncompatibleModifications>true</breakBuildOnBinaryIncompatibleModifications>
+            <breakBuildOnSourceIncompatibleModifications>true</breakBuildOnSourceIncompatibleModifications>
+            <excludes>
+              <exclude>@org.apache.hc.core5.annotation.Internal</exclude>
+            </excludes>
+          </parameter>
         </configuration>
+        <executions>
+          <execution>
+            <phase>verify</phase>
+            <goals>
+              <goal>cmp</goal>
+            </goals>
+          </execution>
+        </executions>
       </plugin>
       <plugin>
         <groupId>org.apache.rat</groupId>
@@ -231,11 +259,35 @@
         </reportSets>
       </plugin>
       <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>clirr-maven-plugin</artifactId>
-        <version>${hc.clirr.version}</version>
+        <groupId>com.github.siom79.japicmp</groupId>
+        <artifactId>japicmp-maven-plugin</artifactId>
+        <version>0.14.4</version>
+        <reportSets>
+          <reportSet>
+            <reports>
+              <report>cmp-report</report>
+            </reports>
+          </reportSet>
+        </reportSets>
         <configuration>
-          <comparisonVersion>${api.comparison.version}</comparisonVersion>
+          <oldVersion>
+            <dependency>
+              <groupId>${project.groupId}</groupId>
+              <artifactId>${project.artifactId}</artifactId>
+              <version>${api.comparison.version}</version>
+              <type>jar</type>
+            </dependency>
+          </oldVersion>
+          <newVersion>
+            <file>
+              <path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
+            </file>
+          </newVersion>
+          <parameter>
+            <excludes>
+              <exclude>@org.apache.hc.core5.annotation.Internal</exclude>
+            </excludes>
+          </parameter>
         </configuration>
       </plugin>
       <plugin>


[httpcomponents-core] 05/06: TLS upgrade and TLS strategy APIs redesign

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit b5b2f09ea22a7b7b6b1e9cb250f093f4fc31a7a4
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sun Dec 13 11:10:40 2020 +0100

    TLS upgrade and TLS strategy APIs redesign
---
 .../nio/ClientHttpProtocolNegotiatorFactory.java   | 14 ++-------
 .../nio/ServerHttpProtocolNegotiatorFactory.java   | 12 ++------
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |  3 +-
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  3 +-
 .../apache/hc/core5/http2/nio/pool/H2ConnPool.java | 15 +++++++---
 .../http2/ssl/ConscryptClientTlsStrategy.java      | 31 +++++++++++++++-----
 .../http2/ssl/ConscryptServerTlsStrategy.java      | 32 +++++++++++++++-----
 .../hc/core5/http2/ssl/H2ClientTlsStrategy.java    | 31 +++++++++++++++-----
 .../hc/core5/http2/ssl/H2ServerTlsStrategy.java    | 32 +++++++++++++++-----
 .../impl/nio/ClientHttp1IOEventHandlerFactory.java | 10 +------
 .../impl/nio/ServerHttp1IOEventHandlerFactory.java | 22 ++++++--------
 .../core5/http/nio/ssl/BasicClientTlsStrategy.java | 20 +++++++++++--
 .../core5/http/nio/ssl/BasicServerTlsStrategy.java | 20 +++++++++++--
 .../apache/hc/core5/http/nio/ssl/TlsStrategy.java  | 32 +++++++++++++++++++-
 .../hc/core5/reactor/InternalDataChannel.java      | 34 ++++++++++++++++++++--
 .../apache/hc/core5/reactor/ssl/SSLIOSession.java  | 16 +++++-----
 .../core5/reactor/ssl/TransportSecurityLayer.java  | 29 ++++++++++++++++++
 17 files changed, 258 insertions(+), 98 deletions(-)

diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
index e257ae9..82fe49b 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientHttpProtocolNegotiatorFactory.java
@@ -30,7 +30,6 @@ package org.apache.hc.core5.http2.impl.nio;
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.Internal;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.nio.ClientHttp1StreamDuplexerFactory;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
@@ -39,7 +38,6 @@ import org.apache.hc.core5.reactor.EndpointParameters;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
-import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -75,16 +73,8 @@ public class ClientHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
         HttpVersionPolicy endpointPolicy = versionPolicy;
         if (attachment instanceof EndpointParameters) {
             final EndpointParameters params = (EndpointParameters) attachment;
-            if (URIScheme.HTTPS.same(params.getScheme())) {
-                Asserts.notNull(tlsStrategy, "TLS strategy");
-                final HttpHost host = new HttpHost(params.getScheme(), params.getHostName(), params.getPort());
-                tlsStrategy.upgrade(
-                        ioSession,
-                        host,
-                        ioSession.getLocalAddress(),
-                        ioSession.getRemoteAddress(),
-                        params.getAttachment(),
-                        handshakeTimeout);
+            if (tlsStrategy != null && URIScheme.HTTPS.same(params.getScheme())) {
+                tlsStrategy.upgrade(ioSession, params, params.getAttachment(), handshakeTimeout, null);
             }
             if (params.getAttachment() instanceof HttpVersionPolicy) {
                 endpointPolicy = (HttpVersionPolicy) params.getAttachment();
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
index e3f432c..9143538 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ServerHttpProtocolNegotiatorFactory.java
@@ -38,7 +38,6 @@ import org.apache.hc.core5.reactor.EndpointParameters;
 import org.apache.hc.core5.reactor.IOEventHandlerFactory;
 import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
-import org.apache.hc.core5.util.Asserts;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -74,15 +73,8 @@ public class ServerHttpProtocolNegotiatorFactory implements IOEventHandlerFactor
         HttpVersionPolicy endpointPolicy = versionPolicy;
         if (attachment instanceof EndpointParameters) {
             final EndpointParameters params = (EndpointParameters) attachment;
-            if (URIScheme.HTTPS.same(params.getScheme())) {
-                Asserts.notNull(tlsStrategy, "TLS strategy");
-                tlsStrategy.upgrade(
-                        ioSession,
-                        null,
-                        ioSession.getLocalAddress(),
-                        ioSession.getRemoteAddress(),
-                        params.getAttachment(),
-                        handshakeTimeout);
+            if (tlsStrategy != null && URIScheme.HTTPS.same(params.getScheme())) {
+                tlsStrategy.upgrade(ioSession, params, params.getAttachment(), handshakeTimeout, null);
             }
             if (params.getAttachment() instanceof HttpVersionPolicy) {
                 endpointPolicy = (HttpVersionPolicy) params.getAttachment();
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index bce7df9..ab94662 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -321,7 +321,6 @@ public class H2RequesterBootstrap {
                 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
                 streamListener);
 
-        final HttpVersionPolicy actualVersionProtocol = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
         final TlsStrategy actualTlsStrategy = tlsStrategy != null ? tlsStrategy : new H2ClientTlsStrategy();
 
         final ClientHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ClientHttp1StreamDuplexerFactory(
@@ -338,7 +337,7 @@ public class H2RequesterBootstrap {
         final IOEventHandlerFactory ioEventHandlerFactory = new ClientHttpProtocolNegotiatorFactory(
                 http1StreamHandlerFactory,
                 http2StreamHandlerFactory,
-                actualVersionProtocol,
+                versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
                 actualTlsStrategy,
                 handshakeTimeout);
 
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index 5448c9b..884c3a6 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -401,7 +401,6 @@ public class H2ServerBootstrap {
                 charCodingConfig != null ? charCodingConfig : CharCodingConfig.DEFAULT,
                 h2StreamListener);
 
-        final HttpVersionPolicy actualVersionProtocol = versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE;
         final TlsStrategy actualTlsStrategy = tlsStrategy != null ? tlsStrategy : new H2ServerTlsStrategy();
 
         final ServerHttp1StreamDuplexerFactory http1StreamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
@@ -419,7 +418,7 @@ public class H2ServerBootstrap {
         final IOEventHandlerFactory ioEventHandlerFactory = new ServerHttpProtocolNegotiatorFactory(
                 http1StreamHandlerFactory,
                 http2StreamHandlerFactory,
-                actualVersionProtocol,
+                versionPolicy != null ? versionPolicy : HttpVersionPolicy.NEGOTIATE,
                 actualTlsStrategy,
                 handshakeTimeout);
 
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
index 37107ca..6eac4d0 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
@@ -117,13 +117,20 @@ public final class H2ConnPool extends AbstractIOSessionPool<HttpHost> {
                             tlsStrategy.upgrade(
                                     (TransportSecurityLayer) ioSession,
                                     namedEndpoint,
-                                    ioSession.getLocalAddress(),
-                                    ioSession.getRemoteAddress(),
                                     null,
-                                    connectTimeout);
+                                    connectTimeout,
+                                    new CallbackContribution<TransportSecurityLayer>(callback) {
+
+                                        @Override
+                                        public void completed(final TransportSecurityLayer transportSecurityLayer) {
+                                            callback.completed(ioSession);
+                                        }
+
+                                    });
                             ioSession.setSocketTimeout(connectTimeout);
+                        } else {
+                            callback.completed(ioSession);
                         }
-                        callback.completed(ioSession);
                     }
 
                 });
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
index 88cf871..e6ad019 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptClientTlsStrategy.java
@@ -31,9 +31,11 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+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;
@@ -83,6 +85,27 @@ public class ConscryptClientTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(
+                sslContext,
+                endpoint,
+                sslBufferMode,
+                ConscryptSupport.initialize(attachment, initializer),
+                ConscryptSupport.verify(verifier),
+                handshakeTimeout,
+                callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -92,13 +115,7 @@ public class ConscryptClientTlsStrategy implements TlsStrategy {
             final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
-            tlsSession.startTls(
-                    sslContext,
-                    host,
-                    sslBufferMode,
-                    ConscryptSupport.initialize(attachment, initializer),
-                    ConscryptSupport.verify(verifier),
-                    handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
index dba69b8..2b6e9e6 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptServerTlsStrategy.java
@@ -31,10 +31,12 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.nio.ssl.FixedPortStrategy;
 import org.apache.hc.core5.http.nio.ssl.SecurePortStrategy;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+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;
@@ -145,6 +147,27 @@ public class ConscryptServerTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(
+                sslContext,
+                endpoint,
+                sslBufferMode,
+                ConscryptSupport.initialize(attachment, initializer),
+                ConscryptSupport.verify(verifier),
+                handshakeTimeout,
+                callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -153,16 +176,9 @@ public class ConscryptServerTlsStrategy implements TlsStrategy {
             final Object attachment,
             final Timeout handshakeTimeout) {
         if (isApplicable(localAddress)) {
-            tlsSession.startTls(
-                    sslContext,
-                    host,
-                    sslBufferMode,
-                    ConscryptSupport.initialize(attachment, initializer),
-                    ConscryptSupport.verify(verifier),
-                    handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
     }
-
 }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
index a003d54..a3f0d88 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ClientTlsStrategy.java
@@ -31,9 +31,11 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+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;
@@ -88,6 +90,27 @@ public class H2ClientTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(
+                sslContext,
+                endpoint,
+                sslBufferMode,
+                H2TlsSupport.enforceRequirements(attachment, initializer),
+                verifier,
+                handshakeTimeout,
+                callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -97,13 +120,7 @@ public class H2ClientTlsStrategy implements TlsStrategy {
             final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
-            tlsSession.startTls(
-                    sslContext,
-                    host,
-                    sslBufferMode,
-                    H2TlsSupport.enforceRequirements(attachment, initializer),
-                    verifier,
-                    handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
index f4e7f6f..e850edd 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2ServerTlsStrategy.java
@@ -31,10 +31,12 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.nio.ssl.FixedPortStrategy;
 import org.apache.hc.core5.http.nio.ssl.SecurePortStrategy;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
+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;
@@ -150,6 +152,27 @@ public class H2ServerTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(
+                sslContext,
+                endpoint,
+                sslBufferMode,
+                H2TlsSupport.enforceRequirements(attachment, initializer),
+                verifier,
+                handshakeTimeout,
+                callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -158,16 +181,9 @@ public class H2ServerTlsStrategy implements TlsStrategy {
             final Object attachment,
             final Timeout handshakeTimeout) {
         if (isApplicable(localAddress)) {
-            tlsSession.startTls(
-                    sslContext,
-                    host,
-                    sslBufferMode,
-                    H2TlsSupport.enforceRequirements(attachment, initializer),
-                    verifier,
-                    handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
     }
-
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
index f33e0c8..0c2643b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1IOEventHandlerFactory.java
@@ -29,7 +29,6 @@ package org.apache.hc.core5.http.impl.nio;
 
 import org.apache.hc.core5.annotation.Contract;
 import org.apache.hc.core5.annotation.ThreadingBehavior;
-import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.nio.ssl.TlsStrategy;
 import org.apache.hc.core5.reactor.EndpointParameters;
@@ -65,14 +64,7 @@ public class ClientHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
         if (attachment instanceof EndpointParameters) {
             final EndpointParameters params = (EndpointParameters) attachment;
             if (tlsStrategy != null && URIScheme.HTTPS.same(params.getScheme())) {
-                final HttpHost host = new HttpHost(params.getScheme(), params.getHostName(), params.getPort());
-                tlsStrategy.upgrade(
-                        ioSession,
-                        host,
-                        ioSession.getLocalAddress(),
-                        ioSession.getRemoteAddress(),
-                        params.getAttachment(),
-                        handshakeTimeout);
+                tlsStrategy.upgrade(ioSession, params, params.getAttachment(), handshakeTimeout, null);
             }
         }
         return new ClientHttp1IOEventHandler(streamDuplexerFactory.create(ioSession));
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
index ef3a32f..1ec0016 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ServerHttp1IOEventHandlerFactory.java
@@ -68,22 +68,18 @@ public class ServerHttp1IOEventHandlerFactory implements IOEventHandlerFactory {
             if (tlsStrategy != null && URIScheme.HTTPS.same(endpointScheme)) {
                 tlsStrategy.upgrade(
                         ioSession,
-                        null,
-                        ioSession.getLocalAddress(),
-                        ioSession.getRemoteAddress(),
+                        params,
                         params.getAttachment(),
-                        handshakeTimeout);
+                        handshakeTimeout,
+                        null);
             }
         } else {
-            if (tlsStrategy != null) {
-                tlsStrategy.upgrade(
-                        ioSession,
-                        null,
-                        ioSession.getLocalAddress(),
-                        ioSession.getRemoteAddress(),
-                        attachment,
-                        handshakeTimeout);
-            }
+            tlsStrategy.upgrade(
+                    ioSession,
+                    null,
+                    attachment,
+                    handshakeTimeout,
+                    null);
         }
         return new ServerHttp1IOEventHandler(streamDuplexerFactory.create(endpointScheme, ioSession));
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
index 2ccc9c2..3386708 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicClientTlsStrategy.java
@@ -31,8 +31,10 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.URIScheme;
+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;
@@ -87,6 +89,21 @@ public class BasicClientTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(sslContext, endpoint, sslBufferMode,
+                TlsSupport.enforceStrongSecurity(initializer), verifier, handshakeTimeout, callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -96,8 +113,7 @@ public class BasicClientTlsStrategy implements TlsStrategy {
             final Timeout handshakeTimeout) {
         final String scheme = host != null ? host.getSchemeName() : null;
         if (URIScheme.HTTPS.same(scheme)) {
-            tlsSession.startTls(sslContext, host, sslBufferMode,
-                    TlsSupport.enforceStrongSecurity(initializer), verifier, handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
index 06cd6b4..63c0025 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/BasicServerTlsStrategy.java
@@ -31,7 +31,9 @@ import java.net.SocketAddress;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
+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;
@@ -149,6 +151,21 @@ public class BasicServerTlsStrategy implements TlsStrategy {
     }
 
     @Override
+    public void upgrade(
+            final TransportSecurityLayer tlsSession,
+            final NamedEndpoint endpoint,
+            final Object attachment,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
+        tlsSession.startTls(sslContext, endpoint, sslBufferMode,
+                TlsSupport.enforceStrongSecurity(initializer), verifier, handshakeTimeout, callback);
+    }
+
+    /**
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
+     */
+    @Deprecated
+    @Override
     public boolean upgrade(
             final TransportSecurityLayer tlsSession,
             final HttpHost host,
@@ -157,8 +174,7 @@ public class BasicServerTlsStrategy implements TlsStrategy {
             final Object attachment,
             final Timeout handshakeTimeout) {
         if (isApplicable(localAddress)) {
-            tlsSession.startTls(sslContext, host, sslBufferMode,
-                    TlsSupport.enforceStrongSecurity(initializer), verifier, handshakeTimeout);
+            upgrade(tlsSession, host, attachment, handshakeTimeout, null);
             return true;
         }
         return false;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
index 5ebee69..a5f09c4 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsStrategy.java
@@ -29,7 +29,10 @@ package org.apache.hc.core5.http.nio.ssl;
 
 import java.net.SocketAddress;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.URIScheme;
+import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.TransportSecurityLayer;
 import org.apache.hc.core5.util.Timeout;
 
@@ -41,7 +44,7 @@ import org.apache.hc.core5.util.Timeout;
 public interface TlsStrategy {
 
     /**
-     * Secures current session layer with TLS security.
+     * Secures current session layer with TLS.
      *
      * @param sessionLayer the session layer
      * @param host the name of the opposite endpoint when given or {@code null} otherwise.
@@ -50,7 +53,10 @@ public interface TlsStrategy {
      * @param attachment arbitrary object passes to the TLS session initialization code.
      * @param handshakeTimeout the timeout to use while performing the TLS handshake; may be {@code null}.
      * @return {@code true} if the session has been upgraded, {@code false} otherwise.
+     *
+     * @deprecated use {@link #upgrade(TransportSecurityLayer, NamedEndpoint, Object, Timeout, FutureCallback)}
      */
+    @Deprecated
     boolean upgrade(
             TransportSecurityLayer sessionLayer,
             HttpHost host,
@@ -59,4 +65,28 @@ public interface TlsStrategy {
             Object attachment,
             Timeout handshakeTimeout);
 
+    /**
+     * Secures current session layer with TLS.
+     *
+     * @param sessionLayer the session layer
+     * @param endpoint the name of the opposite endpoint when applicable or {@code null} otherwise.
+     * @param attachment arbitrary object passes to the TLS session initialization code.
+     * @param handshakeTimeout the timeout to use while performing the TLS handshake; may be {@code null}.
+     * @param callback Operation result callback.
+     *
+     * @since 5.2
+     */
+    default void upgrade(
+            TransportSecurityLayer sessionLayer,
+            NamedEndpoint endpoint,
+            Object attachment,
+            Timeout handshakeTimeout,
+            FutureCallback<TransportSecurityLayer> callback) {
+        upgrade(sessionLayer, new HttpHost(URIScheme.HTTPS.id, endpoint.getHostName(), endpoint.getPort()),
+                null, null, attachment, handshakeTimeout);
+        if (callback != null) {
+            callback.completed(sessionLayer);
+        }
+    }
+
 }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index 33ed80d..e292a69 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -39,6 +39,7 @@ import java.util.concurrent.locks.Lock;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.net.NamedEndpoint;
@@ -48,6 +49,7 @@ import org.apache.hc.core5.reactor.ssl.SSLMode;
 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.Asserts;
 import org.apache.hc.core5.util.Timeout;
 
@@ -60,6 +62,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
     private final Queue<InternalDataChannel> closedSessions;
     private final AtomicReference<SSLIOSession> tlsSessionRef;
     private final AtomicReference<IOSession> currentSessionRef;
+    private final AtomicReference<FutureCallback<TransportSecurityLayer>> tlsHandshakeCallbackRef;
     private final AtomicBoolean closed;
 
     InternalDataChannel(
@@ -76,6 +79,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
         this.tlsSessionRef = new AtomicReference<>(null);
         this.currentSessionRef = new AtomicReference<>(
                 ioSessionDecorator != null ? ioSessionDecorator.decorate(ioSession) : ioSession);
+        this.tlsHandshakeCallbackRef = new AtomicReference<>(null);
         this.closed = new AtomicBoolean(false);
     }
 
@@ -167,6 +171,10 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
         if (handler != null) {
             handler.exception(currentSession, cause);
         }
+        final FutureCallback<?> callback = tlsHandshakeCallbackRef.getAndSet(null);
+        if (callback != null) {
+            callback.failed(cause);
+        }
     }
 
     void onTLSSessionStart(final SSLIOSession sslSession) {
@@ -174,6 +182,10 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
         if (sessionListener != null) {
             sessionListener.connected(currentSession);
         }
+        final FutureCallback<TransportSecurityLayer> callback = tlsHandshakeCallbackRef.getAndSet(null);
+        if (callback != null) {
+            callback.completed(this);
+        }
     }
 
     void onTLSSessionEnd(final SSLIOSession sslSession) {
@@ -201,6 +213,18 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
             final SSLSessionInitializer initializer,
             final SSLSessionVerifier verifier,
             final Timeout handshakeTimeout) {
+        startTls(sslContext, endpoint, sslBufferMode, initializer, verifier, handshakeTimeout, null);
+    }
+
+    @Override
+    public void startTls(
+            final SSLContext sslContext,
+            final NamedEndpoint endpoint,
+            final SSLBufferMode sslBufferMode,
+            final SSLSessionInitializer initializer,
+            final SSLSessionVerifier verifier,
+            final Timeout handshakeTimeout,
+            final FutureCallback<TransportSecurityLayer> callback) {
         final SSLIOSession sslioSession = new SSLIOSession(
                 endpoint != null ? endpoint : initialEndpoint,
                 ioSession,
@@ -214,11 +238,17 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
                 handshakeTimeout);
         if (tlsSessionRef.compareAndSet(null, sslioSession)) {
             currentSessionRef.set(ioSessionDecorator != null ? ioSessionDecorator.decorate(sslioSession) : sslioSession);
+            tlsHandshakeCallbackRef.set(callback);
+        } else {
+            throw new IllegalStateException("TLS already activated");
+        }
+        try {
             if (sessionListener != null) {
                 sessionListener.startTls(sslioSession);
             }
-        } else {
-            throw new IllegalStateException("TLS already activated");
+            sslioSession.beginHandshake(this);
+        } catch (final Exception ex) {
+            onException(ex);
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
index 90d67a6..4b90d93 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/SSLIOSession.java
@@ -157,16 +157,11 @@ public class SSLIOSession implements IOSession {
 
             @Override
             public void connected(final IOSession protocolSession) throws IOException {
-                if (handshakeStateRef.compareAndSet(TLSHandShakeState.READY, TLSHandShakeState.INITIALIZED)) {
-                    initialize(protocolSession);
-                }
+                beginHandshake(protocolSession);
             }
 
             @Override
             public void inputReady(final IOSession protocolSession, final ByteBuffer src) throws IOException {
-                if (handshakeStateRef.compareAndSet(TLSHandShakeState.READY, TLSHandShakeState.INITIALIZED)) {
-                    initialize(protocolSession);
-                }
                 receiveEncryptedData();
                 doHandshake(protocolSession);
                 decryptData(protocolSession);
@@ -175,9 +170,6 @@ public class SSLIOSession implements IOSession {
 
             @Override
             public void outputReady(final IOSession protocolSession) throws IOException {
-                if (handshakeStateRef.compareAndSet(TLSHandShakeState.READY, TLSHandShakeState.INITIALIZED)) {
-                    initialize(protocolSession);
-                }
                 encryptData(protocolSession);
                 sendEncryptedData();
                 doHandshake(protocolSession);
@@ -228,6 +220,12 @@ public class SSLIOSession implements IOSession {
         return internalEventHandler;
     }
 
+    public void beginHandshake(final IOSession protocolSession) throws IOException {
+        if (handshakeStateRef.compareAndSet(TLSHandShakeState.READY, TLSHandShakeState.INITIALIZED)) {
+            initialize(protocolSession);
+        }
+    }
+
     private void initialize(final IOSession protocolSession) throws IOException {
         // Save the initial socketTimeout of the underlying IOSession, to be restored after the handshake is finished
         this.socketTimeout = this.session.getSocketTimeout();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
index 42de768..4c48aea 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/ssl/TransportSecurityLayer.java
@@ -29,6 +29,7 @@ package org.apache.hc.core5.reactor.ssl;
 
 import javax.net.ssl.SSLContext;
 
+import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.util.Timeout;
 
@@ -60,6 +61,34 @@ public interface TransportSecurityLayer {
             Timeout handshakeTimeout) throws UnsupportedOperationException;
 
     /**
+     * Starts TLS session over an existing network connection with the given SSL context.
+     * {@link NamedEndpoint} details are applicable for client side connections and
+     * are used for host name verification, when supported by the SSL engine.
+     *
+     * @param sslContext SSL context to be used for this session.
+     * @param endpoint optional endpoint details for outgoing client side connections.
+     * @param sslBufferMode SSL buffer management mode.
+     * @param initializer SSL session initialization callback.
+     * @param verifier SSL session verification callback.
+     * @param handshakeTimeout the timeout to use while performing the TLS handshake; may be {@code null}.
+     *
+     * @since 5.2
+     */
+    default void startTls(
+            SSLContext sslContext,
+            NamedEndpoint endpoint,
+            SSLBufferMode sslBufferMode,
+            SSLSessionInitializer initializer,
+            SSLSessionVerifier verifier,
+            Timeout handshakeTimeout,
+            FutureCallback<TransportSecurityLayer> callback) throws UnsupportedOperationException {
+        startTls(sslContext, endpoint, sslBufferMode, initializer, verifier, handshakeTimeout);
+        if (callback != null) {
+            callback.completed(null);
+        }
+    }
+
+    /**
      * Returns details of a fully established TLS session.
      *
      * @return TLS session details.


[httpcomponents-core] 02/06: Upgrade to Java 1.8

Posted by ol...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit da924c84fa421a822a04a52d8672e8287f926b29
Author: Oleg Kalnichevski <ol...@apache.org>
AuthorDate: Sat Dec 5 11:21:43 2020 +0100

    Upgrade to Java 1.8
---
 .travis.yml                                        |   4 -
 README.md                                          |   2 +-
 .../hc/core5/http2/hpack/OutboundDynamicTable.java |   6 +-
 .../http2/impl/DefaultH2RequestConverter.java      |  43 +-
 .../impl/nio/AbstractH2StreamMultiplexer.java      |  13 +-
 .../http2/impl/nio/ClientH2StreamHandler.java      |  12 +-
 .../nio/bootstrap/H2MultiplexingRequester.java     | 168 +++--
 .../H2MultiplexingRequesterBootstrap.java          |  12 +-
 .../impl/nio/bootstrap/H2RequesterBootstrap.java   |   4 +-
 .../impl/nio/bootstrap/H2ServerBootstrap.java      |  38 +-
 .../apache/hc/core5/http2/nio/pool/H2ConnPool.java |  11 +-
 .../hc/core5/http2/ssl/ConscryptSupport.java       |  53 +-
 .../apache/hc/core5/http2/ssl/H2TlsSupport.java    |  25 +-
 .../H2ConscriptRequestExecutionExample.java        |  13 +-
 .../core5/http2/examples/H2FileServerExample.java  |  15 +-
 .../http2/examples/H2FullDuplexClientExample.java  |  11 +-
 .../http2/examples/H2FullDuplexServerExample.java  | 187 +++--
 .../hc/core5/http2/examples/H2GreetingServer.java  |  26 +-
 .../examples/H2MultiStreamExecutionExample.java    |  11 +-
 .../http2/examples/H2RequestExecutionExample.java  |  11 +-
 .../examples/H2TlsAlpnRequestExecutionExample.java |  38 +-
 .../http2/impl/TestDefaultH2RequestConverter.java  |   2 +-
 .../http2/impl/TestDefaultH2ResponseConverter.java |   2 +-
 .../core5/reactive/ReactiveResponseConsumer.java   |   4 +-
 .../reactive/ReactiveServerExchangeHandler.java    |  15 +-
 .../core5/reactive/TestReactiveDataConsumer.java   |  27 +-
 .../examples/ReactiveFullDuplexClientExample.java  |  41 +-
 .../examples/ReactiveFullDuplexServerExample.java  |  61 +-
 .../apache/hc/core5/benchmark/HttpBenchmark.java   | 251 +++----
 .../org/apache/hc/core5/testing/SocksProxy.java    |  56 +-
 .../core5/testing/framework/TestingFramework.java  |   3 +-
 .../apache/hc/core5/testing/nio/H2TestServer.java  |  27 +-
 .../hc/core5/testing/nio/Http1TestServer.java      |  18 +-
 .../core5/testing/reactive/ReactiveTestUtils.java  |  12 +-
 .../hc/core5/benchmark/BenchmarkToolTest.java      |   4 +-
 .../testing/classic/ClassicIntegrationTest.java    | 328 +++------
 .../classic/ClassicServerAndRequesterTest.java     |  41 +-
 .../classic/ClassicServerBootstrapFilterTest.java  |  16 +-
 .../testing/classic/ClassicTLSIntegrationTest.java |  40 +-
 ...gResponseOutOfOrderStrategyIntegrationTest.java |  28 +-
 .../compatibility/http2/H2CompatibilityTest.java   |  59 +-
 .../nio/AsyncServerBootstrapFilterTest.java        |  33 +-
 .../apache/hc/core5/testing/nio/H2AlpnTest.java    |  11 +-
 .../hc/core5/testing/nio/H2IntegrationTest.java    | 366 +++-------
 .../testing/nio/H2ProtocolNegotiationTest.java     |  11 +-
 .../nio/H2ServerAndMultiplexingRequesterTest.java  |  11 +-
 .../testing/nio/H2ServerAndRequesterTest.java      |  13 +-
 .../testing/nio/H2ServerBootstrapFiltersTest.java  |  33 +-
 .../hc/core5/testing/nio/H2TLSIntegrationTest.java |  99 +--
 .../core5/testing/nio/Http1AuthenticationTest.java |  11 +-
 .../hc/core5/testing/nio/Http1IntegrationTest.java | 794 +++++++--------------
 .../testing/nio/Http1ServerAndRequesterTest.java   |  66 +-
 .../testing/nio/JSSEProviderIntegrationTest.java   |  55 +-
 .../core5/testing/reactive/ReactiveClientTest.java |  41 +-
 .../apache/hc/core5/concurrent/ComplexFuture.java  |   9 +-
 .../impl/bootstrap/AsyncRequesterBootstrap.java    |   4 +-
 .../http/impl/bootstrap/AsyncServerBootstrap.java  |  38 +-
 .../http/impl/bootstrap/HttpAsyncRequester.java    | 170 +++--
 .../core5/http/impl/bootstrap/HttpRequester.java   |   9 +-
 .../hc/core5/http/impl/bootstrap/HttpServer.java   |   4 +-
 .../http/impl/bootstrap/RequesterBootstrap.java    |   4 +-
 .../core5/http/impl/bootstrap/ServerBootstrap.java |  12 +-
 .../http/impl/nio/ClientHttp1StreamHandler.java    |  12 +-
 .../hc/core5/http/io/entity/HttpEntities.java      |   9 +-
 .../io/support/HttpServerFilterChainElement.java   |  11 +-
 .../hc/core5/http/nio/command/ShutdownCommand.java |   9 +-
 ...Consumer.java => DiscardingEntityConsumer.java} |  10 +-
 .../core5/http/nio/entity/NoopEntityConsumer.java  |   3 +
 .../apache/hc/core5/http/nio/ssl/TlsSupport.java   |  21 +-
 .../support/AbstractAsyncRequesterConsumer.java    |   9 +-
 .../nio/support/AbstractAsyncResponseConsumer.java |   9 +-
 .../nio/support/AsyncServerFilterChainElement.java |  13 +-
 .../http/nio/support/BasicRequestConsumer.java     |   9 +-
 .../http/nio/support/BasicResponseConsumer.java    |   9 +-
 .../classic/AbstractClassicEntityConsumer.java     |  25 +-
 .../classic/AbstractClassicEntityProducer.java     |  21 +-
 .../AbstractClassicServerExchangeHandler.java      |  29 +-
 .../http/protocol/RequestHandlerRegistry.java      |  18 +-
 .../java/org/apache/hc/core5/net/URIBuilder.java   |   8 +-
 .../java/org/apache/hc/core5/pool/LaxConnPool.java |  22 +-
 .../org/apache/hc/core5/pool/StrictConnPool.java   |  22 +-
 .../hc/core5/reactor/AbstractIOSessionPool.java    |  31 +-
 .../core5/reactor/DefaultListeningIOReactor.java   |   9 +-
 .../hc/core5/reactor/InternalDataChannel.java      |  21 +-
 .../hc/core5/reactor/SingleCoreIOReactor.java      |  38 +-
 .../org/apache/hc/core5/util/ReflectionUtils.java  |   9 +-
 .../hc/core5/concurrent/TestBasicFuture.java       |  68 +-
 .../http/examples/AsyncFileServerExample.java      |  17 +-
 .../examples/AsyncFullDuplexClientExample.java     |  23 +-
 .../examples/AsyncFullDuplexServerExample.java     | 187 +++--
 .../AsyncPipelinedRequestExecutionExample.java     |  11 +-
 .../examples/AsyncRequestExecutionExample.java     |  11 +-
 .../http/examples/AsyncReverseProxyExample.java    |  25 +-
 .../http/examples/AsyncServerFilterExample.java    |  75 +-
 .../http/examples/ClassicFileServerExample.java    |   9 +-
 .../http/examples/ClassicPostExecutionExample.java |  14 +-
 .../http/examples/ClassicReverseProxyExample.java  |  11 +-
 .../http/examples/ClassicServerFilterExample.java  |  75 +-
 .../hc/core5/http/impl/io/TestChunkCoding.java     |  13 +-
 .../hc/core5/http/impl/io/TestHttpService.java     |  36 +-
 .../http/io/entity/TestSerializableEntity.java     |   4 +-
 .../nio/support/classic/TestSharedInputBuffer.java | 110 +--
 .../support/classic/TestSharedOutputBuffer.java    |  83 +--
 .../http/protocol/TestRequestHandlerRegistry.java  |  10 +-
 .../org/apache/hc/core5/net/TestURIBuilder.java    |   2 +-
 .../org/apache/hc/core5/pool/TestLaxConnPool.java  |   4 +-
 .../org/apache/hc/core5/pool/TestPoolEntry.java    |   9 +-
 .../apache/hc/core5/pool/TestStrictConnPool.java   |  29 +-
 .../core5/reactor/TestAbstractIOSessionPool.java   |  60 +-
 .../apache/hc/core5/ssl/TestSSLContextBuilder.java | 167 ++---
 .../java/org/apache/hc/core5/util/TestArgs.java    |   2 +-
 .../java/org/apache/hc/core5/util/TestAsserts.java |   4 +-
 pom.xml                                            |   4 +-
 113 files changed, 1652 insertions(+), 3320 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index 0ff322d..c6cff08 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,10 +36,6 @@ script: mvn verify -B -P docker
 
 jobs:
   include:
-    - name: amd64-jdk7
-      arch: amd64
-      jdk: openjdk7
-      script: mvn verify -B
     - name: arm64
       arch: arm64
       script: mvn verify -B
diff --git a/README.md b/README.md
index ff3516b..2736f26 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ For building from source instructions please refer to [BUILDING.txt](./BUILDING.
 Dependencies
 ------------
 
-HttpCore requires Java 1.7 compatible runtime.
+HttpCore requires Java 1.8 compatible runtime.
 
 Licensing
 ---------
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/OutboundDynamicTable.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/OutboundDynamicTable.java
index a1c2e6a..825ae84 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/OutboundDynamicTable.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/hpack/OutboundDynamicTable.java
@@ -103,11 +103,7 @@ final class OutboundDynamicTable {
         }
         final String key = header.getName();
         final FifoLinkedList.InternalNode node = headers.addFirst(header);
-        LinkedList<HPackEntry> nodes = mapByName.get(key);
-        if (nodes == null) {
-            nodes = new LinkedList<>();
-            mapByName.put(key, nodes);
-        }
+        final LinkedList<HPackEntry> nodes = mapByName.computeIfAbsent(key, k -> new LinkedList<>());
         nodes.addFirst(node);
         currentSize += entrySize;
         evict();
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
index 553aba6..7771ee5 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/DefaultH2RequestConverter.java
@@ -81,25 +81,30 @@ public final class DefaultH2RequestConverter implements H2MessageConverter<HttpR
                     throw new ProtocolException("Invalid sequence of headers (pseudo-headers must precede message headers)");
                 }
 
-                if (name.equals(H2PseudoRequestHeaders.METHOD)) {
-                    if (method != null) {
-                        throw new ProtocolException("Multiple '%s' request headers are illegal", name);
-                    }
-                    method = value;
-                } else if (name.equals(H2PseudoRequestHeaders.SCHEME)) {
-                    if (scheme != null) {
-                        throw new ProtocolException("Multiple '%s' request headers are illegal", name);
-                    }
-                    scheme = value;
-                } else if (name.equals(H2PseudoRequestHeaders.PATH)) {
-                    if (path != null) {
-                        throw new ProtocolException("Multiple '%s' request headers are illegal", name);
-                    }
-                    path = value;
-                } else if (name.equals(H2PseudoRequestHeaders.AUTHORITY)) {
-                    authority = value;
-                } else {
-                    throw new ProtocolException("Unsupported request header '%s'", name);
+                switch (name) {
+                    case H2PseudoRequestHeaders.METHOD:
+                        if (method != null) {
+                            throw new ProtocolException("Multiple '%s' request headers are illegal", name);
+                        }
+                        method = value;
+                        break;
+                    case H2PseudoRequestHeaders.SCHEME:
+                        if (scheme != null) {
+                            throw new ProtocolException("Multiple '%s' request headers are illegal", name);
+                        }
+                        scheme = value;
+                        break;
+                    case H2PseudoRequestHeaders.PATH:
+                        if (path != null) {
+                            throw new ProtocolException("Multiple '%s' request headers are illegal", name);
+                        }
+                        path = value;
+                        break;
+                    case H2PseudoRequestHeaders.AUTHORITY:
+                        authority = value;
+                        break;
+                    default:
+                        throw new ProtocolException("Unsupported request header '%s'", name);
                 }
             } else {
                 if (name.equalsIgnoreCase(HttpHeaders.CONNECTION)) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
index 67d5db2..aa79ad1 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/AbstractH2StreamMultiplexer.java
@@ -26,7 +26,6 @@
  */
 package org.apache.hc.core5.http2.impl.nio;
 
-import javax.net.ssl.SSLSession;
 import java.io.IOException;
 import java.net.SocketAddress;
 import java.nio.ByteBuffer;
@@ -43,7 +42,8 @@ import java.util.concurrent.ConcurrentLinkedDeque;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.apache.hc.core5.concurrent.Cancellable;
+import javax.net.ssl.SSLSession;
+
 import org.apache.hc.core5.concurrent.CancellableDependency;
 import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.EndpointDetails;
@@ -628,14 +628,7 @@ abstract class AbstractH2StreamMultiplexer implements Identifiable, HttpConnecti
                 }
                 final CancellableDependency cancellableDependency = executableCommand.getCancellableDependency();
                 if (cancellableDependency != null) {
-                    cancellableDependency.setDependency(new Cancellable() {
-
-                        @Override
-                        public boolean cancel() {
-                            return stream.abort();
-                        }
-
-                    });
+                    cancellableDependency.setDependency(stream::abort);
                 }
                 if (!outputQueue.isEmpty()) {
                     return;
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
index a1dc57f..732e60c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/ClientH2StreamHandler.java
@@ -49,8 +49,6 @@ import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncPushConsumer;
 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.protocol.HttpCoreContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http2.H2ConnectionException;
@@ -168,15 +166,7 @@ class ClientH2StreamHandler implements H2StreamHandler {
     public void produceOutput() throws HttpException, IOException {
         switch (requestState) {
             case HEADERS:
-                exchangeHandler.produceRequest(new RequestChannel() {
-
-                    @Override
-                    public void sendRequest(
-                            final HttpRequest request, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
-                        commitRequest(request, entityDetails);
-                    }
-
-                }, context);
+                exchangeHandler.produceRequest((request, entityDetails, httpContext) -> commitRequest(request, entityDetails), context);
                 break;
             case BODY:
                 exchangeHandler.produce(dataChannel);
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
index 552b4d3..082ce9e 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequester.java
@@ -48,7 +48,6 @@ 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.ProtocolException;
 import org.apache.hc.core5.http.impl.DefaultAddressResolver;
@@ -150,99 +149,92 @@ public class H2MultiplexingRequester extends AsyncRequester{
         Args.notNull(timeout, "Timeout");
         Args.notNull(context, "Context");
         try {
-            exchangeHandler.produceRequest(new RequestChannel() {
-
-                @Override
-                public void sendRequest(
-                        final HttpRequest request,
-                        final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
-                    final String scheme = request.getScheme();
-                    final URIAuthority authority = request.getAuthority();
-                    if (authority == null) {
-                        throw new ProtocolException("Request authority not specified");
-                    }
-                    final HttpHost target = new HttpHost(scheme, authority);
-                    connPool.getSession(target, timeout, new FutureCallback<IOSession>() {
-
-                        @Override
-                        public void completed(final IOSession ioSession) {
-                            ioSession.enqueue(new RequestExecutionCommand(new AsyncClientExchangeHandler() {
-
-                                @Override
-                                public void releaseResources() {
-                                    exchangeHandler.releaseResources();
-                                }
-
-                                @Override
-                                public void produceRequest(final RequestChannel channel, final HttpContext httpContext) throws HttpException, IOException {
-                                    channel.sendRequest(request, entityDetails, httpContext);
-                                }
-
-                                @Override
-                                public int available() {
-                                    return exchangeHandler.available();
-                                }
-
-                                @Override
-                                public void produce(final DataStreamChannel channel) throws IOException {
-                                    exchangeHandler.produce(channel);
-                                }
-
-                                @Override
-                                public void consumeInformation(final HttpResponse response, final HttpContext httpContext) throws HttpException, IOException {
-                                    exchangeHandler.consumeInformation(response, httpContext);
-                                }
-
-                                @Override
-                                public void consumeResponse(
-                                        final HttpResponse response, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
-                                    exchangeHandler.consumeResponse(response, entityDetails, httpContext);
-                                }
-
-                                @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 streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                                    exchangeHandler.streamEnd(trailers);
-                                }
-
-                                @Override
-                                public void cancel() {
-                                    exchangeHandler.cancel();
-                                }
-
-                                @Override
-                                public void failed(final Exception cause) {
-                                    exchangeHandler.failed(cause);
-                                }
-
-                            }, pushHandlerFactory, cancellableDependency, context), Command.Priority.NORMAL);
-                            if (!ioSession.isOpen()) {
-                                exchangeHandler.failed(new ConnectionClosedException());
+            exchangeHandler.produceRequest((request, entityDetails, httpContext) -> {
+                final String scheme = request.getScheme();
+                final URIAuthority authority = request.getAuthority();
+                if (authority == null) {
+                    throw new ProtocolException("Request authority not specified");
+                }
+                final HttpHost target = new HttpHost(scheme, authority);
+                connPool.getSession(target, timeout, new FutureCallback<IOSession>() {
+
+                    @Override
+                    public void completed(final IOSession ioSession) {
+                        ioSession.enqueue(new RequestExecutionCommand(new AsyncClientExchangeHandler() {
+
+                            @Override
+                            public void releaseResources() {
+                                exchangeHandler.releaseResources();
                             }
-                        }
 
-                        @Override
-                        public void failed(final Exception ex) {
-                            exchangeHandler.failed(ex);
-                        }
+                            @Override
+                            public void produceRequest(final RequestChannel channel, final HttpContext httpContext) throws HttpException, IOException {
+                                channel.sendRequest(request, entityDetails, httpContext);
+                            }
+
+                            @Override
+                            public int available() {
+                                return exchangeHandler.available();
+                            }
+
+                            @Override
+                            public void produce(final DataStreamChannel channel) throws IOException {
+                                exchangeHandler.produce(channel);
+                            }
+
+                            @Override
+                            public void consumeInformation(final HttpResponse response, final HttpContext httpContext) throws HttpException, IOException {
+                                exchangeHandler.consumeInformation(response, httpContext);
+                            }
+
+                            @Override
+                            public void consumeResponse(
+                                    final HttpResponse response, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
+                                exchangeHandler.consumeResponse(response, entityDetails, httpContext);
+                            }
+
+                            @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 streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                                exchangeHandler.streamEnd(trailers);
+                            }
+
+                            @Override
+                            public void cancel() {
+                                exchangeHandler.cancel();
+                            }
+
+                            @Override
+                            public void failed(final Exception cause) {
+                                exchangeHandler.failed(cause);
+                            }
 
-                        @Override
-                        public void cancelled() {
-                            exchangeHandler.cancel();
+                        }, pushHandlerFactory, cancellableDependency, context), Command.Priority.NORMAL);
+                        if (!ioSession.isOpen()) {
+                            exchangeHandler.failed(new ConnectionClosedException());
                         }
+                    }
 
-                    });
+                    @Override
+                    public void failed(final Exception ex) {
+                        exchangeHandler.failed(ex);
+                    }
 
-                }
+                    @Override
+                    public void cancelled() {
+                        exchangeHandler.cancel();
+                    }
+
+                });
 
             }, context);
         } catch (final IOException | HttpException ex) {
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
index e59802a..4351b5c 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2MultiplexingRequesterBootstrap.java
@@ -46,12 +46,9 @@ import org.apache.hc.core5.http2.impl.nio.H2OnlyClientProtocolNegotiator;
 import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
 import org.apache.hc.core5.http2.nio.support.DefaultAsyncPushConsumerFactory;
 import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
-import org.apache.hc.core5.reactor.IOEventHandler;
-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.reactor.IOSessionListener;
-import org.apache.hc.core5.reactor.ProtocolIOSession;
 import org.apache.hc.core5.util.Args;
 
 /**
@@ -210,14 +207,7 @@ public class H2MultiplexingRequesterBootstrap {
                 streamListener);
         return new H2MultiplexingRequester(
                 ioReactorConfig,
-                new IOEventHandlerFactory() {
-
-                    @Override
-                    public IOEventHandler createHandler(final ProtocolIOSession ioSession, final Object attachment) {
-                        return new H2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, strictALPNHandshake);
-                    }
-
-                },
+                (ioSession, attachment) -> new H2OnlyClientProtocolNegotiator(ioSession, http2StreamHandlerFactory, strictALPNHandshake),
                 ioSessionDecorator,
                 exceptionCallback,
                 sessionListener,
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
index 44adb0d..bce7df9 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2RequesterBootstrap.java
@@ -295,7 +295,7 @@ public class H2RequesterBootstrap {
                         defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<IOSession>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
             case STRICT:
@@ -305,7 +305,7 @@ public class H2RequesterBootstrap {
                         maxTotal > 0 ? maxTotal : 50,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<IOSession>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
         }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
index a983611..5448c9b 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/impl/nio/bootstrap/H2ServerBootstrap.java
@@ -268,14 +268,7 @@ public class H2ServerBootstrap {
     public final <T> H2ServerBootstrap register(
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
         return this;
     }
 
@@ -291,14 +284,7 @@ public class H2ServerBootstrap {
             final String hostname,
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        registerVirtual(hostname, uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        registerVirtual(hostname, uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
         return this;
     }
 
@@ -358,15 +344,8 @@ public class H2ServerBootstrap {
         final String actualCanonicalHostName = canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName();
         final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry = new RequestHandlerRegistry<>(
                 actualCanonicalHostName,
-                new Supplier<LookupRegistry<Supplier<AsyncServerExchangeHandler>>>() {
-
-                    @Override
-                    public LookupRegistry<Supplier<AsyncServerExchangeHandler>> get() {
-                        return lookupRegistry != null ? lookupRegistry :
-                                UriPatternType.<Supplier<AsyncServerExchangeHandler>>newMatcher(UriPatternType.URI_PATTERN);
-                    }
-
-                });
+                () -> lookupRegistry != null ? lookupRegistry :
+                        UriPatternType.<Supplier<AsyncServerExchangeHandler>>newMatcher(UriPatternType.URI_PATTERN));
         for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
             registry.register(entry.hostname, entry.uriPattern, entry.handler);
         }
@@ -412,14 +391,7 @@ public class H2ServerBootstrap {
 
             handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain, exceptionCallback);
         } else {
-            handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, new Decorator<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                    return new BasicAsyncServerExpectationDecorator(handler, exceptionCallback);
-                }
-
-            });
+            handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, handler -> new BasicAsyncServerExpectationDecorator(handler, exceptionCallback));
         }
 
         final ServerH2StreamMultiplexerFactory http2StreamHandlerFactory = new ServerH2StreamMultiplexerFactory(
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
index 8b8f32b..37107ca 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/nio/pool/H2ConnPool.java
@@ -139,14 +139,9 @@ public final class H2ConnPool extends AbstractIOSessionPool<HttpHost> {
             final long deadline = lastAccessTime + timeValue.toMilliseconds();
             if (deadline <= System.currentTimeMillis()) {
                 final Timeout socketTimeoutMillis = ioSession.getSocketTimeout();
-                ioSession.enqueue(new PingCommand(new BasicPingHandler(new Callback<Boolean>() {
-
-                    @Override
-                    public void execute(final Boolean result) {
-                        ioSession.setSocketTimeout(socketTimeoutMillis);
-                        callback.execute(result);
-                    }
-
+                ioSession.enqueue(new PingCommand(new BasicPingHandler(result -> {
+                    ioSession.setSocketTimeout(socketTimeoutMillis);
+                    callback.execute(result);
                 })), Command.Priority.NORMAL);
                 return;
             }
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptSupport.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptSupport.java
index 2c2440b..4cd7a6e 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptSupport.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/ConscryptSupport.java
@@ -27,13 +27,10 @@
 
 package org.apache.hc.core5.http2.ssl;
 
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLParameters;
 
 import org.apache.hc.core5.http.ssl.TLS;
 import org.apache.hc.core5.http.ssl.TlsCiphers;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.reactor.ssl.TlsDetails;
@@ -49,42 +46,32 @@ public final class ConscryptSupport {
     public static SSLSessionInitializer initialize(
             final Object attachment,
             final SSLSessionInitializer initializer) {
-        return new SSLSessionInitializer() {
-
-            @Override
-            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                final SSLParameters sslParameters = sslEngine.getSSLParameters();
-                sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
-                sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
-                H2TlsSupport.setEnableRetransmissions(sslParameters, false);
-                final String[] appProtocols = H2TlsSupport.selectApplicationProtocols(attachment);
-                if (Conscrypt.isConscrypt(sslEngine)) {
-                    sslEngine.setSSLParameters(sslParameters);
-                    Conscrypt.setApplicationProtocols(sslEngine, appProtocols);
-                } else {
-                    H2TlsSupport.setApplicationProtocols(sslParameters, appProtocols);
-                    sslEngine.setSSLParameters(sslParameters);
-                }
-                if (initializer != null) {
-                    initializer.initialize(endpoint, sslEngine);
-                }
+        return (endpoint, sslEngine) -> {
+            final SSLParameters sslParameters = sslEngine.getSSLParameters();
+            sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
+            sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
+            H2TlsSupport.setEnableRetransmissions(sslParameters, false);
+            final String[] appProtocols = H2TlsSupport.selectApplicationProtocols(attachment);
+            if (Conscrypt.isConscrypt(sslEngine)) {
+                sslEngine.setSSLParameters(sslParameters);
+                Conscrypt.setApplicationProtocols(sslEngine, appProtocols);
+            } else {
+                H2TlsSupport.setApplicationProtocols(sslParameters, appProtocols);
+                sslEngine.setSSLParameters(sslParameters);
+            }
+            if (initializer != null) {
+                initializer.initialize(endpoint, sslEngine);
             }
-
         };
     }
 
     public static SSLSessionVerifier verify(final SSLSessionVerifier verifier) {
-        return new SSLSessionVerifier() {
-
-            @Override
-            public TlsDetails verify(final NamedEndpoint endpoint, final SSLEngine sslEngine) throws SSLException {
-                TlsDetails tlsDetails = verifier != null ? verifier.verify(endpoint, sslEngine) : null;
-                if (tlsDetails == null && Conscrypt.isConscrypt(sslEngine)) {
-                    tlsDetails = new TlsDetails(sslEngine.getSession(), Conscrypt.getApplicationProtocol(sslEngine));
-                }
-                return tlsDetails;
+        return (endpoint, sslEngine) -> {
+            TlsDetails tlsDetails = verifier != null ? verifier.verify(endpoint, sslEngine) : null;
+            if (tlsDetails == null && Conscrypt.isConscrypt(sslEngine)) {
+                tlsDetails = new TlsDetails(sslEngine.getSession(), Conscrypt.getApplicationProtocol(sslEngine));
             }
-
+            return tlsDetails;
         };
     }
 
diff --git a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2TlsSupport.java b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2TlsSupport.java
index da46bc5..4362ee3 100644
--- a/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2TlsSupport.java
+++ b/httpcore5-h2/src/main/java/org/apache/hc/core5/http2/ssl/H2TlsSupport.java
@@ -27,13 +27,11 @@
 
 package org.apache.hc.core5.http2.ssl;
 
-import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
 
 import org.apache.hc.core5.http.ssl.TLS;
 import org.apache.hc.core5.http.ssl.TlsCiphers;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.util.ReflectionUtils;
 
@@ -68,21 +66,16 @@ public final class H2TlsSupport {
     public static SSLSessionInitializer enforceRequirements(
             final Object attachment,
             final SSLSessionInitializer initializer) {
-        return new SSLSessionInitializer() {
-
-            @Override
-            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                final SSLParameters sslParameters = sslEngine.getSSLParameters();
-                sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
-                sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
-                setEnableRetransmissions(sslParameters, false);
-                setApplicationProtocols(sslParameters, selectApplicationProtocols(attachment));
-                sslEngine.setSSLParameters(sslParameters);
-                if (initializer != null) {
-                    initializer.initialize(endpoint, sslEngine);
-                }
+        return (endpoint, sslEngine) -> {
+            final SSLParameters sslParameters = sslEngine.getSSLParameters();
+            sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
+            sslParameters.setCipherSuites(TlsCiphers.excludeH2Blacklisted(sslParameters.getCipherSuites()));
+            setEnableRetransmissions(sslParameters, false);
+            setApplicationProtocols(sslParameters, selectApplicationProtocols(attachment));
+            sslEngine.setSSLParameters(sslParameters);
+            if (initializer != null) {
+                initializer.initialize(endpoint, sslEngine);
             }
-
         };
     }
 
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ConscriptRequestExecutionExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ConscriptRequestExecutionExample.java
index 197bd33..e33f4e2 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ConscriptRequestExecutionExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2ConscriptRequestExecutionExample.java
@@ -59,7 +59,7 @@ import org.conscrypt.Conscrypt;
  */
 public class H2ConscriptRequestExecutionExample {
 
-    public final static void main(final String[] args) throws Exception {
+    public static void main(final String[] args) throws Exception {
 
         // Create and start requester
         final H2Config h2Config = H2Config.custom()
@@ -107,13 +107,10 @@ public class H2ConscriptRequestExecutionExample {
 
                 })
                 .create();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("https", "nghttp2.org", 443);
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
index daa975f..5104751 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FileServerExample.java
@@ -51,7 +51,7 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AsyncResponseBuilder;
 import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
 import org.apache.hc.core5.http.protocol.HttpContext;
@@ -130,7 +130,7 @@ public class H2FileServerExample {
                             final HttpRequest request,
                             final EntityDetails entityDetails,
                             final HttpContext context) throws HttpException {
-                        return new BasicRequestConsumer<>(entityDetails != null ? new NoopEntityConsumer() : null);
+                        return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
                     }
 
                     @Override
@@ -194,13 +194,10 @@ public class H2FileServerExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexClientExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexClientExample.java
index 43d36b9..c752175 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexClientExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexClientExample.java
@@ -113,13 +113,10 @@ public class H2FullDuplexClientExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final URI requestUri = new URI("http://nghttp2.org/httpbin/post");
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexServerExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexServerExample.java
index 78e5f59..d09f09b 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexServerExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2FullDuplexServerExample.java
@@ -34,7 +34,6 @@ import java.util.List;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
@@ -118,122 +117,112 @@ public class H2FullDuplexServerExample {
                     }
 
                 })
-                .register("/echo", new Supplier<AsyncServerExchangeHandler>() {
+                .register("/echo", () -> new AsyncServerExchangeHandler() {
+
+                    ByteBuffer buffer = ByteBuffer.allocate(2048);
+                    CapacityChannel inputCapacityChannel;
+                    DataStreamChannel outputDataChannel;
+                    boolean endStream;
+
+                    private void ensureCapacity(final int chunk) {
+                        if (buffer.remaining() < chunk) {
+                            final ByteBuffer oldBuffer = buffer;
+                            oldBuffer.flip();
+                            buffer = ByteBuffer.allocate(oldBuffer.remaining() + (chunk > 2048 ? chunk : 2048));
+                            buffer.put(oldBuffer);
+                        }
+                    }
 
                     @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new AsyncServerExchangeHandler() {
-
-                            ByteBuffer buffer = ByteBuffer.allocate(2048);
-                            CapacityChannel inputCapacityChannel;
-                            DataStreamChannel outputDataChannel;
-                            boolean endStream;
-
-                            private void ensureCapacity(final int chunk) {
-                                if (buffer.remaining() < chunk) {
-                                    final ByteBuffer oldBuffer = buffer;
-                                    oldBuffer.flip();
-                                    buffer = ByteBuffer.allocate(oldBuffer.remaining() + (chunk > 2048 ? chunk : 2048));
-                                    buffer.put(oldBuffer);
-                                }
-                            }
+                    public void handleRequest(
+                            final HttpRequest request,
+                            final EntityDetails entityDetails,
+                            final ResponseChannel responseChannel,
+                            final HttpContext context) throws HttpException, IOException {
+                        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
+                        responseChannel.sendResponse(response, entityDetails, context);
+                    }
 
-                            @Override
-                            public void handleRequest(
-                                    final HttpRequest request,
-                                    final EntityDetails entityDetails,
-                                    final ResponseChannel responseChannel,
-                                    final HttpContext context) throws HttpException, IOException {
-                                final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
-                                responseChannel.sendResponse(response, entityDetails, context);
+                    @Override
+                    public void consume(final ByteBuffer src) throws IOException {
+                        if (buffer.position() == 0) {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.write(src);
                             }
-
-                            @Override
-                            public void consume(final ByteBuffer src) throws IOException {
-                                if (buffer.position() == 0) {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.write(src);
-                                    }
-                                }
-                                if (src.hasRemaining()) {
-                                    ensureCapacity(src.remaining());
-                                    buffer.put(src);
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.requestOutput();
-                                    }
-                                }
+                        }
+                        if (src.hasRemaining()) {
+                            ensureCapacity(src.remaining());
+                            buffer.put(src);
+                            if (outputDataChannel != null) {
+                                outputDataChannel.requestOutput();
                             }
+                        }
+                    }
 
-                            @Override
-                            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                                if (buffer.hasRemaining()) {
-                                    capacityChannel.update(buffer.remaining());
-                                    inputCapacityChannel = null;
-                                } else {
-                                    inputCapacityChannel = capacityChannel;
-                                }
-                            }
+                    @Override
+                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                        if (buffer.hasRemaining()) {
+                            capacityChannel.update(buffer.remaining());
+                            inputCapacityChannel = null;
+                        } else {
+                            inputCapacityChannel = capacityChannel;
+                        }
+                    }
 
-                            @Override
-                            public void streamEnd(final List<? extends Header> trailers) throws IOException {
-                                endStream = true;
-                                if (buffer.position() == 0) {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.endStream();
-                                    }
-                                } else {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.requestOutput();
-                                    }
-                                }
+                    @Override
+                    public void streamEnd(final List<? extends Header> trailers) throws IOException {
+                        endStream = true;
+                        if (buffer.position() == 0) {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.endStream();
                             }
-
-                            @Override
-                            public int available() {
-                                return buffer.position();
+                        } else {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.requestOutput();
                             }
+                        }
+                    }
 
-                            @Override
-                            public void produce(final DataStreamChannel channel) throws IOException {
-                                outputDataChannel = channel;
-                                buffer.flip();
-                                if (buffer.hasRemaining()) {
-                                    channel.write(buffer);
-                                }
-                                buffer.compact();
-                                if (buffer.position() == 0 && endStream) {
-                                    channel.endStream();
-                                }
-                                final CapacityChannel capacityChannel = inputCapacityChannel;
-                                if (capacityChannel != null && buffer.hasRemaining()) {
-                                    capacityChannel.update(buffer.remaining());
-                                }
-                            }
+                    @Override
+                    public int available() {
+                        return buffer.position();
+                    }
 
-                            @Override
-                            public void failed(final Exception cause) {
-                                if (!(cause instanceof SocketException)) {
-                                    cause.printStackTrace(System.out);
-                                }
-                            }
+                    @Override
+                    public void produce(final DataStreamChannel channel) throws IOException {
+                        outputDataChannel = channel;
+                        buffer.flip();
+                        if (buffer.hasRemaining()) {
+                            channel.write(buffer);
+                        }
+                        buffer.compact();
+                        if (buffer.position() == 0 && endStream) {
+                            channel.endStream();
+                        }
+                        final CapacityChannel capacityChannel = inputCapacityChannel;
+                        if (capacityChannel != null && buffer.hasRemaining()) {
+                            capacityChannel.update(buffer.remaining());
+                        }
+                    }
 
-                            @Override
-                            public void releaseResources() {
-                            }
+                    @Override
+                    public void failed(final Exception cause) {
+                        if (!(cause instanceof SocketException)) {
+                            cause.printStackTrace(System.out);
+                        }
+                    }
 
-                        };
+                    @Override
+                    public void releaseResources() {
                     }
 
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2GreetingServer.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2GreetingServer.java
index 8e1c65c..c6f86b4 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2GreetingServer.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2GreetingServer.java
@@ -33,7 +33,6 @@ import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-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.EntityDetails;
@@ -49,10 +48,9 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http.nio.AsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AbstractServerExchangeHandler;
 import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
@@ -98,21 +96,13 @@ public class H2GreetingServer {
                 .setVersionPolicy(HttpVersionPolicy.NEGOTIATE) // fallback to HTTP/1 as needed
 
                 // wildcard path matcher:
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new CustomServerExchangeHandler();
-                    }
-                })
+                .register("*", CustomServerExchangeHandler::new)
                 .create();
 
 
-        Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
         }));
 
         server.start();
@@ -131,7 +121,7 @@ public class H2GreetingServer {
                 final EntityDetails entityDetails,
                 final HttpContext context) {
             // if there's no body don't try to parse entity:
-            AsyncEntityConsumer entityConsumer = new NoopEntityConsumer();
+            AsyncEntityConsumer<String> entityConsumer = new DiscardingEntityConsumer<>();
 
             if (entityDetails != null) {
                 entityConsumer = new StringAsyncEntityConsumer();
@@ -155,10 +145,10 @@ public class H2GreetingServer {
             final HttpResponse resp = new BasicHttpResponse(200);
 
             // recording the request
-            System.out.println(String.format("[%s] %s %s %s", new Date(),
+            System.out.printf("[%s] %s %s %s%n", new Date(),
                     endpoint.getRemoteAddress(),
                     req.getMethod(),
-                    req.getPath()));
+                    req.getPath());
 
             // Request without an entity - GET/HEAD/DELETE
             if (httpEntity == null) {
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2MultiStreamExecutionExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2MultiStreamExecutionExample.java
index f1545bc..2628387 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2MultiStreamExecutionExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2MultiStreamExecutionExample.java
@@ -106,13 +106,10 @@ public class H2MultiStreamExecutionExample {
 
                 })
                 .create();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("nghttp2.org");
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2RequestExecutionExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2RequestExecutionExample.java
index c150353..3653bae 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2RequestExecutionExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2RequestExecutionExample.java
@@ -98,13 +98,10 @@ public class H2RequestExecutionExample {
 
                 })
                 .create();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("nghttp2.org");
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2TlsAlpnRequestExecutionExample.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2TlsAlpnRequestExecutionExample.java
index 53aae42..5a67e09 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2TlsAlpnRequestExecutionExample.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/examples/H2TlsAlpnRequestExecutionExample.java
@@ -30,9 +30,6 @@ import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.Future;
 
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
-
 import org.apache.hc.core5.concurrent.FutureCallback;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
@@ -50,9 +47,6 @@ import org.apache.hc.core5.http2.impl.nio.H2StreamListener;
 import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
 import org.apache.hc.core5.http2.ssl.H2ClientTlsStrategy;
 import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.net.NamedEndpoint;
-import org.apache.hc.core5.reactor.ssl.SSLSessionVerifier;
-import org.apache.hc.core5.reactor.ssl.TlsDetails;
 import org.apache.hc.core5.ssl.SSLContexts;
 import org.apache.hc.core5.util.Timeout;
 
@@ -63,7 +57,7 @@ import org.apache.hc.core5.util.Timeout;
  */
 public class H2TlsAlpnRequestExecutionExample {
 
-    public final static void main(final String[] args) throws Exception {
+    public static void main(final String[] args) throws Exception {
         // Create and start requester
         final H2Config h2Config = H2Config.custom()
                 .setPushEnabled(false)
@@ -71,18 +65,13 @@ public class H2TlsAlpnRequestExecutionExample {
 
         final HttpAsyncRequester requester = H2RequesterBootstrap.bootstrap()
                 .setH2Config(h2Config)
-                .setTlsStrategy(new H2ClientTlsStrategy(SSLContexts.createSystemDefault(), new SSLSessionVerifier() {
-
-                    @Override
-                    public TlsDetails verify(final NamedEndpoint endpoint, final SSLEngine sslEngine) throws SSLException {
-                        // IMPORTANT uncomment the following line when running Java 9 or older
-                        // in order to avoid the illegal reflective access operation warning
-                        // ====
-                        // return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
-                        // ====
-                        return null;
-                    }
-
+                .setTlsStrategy(new H2ClientTlsStrategy(SSLContexts.createSystemDefault(), (endpoint, sslEngine) -> {
+                    // IMPORTANT uncomment the following line when running Java 9 or older
+                    // in order to avoid the illegal reflective access operation warning
+                    // ====
+                    // return new TlsDetails(sslEngine.getSession(), sslEngine.getApplicationProtocol());
+                    // ====
+                    return null;
                 }))
                 .setStreamListener(new H2StreamListener() {
 
@@ -118,13 +107,10 @@ public class H2TlsAlpnRequestExecutionExample {
 
                 })
                 .create();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("https", "nghttp2.org", 443);
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
index ea734fc..f15078a 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2RequestConverter.java
@@ -45,7 +45,7 @@ import org.junit.rules.ExpectedException;
 public class TestDefaultH2RequestConverter {
 
     @Rule
-    public ExpectedException thrown = ExpectedException.none();
+    public final ExpectedException thrown = ExpectedException.none();
 
     @Test
     public void testConvertFromFieldsBasic() throws Exception {
diff --git a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
index 1307f25..b3af5d7 100644
--- a/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
+++ b/httpcore5-h2/src/test/java/org/apache/hc/core5/http2/impl/TestDefaultH2ResponseConverter.java
@@ -43,7 +43,7 @@ import org.junit.rules.ExpectedException;
 public class TestDefaultH2ResponseConverter {
 
     @Rule
-    public ExpectedException thrown = ExpectedException.none();
+    public final ExpectedException thrown = ExpectedException.none();
 
     @Test
     public void testConvertFromFieldsBasic() throws Exception {
diff --git a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveResponseConsumer.java b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveResponseConsumer.java
index 48a68d3..196f7a1 100644
--- a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveResponseConsumer.java
+++ b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveResponseConsumer.java
@@ -60,7 +60,7 @@ import org.reactivestreams.Publisher;
 public final class ReactiveResponseConsumer implements AsyncResponseConsumer<Void> {
 
     private final ReactiveDataConsumer reactiveDataConsumer = new ReactiveDataConsumer();
-    private final List<Header> trailers = Collections.synchronizedList(new ArrayList<Header>());
+    private final List<Header> trailers = Collections.synchronizedList(new ArrayList<>());
     private final BasicFuture<Message<HttpResponse, Publisher<ByteBuffer>>> responseFuture;
 
     private volatile BasicFuture<Void> responseCompletion;
@@ -124,7 +124,7 @@ public final class ReactiveResponseConsumer implements AsyncResponseConsumer<Voi
     ) {
         this.entityDetails = entityDetails;
         this.responseCompletion = new BasicFuture<>(resultCallback);
-        this.responseFuture.completed(new Message<HttpResponse, Publisher<ByteBuffer>>(response, reactiveDataConsumer));
+        this.responseFuture.completed(new Message<>(response, reactiveDataConsumer));
         if (entityDetails == null) {
             streamEnd(null);
         }
diff --git a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveServerExchangeHandler.java b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveServerExchangeHandler.java
index d7932fe..d2eef61 100644
--- a/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveServerExchangeHandler.java
+++ b/httpcore5-reactive/src/main/java/org/apache/hc/core5/reactive/ReactiveServerExchangeHandler.java
@@ -73,16 +73,13 @@ public final class ReactiveServerExchangeHandler implements AsyncServerExchangeH
             final ResponseChannel responseChannel,
             final HttpContext context
     ) throws HttpException, IOException {
-        final Callback<Publisher<ByteBuffer>> callback = new Callback<Publisher<ByteBuffer>>() {
-            @Override
-            public void execute(final Publisher<ByteBuffer> result) {
-                final ReactiveDataProducer producer = new ReactiveDataProducer(result);
-                if (channel != null) {
-                    producer.setChannel(channel);
-                }
-                responseProducer.set(producer);
-                result.subscribe(producer);
+        final Callback<Publisher<ByteBuffer>> callback = result -> {
+            final ReactiveDataProducer producer = new ReactiveDataProducer(result);
+            if (channel != null) {
+                producer.setChannel(channel);
             }
+            responseProducer.set(producer);
+            result.subscribe(producer);
         };
         requestProcessor.processRequest(request, entityDetails, responseChannel, context, requestConsumer, callback);
     }
diff --git a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
index 47fff1d..2350746 100644
--- a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
+++ b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/TestReactiveDataConsumer.java
@@ -46,7 +46,6 @@ import io.reactivex.Flowable;
 import io.reactivex.Notification;
 import io.reactivex.Observable;
 import io.reactivex.Single;
-import io.reactivex.functions.Consumer;
 
 public class TestReactiveDataConsumer {
 
@@ -54,21 +53,18 @@ public class TestReactiveDataConsumer {
     public void testStreamThatEndsNormally() throws Exception {
         final ReactiveDataConsumer consumer = new ReactiveDataConsumer();
 
-        final List<ByteBuffer> output = Collections.synchronizedList(new ArrayList<ByteBuffer>());
+        final List<ByteBuffer> output = Collections.synchronizedList(new ArrayList<>());
 
         final CountDownLatch complete = new CountDownLatch(1);
         Observable.fromPublisher(consumer)
             .materialize()
-            .forEach(new Consumer<Notification<ByteBuffer>>() {
-                @Override
-                public void accept(final Notification<ByteBuffer> byteBufferNotification) throws Exception {
-                    if (byteBufferNotification.isOnComplete()) {
-                        complete.countDown();
-                    } else if (byteBufferNotification.isOnNext()) {
-                        output.add(byteBufferNotification.getValue());
-                    } else {
-                        throw new IllegalArgumentException();
-                    }
+            .forEach(byteBufferNotification -> {
+                if (byteBufferNotification.isOnComplete()) {
+                    complete.countDown();
+                } else if (byteBufferNotification.isOnNext()) {
+                    output.add(byteBufferNotification.getValue());
+                } else {
+                    throw new IllegalArgumentException();
                 }
             });
 
@@ -128,12 +124,7 @@ public class TestReactiveDataConsumer {
         final ByteBuffer data = ByteBuffer.wrap(new byte[1024]);
 
         final AtomicInteger lastIncrement = new AtomicInteger(-1);
-        final CapacityChannel channel = new CapacityChannel() {
-            @Override
-            public void update(final int increment) {
-                lastIncrement.set(increment);
-            }
-        };
+        final CapacityChannel channel = lastIncrement::set;
         consumer.updateCapacity(channel);
         Assert.assertEquals("CapacityChannel#update should not have been invoked yet", -1, lastIncrement.get());
 
diff --git a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexClientExample.java b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexClientExample.java
index 531d655..f962860 100644
--- a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexClientExample.java
+++ b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexClientExample.java
@@ -55,10 +55,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;
 
 /**
  * Example of full-duplex HTTP/1.1 message exchanges using reactive streaming. This demo will stream randomly
@@ -100,23 +97,17 @@ public class ReactiveFullDuplexClientExample {
             })
             .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final Random random = new Random();
         final Flowable<ByteBuffer> publisher = Flowable.range(1, 100)
-            .map(new Function<Integer, ByteBuffer>() {
-                @Override
-                public ByteBuffer apply(final Integer ignored) {
-                    final String str = random.nextDouble() + "\n";
-                    return ByteBuffer.wrap(str.getBytes(UTF_8));
-                }
+            .map(ignored -> {
+                final String str = random.nextDouble() + "\n";
+                return ByteBuffer.wrap(str.getBytes(UTF_8));
             });
         final AsyncRequestProducer requestProducer = AsyncRequestBuilder.post(new URI(endpoint))
                 .setEntity(new ReactiveEntityProducer(publisher, -1, ContentType.TEXT_PLAIN, null))
@@ -133,21 +124,13 @@ public class ReactiveFullDuplexClientExample {
         System.out.println();
 
         Observable.fromPublisher(streamingResponse.getBody())
-            .map(new Function<ByteBuffer, String>() {
-                @Override
-                public String apply(final ByteBuffer byteBuffer) {
-                    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) {
-                    System.out.println(byteBufferNotification);
-                }
-            });
+            .forEach(System.out::println);
 
         responseComplete.get(1, TimeUnit.MINUTES);
         System.out.println("Shutting down I/O reactor");
diff --git a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexServerExample.java b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexServerExample.java
index 5a91b6f..67c2056b 100644
--- a/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexServerExample.java
+++ b/httpcore5-reactive/src/test/java/org/apache/hc/core5/reactive/examples/ReactiveFullDuplexServerExample.java
@@ -26,19 +26,13 @@
  */
 package org.apache.hc.core5.reactive.examples;
 
-import java.io.IOException;
 import java.net.InetSocketAddress;
-import java.nio.ByteBuffer;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.core5.function.Callback;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.HeaderElements;
 import org.apache.hc.core5.http.HttpConnection;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpRequest;
 import org.apache.hc.core5.http.HttpResponse;
@@ -51,16 +45,11 @@ import org.apache.hc.core5.http.message.BasicHeader;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
 import org.apache.hc.core5.http.message.RequestLine;
 import org.apache.hc.core5.http.message.StatusLine;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
-import org.apache.hc.core5.http.nio.ResponseChannel;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.reactive.ReactiveRequestProcessor;
 import org.apache.hc.core5.reactive.ReactiveServerExchangeHandler;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
 import org.apache.hc.core5.util.TimeValue;
-import org.reactivestreams.Publisher;
 
 /**
  * Example of full-duplex HTTP/1.1 message exchanges using reactive streaming. This demo server works out-of-the-box
@@ -102,44 +91,26 @@ public class ReactiveFullDuplexServerExample {
                 }
 
             })
-            .register("/echo", new Supplier<AsyncServerExchangeHandler>() {
-                @Override
-                public AsyncServerExchangeHandler get() {
-                    return new ReactiveServerExchangeHandler(new ReactiveRequestProcessor() {
-                        @Override
-                        public void processRequest(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final ResponseChannel responseChannel,
-                            final HttpContext context,
-                            final Publisher<ByteBuffer> requestBody,
-                            final Callback<Publisher<ByteBuffer>> responseBodyFuture
-                        ) throws HttpException, IOException {
-                            if (new BasicHeader(HttpHeaders.EXPECT, HeaderElements.CONTINUE).equals(request.getHeader(HttpHeaders.EXPECT))) {
-                                responseChannel.sendInformation(new BasicHttpResponse(100), context);
-                            }
+            .register("/echo", () -> new ReactiveServerExchangeHandler((request, entityDetails, responseChannel, context, requestBody, responseBodyFuture) -> {
+                if (new BasicHeader(HttpHeaders.EXPECT, HeaderElements.CONTINUE).equals(request.getHeader(HttpHeaders.EXPECT))) {
+                    responseChannel.sendInformation(new BasicHttpResponse(100), context);
+                }
 
-                            responseChannel.sendResponse(
-                                new BasicHttpResponse(200),
-                                new BasicEntityDetails(-1, ContentType.APPLICATION_OCTET_STREAM),
-                                context);
+                responseChannel.sendResponse(
+                        new BasicHttpResponse(200),
+                        new BasicEntityDetails(-1, ContentType.APPLICATION_OCTET_STREAM),
+                        context);
 
-                            // Simply using the request publisher as the response publisher will
-                            // cause the server to echo the request body.
-                            responseBodyFuture.execute(requestBody);
-                        }
-                    });
-                }
-            })
+                // Simply using the request publisher as the response publisher will
+                // cause the server to echo the request body.
+                responseBodyFuture.execute(requestBody);
+            }))
             .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
index e968468..f4455ac 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/benchmark/HttpBenchmark.java
@@ -32,8 +32,6 @@ import java.net.SocketAddress;
 import java.net.URI;
 import java.nio.ByteBuffer;
 import java.nio.channels.ByteChannel;
-import java.security.cert.CertificateException;
-import java.security.cert.X509Certificate;
 import java.util.List;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -46,7 +44,6 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.Options;
-import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
 import org.apache.hc.core5.http.HttpHost;
@@ -77,7 +74,6 @@ import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.IOSession;
 import org.apache.hc.core5.ssl.SSLContextBuilder;
 import org.apache.hc.core5.ssl.SSLContexts;
-import org.apache.hc.core5.ssl.TrustStrategy;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -134,15 +130,7 @@ public class HttpBenchmark {
             final SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
             sslContextBuilder.setProtocol("SSL");
             if (config.isDisableSSLVerification()) {
-                sslContextBuilder.loadTrustMaterial(null, new TrustStrategy() {
-
-                    @Override
-                    public boolean isTrusted(
-                            final X509Certificate[] chain, final String authType) throws CertificateException {
-                        return true;
-                    }
-
-                });
+                sslContextBuilder.loadTrustMaterial(null, (chain, authType) -> true);
             } else if (config.getTrustStorePath() != null) {
                 sslContextBuilder.loadTrustMaterial(
                         new File(config.getTrustStorePath()),
@@ -178,156 +166,149 @@ public class HttpBenchmark {
                 .setH2Config(H2Config.custom()
                         .setPushEnabled(false)
                         .build())
-                .setIOSessionDecorator(new Decorator<IOSession>() {
+                .setIOSessionDecorator(ioSession -> new IOSession() {
 
                     @Override
-                    public IOSession decorate(final IOSession ioSession) {
-                        return new IOSession() {
-
-                            @Override
-                            public String getId() {
-                                return ioSession.getId();
-                            }
-
-                            @Override
-                            public Lock getLock() {
-                                return ioSession.getLock();
-                            }
+                    public String getId() {
+                        return ioSession.getId();
+                    }
 
-                            @Override
-                            public void enqueue(final Command command, final Command.Priority priority) {
-                                ioSession.enqueue(command, priority);
-                            }
+                    @Override
+                    public Lock getLock() {
+                        return ioSession.getLock();
+                    }
 
-                            @Override
-                            public boolean hasCommands() {
-                                return ioSession.hasCommands();
-                            }
+                    @Override
+                    public void enqueue(final Command command, final Command.Priority priority) {
+                        ioSession.enqueue(command, priority);
+                    }
 
-                            @Override
-                            public Command poll() {
-                                return ioSession.poll();
-                            }
+                    @Override
+                    public boolean hasCommands() {
+                        return ioSession.hasCommands();
+                    }
 
-                            @Override
-                            public ByteChannel channel() {
-                                return ioSession.channel();
-                            }
+                    @Override
+                    public Command poll() {
+                        return ioSession.poll();
+                    }
 
-                            @Override
-                            public SocketAddress getRemoteAddress() {
-                                return ioSession.getRemoteAddress();
-                            }
+                    @Override
+                    public ByteChannel channel() {
+                        return ioSession.channel();
+                    }
 
-                            @Override
-                            public SocketAddress getLocalAddress() {
-                                return ioSession.getLocalAddress();
-                            }
+                    @Override
+                    public SocketAddress getRemoteAddress() {
+                        return ioSession.getRemoteAddress();
+                    }
 
-                            @Override
-                            public int getEventMask() {
-                                return ioSession.getEventMask();
-                            }
+                    @Override
+                    public SocketAddress getLocalAddress() {
+                        return ioSession.getLocalAddress();
+                    }
 
-                            @Override
-                            public void setEventMask(final int ops) {
-                                ioSession.setEventMask(ops);
-                            }
+                    @Override
+                    public int getEventMask() {
+                        return ioSession.getEventMask();
+                    }
 
-                            @Override
-                            public void setEvent(final int op) {
-                                ioSession.setEvent(op);
-                            }
+                    @Override
+                    public void setEventMask(final int ops) {
+                        ioSession.setEventMask(ops);
+                    }
 
-                            @Override
-                            public void clearEvent(final int op) {
-                                ioSession.clearEvent(op);
-                            }
+                    @Override
+                    public void setEvent(final int op) {
+                        ioSession.setEvent(op);
+                    }
 
-                            @Override
-                            public void close() {
-                                ioSession.close();
-                            }
+                    @Override
+                    public void clearEvent(final int op) {
+                        ioSession.clearEvent(op);
+                    }
 
-                            @Override
-                            public Status getStatus() {
-                                return ioSession.getStatus();
-                            }
+                    @Override
+                    public void close() {
+                        ioSession.close();
+                    }
 
-                            @Override
-                            public int read(final ByteBuffer dst) throws IOException {
-                                final int bytesRead = ioSession.read(dst);
-                                if (bytesRead > 0) {
-                                    stats.incTotalBytesRecv(bytesRead);
-                                }
-                                return bytesRead;
-                            }
+                    @Override
+                    public Status getStatus() {
+                        return ioSession.getStatus();
+                    }
 
-                            @Override
-                            public int write(final ByteBuffer src) throws IOException {
-                                final int bytesWritten = ioSession.write(src);
-                                if (bytesWritten > 0) {
-                                    stats.incTotalBytesSent(bytesWritten);
-                                }
-                                return bytesWritten;
-                            }
+                    @Override
+                    public int read(final ByteBuffer dst) throws IOException {
+                        final int bytesRead = ioSession.read(dst);
+                        if (bytesRead > 0) {
+                            stats.incTotalBytesRecv(bytesRead);
+                        }
+                        return bytesRead;
+                    }
 
-                            @Override
-                            public boolean isOpen() {
-                                return ioSession.isOpen();
-                            }
+                    @Override
+                    public int write(final ByteBuffer src) throws IOException {
+                        final int bytesWritten = ioSession.write(src);
+                        if (bytesWritten > 0) {
+                            stats.incTotalBytesSent(bytesWritten);
+                        }
+                        return bytesWritten;
+                    }
 
-                            @Override
-                            public Timeout getSocketTimeout() {
-                                return ioSession.getSocketTimeout();
-                            }
+                    @Override
+                    public boolean isOpen() {
+                        return ioSession.isOpen();
+                    }
 
-                            @Override
-                            public void setSocketTimeout(final Timeout timeout) {
-                                ioSession.setSocketTimeout(timeout);
-                            }
+                    @Override
+                    public Timeout getSocketTimeout() {
+                        return ioSession.getSocketTimeout();
+                    }
 
-                            @Override
-                            public long getLastReadTime() {
-                                return ioSession.getLastReadTime();
-                            }
+                    @Override
+                    public void setSocketTimeout(final Timeout timeout) {
+                        ioSession.setSocketTimeout(timeout);
+                    }
 
-                            @Override
-                            public long getLastWriteTime() {
-                                return ioSession.getLastWriteTime();
-                            }
+                    @Override
+                    public long getLastReadTime() {
+                        return ioSession.getLastReadTime();
+                    }
 
-                            @Override
-                            public long getLastEventTime() {
-                                return ioSession.getLastEventTime();
-                            }
+                    @Override
+                    public long getLastWriteTime() {
+                        return ioSession.getLastWriteTime();
+                    }
 
-                            @Override
-                            public void updateReadTime() {
-                                ioSession.updateReadTime();
-                            }
+                    @Override
+                    public long getLastEventTime() {
+                        return ioSession.getLastEventTime();
+                    }
 
-                            @Override
-                            public void updateWriteTime() {
-                                ioSession.updateWriteTime();
-                            }
+                    @Override
+                    public void updateReadTime() {
+                        ioSession.updateReadTime();
+                    }
 
-                            @Override
-                            public void close(final CloseMode closeMode) {
-                                ioSession.close(closeMode);
-                            }
+                    @Override
+                    public void updateWriteTime() {
+                        ioSession.updateWriteTime();
+                    }
 
-                            @Override
-                            public IOEventHandler getHandler() {
-                                return ioSession.getHandler();
-                            }
+                    @Override
+                    public void close(final CloseMode closeMode) {
+                        ioSession.close(closeMode);
+                    }
 
-                            @Override
-                            public void upgrade(final IOEventHandler handler) {
-                                ioSession.upgrade(handler);
-                            }
+                    @Override
+                    public IOEventHandler getHandler() {
+                        return ioSession.getHandler();
+                    }
 
-                        };
+                    @Override
+                    public void upgrade(final IOEventHandler handler) {
+                        ioSession.upgrade(handler);
                     }
 
                 })
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
index 3a200d3..7d8234d 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/SocksProxy.java
@@ -166,23 +166,20 @@ public class SocksProxy {
                 }
 
                 private Thread pumpStream(final InputStream input, final OutputStream output) {
-                    final Thread t = new Thread(new Runnable() {
-                        @Override
-                        public void run() {
-                            final byte[] buffer = new byte[1024 * 8];
-                            try {
-                                while (true) {
-                                    final int read = input.read(buffer);
-                                    if (read < 0) {
-                                        break;
-                                    }
-                                    output.write(buffer, 0, read);
-                                    output.flush();
+                    final Thread t = new Thread(() -> {
+                        final byte[] buffer = new byte[1024 * 8];
+                        try {
+                            while (true) {
+                                final int read = input.read(buffer);
+                                if (read < 0) {
+                                    break;
                                 }
-                            } catch (final IOException e) {
-                            } finally {
-                                shutdown();
+                                output.write(buffer, 0, read);
+                                output.flush();
                             }
+                        } catch (final IOException e) {
+                        } finally {
+                            shutdown();
                         }
                     });
                     t.start();
@@ -224,23 +221,20 @@ public class SocksProxy {
     public synchronized void start() throws IOException {
         if (this.server == null) {
             this.server = new ServerSocket(this.port);
-            this.serverThread = new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    try {
-                        while (true) {
-                            final Socket socket = server.accept();
-                            startSocksProxyHandler(socket);
-                        }
-                    } catch (final IOException e) {
-                    } finally {
-                        if (server != null) {
-                            try {
-                                server.close();
-                            } catch (final IOException e) {
-                            }
-                            server = null;
+            this.serverThread = new Thread(() -> {
+                try {
+                    while (true) {
+                        final Socket socket = server.accept();
+                        startSocksProxyHandler(socket);
+                    }
+                } catch (final IOException e) {
+                } finally {
+                    if (server != null) {
+                        try {
+                            server.close();
+                        } catch (final IOException e) {
                         }
+                        server = null;
                     }
                 }
             });
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
index b9ac33e..a065827 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/framework/TestingFramework.java
@@ -52,7 +52,6 @@ import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.ProtocolVersion;
 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.io.SocketConfig;
 import org.apache.hc.core5.http.protocol.UriPatternMatcher;
 import org.apache.hc.core5.io.CloseMode;
@@ -233,7 +232,7 @@ public class TestingFramework {
                                           .build();
 
         final ServerBootstrap serverBootstrap = ServerBootstrap.bootstrap()
-                                          .setLookupRegistry(new UriPatternMatcher<HttpRequestHandler>())
+                                          .setLookupRegistry(new UriPatternMatcher<>())
                                           .setSocketConfig(socketConfig)
                                           .register("/*", requestHandler);
 
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
index 7707bfd..5406f55 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/H2TestServer.java
@@ -84,14 +84,7 @@ public class H2TestServer extends AsyncServer {
     public <T> void register(
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
     }
 
     public void start(final IOEventHandlerFactory handlerFactory) throws IOException {
@@ -106,14 +99,7 @@ public class H2TestServer extends AsyncServer {
                 httpProcessor != null ? httpProcessor : H2Processors.server(),
                 new DefaultAsyncResponseExchangeHandlerFactory(
                         registry,
-                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
-
-                            @Override
-                            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                                return new BasicAsyncServerExpectationDecorator(handler);
-                            }
-
-                        }),
+                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : BasicAsyncServerExpectationDecorator::new),
                 HttpVersionPolicy.FORCE_HTTP_2,
                 h2Config,
                 Http1Config.DEFAULT,
@@ -134,14 +120,7 @@ public class H2TestServer extends AsyncServer {
                 httpProcessor != null ? httpProcessor : HttpProcessors.server(),
                 new DefaultAsyncResponseExchangeHandlerFactory(
                         registry,
-                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                        return new BasicAsyncServerExpectationDecorator(handler);
-                    }
-
-                }),
+                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : BasicAsyncServerExpectationDecorator::new),
                 HttpVersionPolicy.FORCE_HTTP_1,
                 H2Config.DEFAULT,
                 http1Config,
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
index 1bcc2da..bd3cfc6 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/nio/Http1TestServer.java
@@ -82,14 +82,7 @@ public class Http1TestServer extends AsyncServer {
     public <T> void register(
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
     }
 
     public InetSocketAddress start(final IOEventHandlerFactory handlerFactory) throws Exception {
@@ -107,14 +100,7 @@ public class Http1TestServer extends AsyncServer {
                 httpProcessor != null ? httpProcessor : HttpProcessors.server(),
                 new DefaultAsyncResponseExchangeHandlerFactory(
                         registry,
-                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : new Decorator<AsyncServerExchangeHandler>() {
-
-                            @Override
-                            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                                return new BasicAsyncServerExpectationDecorator(handler);
-                            }
-
-                        }),
+                        exchangeHandlerDecorator != null ? exchangeHandlerDecorator : BasicAsyncServerExpectationDecorator::new),
                 http1Config,
                 CharCodingConfig.DEFAULT,
                 DefaultConnectionReuseStrategy.INSTANCE,
diff --git a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/reactive/ReactiveTestUtils.java b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/reactive/ReactiveTestUtils.java
index 66c0dc8..39fb67d 100644
--- a/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/reactive/ReactiveTestUtils.java
+++ b/httpcore5-testing/src/main/java/org/apache/hc/core5/testing/reactive/ReactiveTestUtils.java
@@ -40,7 +40,6 @@ import org.reactivestreams.Publisher;
 import io.reactivex.Emitter;
 import io.reactivex.Flowable;
 import io.reactivex.Single;
-import io.reactivex.functions.BiFunction;
 import io.reactivex.functions.Consumer;
 
 public class ReactiveTestUtils {
@@ -128,13 +127,10 @@ public class ReactiveTestUtils {
     public static Single<StreamDescription> consumeStream(final Publisher<ByteBuffer> publisher) {
         final StreamDescription seed = new StreamDescription(0, newMessageDigest());
         return Flowable.fromPublisher(publisher)
-                .reduce(seed, new BiFunction<StreamDescription, ByteBuffer, StreamDescription>() {
-                    @Override
-                    public StreamDescription apply(final StreamDescription desc, final ByteBuffer byteBuffer) {
-                        final long length = desc.length + byteBuffer.remaining();
-                        desc.md.update(byteBuffer);
-                        return new StreamDescription(length, desc.md);
-                    }
+                .reduce(seed, (desc, byteBuffer) -> {
+                    final long length = desc.length + byteBuffer.remaining();
+                    desc.md.update(byteBuffer);
+                    return new StreamDescription(length, desc.md);
                 });
     }
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
index d3195d2..becc3f0 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/benchmark/BenchmarkToolTest.java
@@ -43,7 +43,7 @@ import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AsyncResponseBuilder;
 import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
 import org.apache.hc.core5.http.protocol.HttpContext;
@@ -88,7 +88,7 @@ public class BenchmarkToolTest {
                             final HttpRequest request,
                             final EntityDetails entityDetails,
                             final HttpContext context) throws HttpException {
-                        return new BasicRequestConsumer<>(entityDetails != null ? new NoopEntityConsumer() : null);
+                        return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
                     }
 
                     @Override
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
index f843485..0d3a978 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicIntegrationTest.java
@@ -41,25 +41,19 @@ import java.util.List;
 import java.util.Random;
 import java.util.concurrent.TimeUnit;
 
-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.ContentType;
-import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpEntity;
 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.HttpRequest;
-import org.apache.hc.core5.http.HttpRequestInterceptor;
 import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.HttpVersion;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.config.Http1Config;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
-import org.apache.hc.core5.http.io.HttpServerRequestHandler;
 import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
 import org.apache.hc.core5.http.io.entity.ByteArrayEntity;
@@ -175,24 +169,16 @@ public class ClassicIntegrationTest {
         }
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                String s = request.getPath();
-                if (s.startsWith("/?")) {
-                    s = s.substring(2);
-                }
-                final int index = Integer.parseInt(s);
-                final byte[] data = testData.get(index);
-                final ByteArrayEntity entity = new ByteArrayEntity(data, null);
-                response.setEntity(entity);
+            String s = request.getPath();
+            if (s.startsWith("/?")) {
+                s = s.substring(2);
             }
-
+            final int index = Integer.parseInt(s);
+            final byte[] data = testData.get(index);
+            final ByteArrayEntity entity = new ByteArrayEntity(data, null);
+            response.setEntity(entity);
         });
 
         this.server.start();
@@ -236,21 +222,13 @@ public class ClassicIntegrationTest {
         }
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null));
             }
-
         });
 
         this.server.start();
@@ -297,21 +275,13 @@ public class ClassicIntegrationTest {
         }
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null, true));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null, true));
             }
-
         });
 
         this.server.start();
@@ -357,24 +327,16 @@ public class ClassicIntegrationTest {
         }
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null));
-                }
-                if (HttpVersion.HTTP_1_0.equals(request.getVersion())) {
-                    response.addHeader("Version", "1.0");
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null));
+            }
+            if (HttpVersion.HTTP_1_0.equals(request.getVersion())) {
+                response.addHeader("Version", "1.0");
             }
-
         });
 
         this.server.start();
@@ -427,21 +389,13 @@ public class ClassicIntegrationTest {
         }
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null, true));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null, true));
             }
-
         });
 
         this.server.start();
@@ -477,47 +431,29 @@ public class ClassicIntegrationTest {
         final int reqNo = 20;
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> response.setEntity(new StringEntity("No content")));
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                response.setEntity(new StringEntity("No content"));
-            }
-
-        });
-
-        this.server.start(null, null, new Decorator<HttpServerRequestHandler>() {
+        this.server.start(null, null, handler -> new BasicHttpServerExpectationDecorator(handler) {
 
             @Override
-            public HttpServerRequestHandler decorate(final HttpServerRequestHandler handler) {
-                return new BasicHttpServerExpectationDecorator(handler) {
-
-                    @Override
-                    protected ClassicHttpResponse verify(final ClassicHttpRequest request, final HttpContext context) {
-                        final Header someheader = request.getFirstHeader("Secret");
-                        if (someheader != null) {
-                            final int secretNumber;
-                            try {
-                                secretNumber = Integer.parseInt(someheader.getValue());
-                            } catch (final NumberFormatException ex) {
-                                final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST);
-                                response.setEntity(new StringEntity(ex.toString()));
-                                return response;
-                            }
-                            if (secretNumber >= 2) {
-                                final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
-                                response.setEntity(new StringEntity("Wrong secret number", ContentType.TEXT_PLAIN));
-                                return response;
-                            }
-                        }
-                        return null;
+            protected ClassicHttpResponse verify(final ClassicHttpRequest request, final HttpContext context) {
+                final Header someheader = request.getFirstHeader("Secret");
+                if (someheader != null) {
+                    final int secretNumber;
+                    try {
+                        secretNumber = Integer.parseInt(someheader.getValue());
+                    } catch (final NumberFormatException ex) {
+                        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_BAD_REQUEST);
+                        response.setEntity(new StringEntity(ex.toString()));
+                        return response;
                     }
-
-                };
+                    if (secretNumber >= 2) {
+                        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_EXPECTATION_FAILED);
+                        response.setEntity(new StringEntity("Wrong secret number", ContentType.TEXT_PLAIN));
+                        return response;
+                    }
+                }
+                return null;
             }
 
         });
@@ -622,42 +558,34 @@ public class ClassicIntegrationTest {
         };
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                int n = 1;
-                String s = request.getPath();
-                if (s.startsWith("/?n=")) {
-                    s = s.substring(4);
-                    try {
-                        n = Integer.parseInt(s);
-                        if (n <= 0) {
-                            throw new HttpException("Invalid request: " +
-                                    "number of repetitions cannot be negative or zero");
-                        }
-                    } catch (final NumberFormatException ex) {
+            int n = 1;
+            String s = request.getPath();
+            if (s.startsWith("/?n=")) {
+                s = s.substring(4);
+                try {
+                    n = Integer.parseInt(s);
+                    if (n <= 0) {
                         throw new HttpException("Invalid request: " +
-                                "number of repetitions is invalid");
+                                "number of repetitions cannot be negative or zero");
                     }
+                } catch (final NumberFormatException ex) {
+                    throw new HttpException("Invalid request: " +
+                            "number of repetitions is invalid");
                 }
+            }
 
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final String line = EntityUtils.toString(entity);
-                    final ContentType contentType = ContentType.parse(entity.getContentType());
-                    Charset charset = contentType.getCharset();
-                    if (charset == null) {
-                        charset = StandardCharsets.ISO_8859_1;
-                    }
-                    response.setEntity(new RepeatingEntity(line, charset, n, n % 2 == 0));
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final String line = EntityUtils.toString(entity);
+                final ContentType contentType = ContentType.parse(entity.getContentType());
+                Charset charset = contentType.getCharset();
+                if (charset == null) {
+                    charset = StandardCharsets.ISO_8859_1;
                 }
+                response.setEntity(new RepeatingEntity(line, charset, n, n % 2 == 0));
             }
-
         });
 
         this.server.start();
@@ -698,21 +626,13 @@ public class ClassicIntegrationTest {
 
     @Test
     public void testHttpPostNoEntity() throws Exception {
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null));
             }
-
         });
 
         this.server.start();
@@ -733,21 +653,13 @@ public class ClassicIntegrationTest {
 
     @Test
     public void testHttpPostNoContentLength() throws Exception {
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null));
             }
-
         });
 
         this.server.start();
@@ -772,36 +684,18 @@ public class ClassicIntegrationTest {
 
     @Test
     public void testHttpPostIdentity() throws Exception {
-        this.server.registerHandler("*", new HttpRequestHandler() {
+        this.server.registerHandler("*", (request, response, context) -> {
 
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-
-                final HttpEntity entity = request.getEntity();
-                if (entity != null) {
-                    final byte[] data = EntityUtils.toByteArray(entity);
-                    response.setEntity(new ByteArrayEntity(data, null));
-                }
+            final HttpEntity entity = request.getEntity();
+            if (entity != null) {
+                final byte[] data = EntityUtils.toByteArray(entity);
+                response.setEntity(new ByteArrayEntity(data, null));
             }
-
         });
 
         this.server.start();
         this.client.start(new DefaultHttpProcessor(
-                new HttpRequestInterceptor() {
-
-                    @Override
-                    public void process(
-                            final HttpRequest request,
-                            final EntityDetails entity,
-                            final HttpContext context) throws HttpException, IOException {
-                        request.addHeader(HttpHeaders.TRANSFER_ENCODING, "identity");
-                    }
-
-                },
+                (request, entity, context) -> request.addHeader(HttpHeaders.TRANSFER_ENCODING, "identity"),
                 new RequestTargetHost(),
                 new RequestConnControl(),
                 new RequestUserAgent(),
@@ -824,17 +718,7 @@ public class ClassicIntegrationTest {
         final int reqNo = 20;
 
         // Initialize the server-side request handler
-        this.server.registerHandler("*", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_NO_CONTENT);
-            }
-
-        });
+        this.server.registerHandler("*", (request, response, context) -> response.setCode(HttpStatus.SC_NO_CONTENT));
 
         this.server.start();
         this.client.start();
@@ -854,17 +738,7 @@ public class ClassicIntegrationTest {
     public void testAbsentHostHeader() throws Exception {
 
         // Initialize the server-side request handler
-        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", StandardCharsets.US_ASCII));
-            }
-
-        });
+        this.server.registerHandler("*", (request, response, context) -> response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII)));
 
         this.server.start();
         this.client.start(new DefaultHttpProcessor(new RequestContent(), new RequestConnControl()));
@@ -888,17 +762,7 @@ public class ClassicIntegrationTest {
 
     @Test
     public void testHeaderTooLarge() 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", StandardCharsets.US_ASCII));
-            }
-
-        });
+        this.server.registerHandler("*", (request, response, context) -> response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII)));
 
         this.server.start(
                 Http1Config.custom()
@@ -922,17 +786,7 @@ public class ClassicIntegrationTest {
 
     @Test
     public void testHeaderTooLargePost() 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", StandardCharsets.US_ASCII));
-            }
-
-        });
+        this.server.registerHandler("*", (request, response, context) -> response.setEntity(new StringEntity("All is well", StandardCharsets.US_ASCII)));
 
         this.server.start(
                 Http1Config.custom()
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerAndRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerAndRequesterTest.java
index 83377b3..1d8b3e0 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerAndRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerAndRequesterTest.java
@@ -47,12 +47,10 @@ import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
 import org.apache.hc.core5.http.io.HttpFilterChain;
-import org.apache.hc.core5.http.io.HttpFilterHandler;
 import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.testing.SSLTestContexts;
@@ -101,35 +99,24 @@ public class ClassicServerAndRequesterTest {
                             .setSoTimeout(TIMEOUT)
                             .build())
                     .register("*", new EchoHandler())
-                    .addFilterBefore(StandardFilter.MAIN_HANDLER.name(), "no-keep-alive", new HttpFilterHandler() {
+                    .addFilterBefore(StandardFilter.MAIN_HANDLER.name(), "no-keep-alive", (request, responseTrigger, context, chain) -> chain.proceed(request, new HttpFilterChain.ResponseTrigger() {
 
                         @Override
-                        public void handle(
-                                final ClassicHttpRequest request,
-                                final HttpFilterChain.ResponseTrigger responseTrigger,
-                                final HttpContext context,
-                                final HttpFilterChain chain) throws HttpException, IOException {
-                            chain.proceed(request, new HttpFilterChain.ResponseTrigger() {
-
-                                @Override
-                                public void sendInformation(
-                                        final ClassicHttpResponse response) throws HttpException, IOException {
-                                    responseTrigger.sendInformation(response);
-                                }
-
-                                @Override
-                                public void submitResponse(
-                                        final ClassicHttpResponse response) throws HttpException, IOException {
-                                    if (request.getPath().startsWith("/no-keep-alive")) {
-                                        response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-                                    }
-                                    responseTrigger.submitResponse(response);
-                                }
-
-                            }, context);
+                        public void sendInformation(
+                                final ClassicHttpResponse response) throws HttpException, IOException {
+                            responseTrigger.sendInformation(response);
                         }
 
-                    })
+                        @Override
+                        public void submitResponse(
+                                final ClassicHttpResponse response) throws HttpException, IOException {
+                            if (request.getPath().startsWith("/no-keep-alive")) {
+                                response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                            }
+                            responseTrigger.submitResponse(response);
+                        }
+
+                    }, context))
                     .setExceptionListener(LoggingExceptionListener.INSTANCE)
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE)
                     .create();
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
index 8345886..3e50e34 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicServerBootstrapFilterTest.java
@@ -42,11 +42,9 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpServer;
 import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.HttpFilterChain;
-import org.apache.hc.core5.http.io.HttpFilterHandler;
 import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.util.Timeout;
@@ -77,14 +75,7 @@ public class ClassicServerBootstrapFilterTest {
                             .setSoTimeout(TIMEOUT)
                             .build())
                     .register("*", new EchoHandler())
-                    .addFilterLast("test-filter", new HttpFilterHandler() {
-
-                        @Override
-                        public void handle(
-                                final ClassicHttpRequest request,
-                                final HttpFilterChain.ResponseTrigger responseTrigger,
-                                final HttpContext context,
-                                final HttpFilterChain chain) throws HttpException, IOException {
+                    .addFilterLast("test-filter", (request, responseTrigger, context, chain) ->
                             chain.proceed(request, new HttpFilterChain.ResponseTrigger() {
 
                                 @Override
@@ -100,10 +91,7 @@ public class ClassicServerBootstrapFilterTest {
                                     responseTrigger.submitResponse(response);
                                 }
 
-                            }, context);
-                        }
-
-                    })
+                            }, context))
                     .setExceptionListener(LoggingExceptionListener.INSTANCE)
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE)
                     .create();
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicTLSIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicTLSIntegrationTest.java
index c839f01..0876347 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicTLSIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/ClassicTLSIntegrationTest.java
@@ -30,12 +30,9 @@ package org.apache.hc.core5.testing.classic;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLSession;
 
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
@@ -50,7 +47,6 @@ import org.apache.hc.core5.http.impl.bootstrap.ServerBootstrap;
 import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
-import org.apache.hc.core5.http.io.ssl.SSLSessionVerifier;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
 import org.apache.hc.core5.http.protocol.BasicHttpContext;
 import org.apache.hc.core5.http.protocol.HttpContext;
@@ -121,14 +117,7 @@ public class ClassicTLSIntegrationTest {
 
         requester = RequesterBootstrap.bootstrap()
                 .setSslContext(SSLTestContexts.createClientSSLContext())
-                .setSslSessionVerifier(new SSLSessionVerifier() {
-
-                    @Override
-                    public void verify(final HttpHost endpoint, final SSLSession sslSession) throws SSLException {
-                        sslSessionRef.set(sslSession);
-                    }
-
-                })
+                .setSslSessionVerifier((endpoint, sslSession) -> sslSessionRef.set(sslSession))
                 .setSocketConfig(SocketConfig.custom()
                         .setSoTimeout(TIMEOUT)
                         .build())
@@ -192,14 +181,7 @@ public class ClassicTLSIntegrationTest {
                         .setSoTimeout(TIMEOUT)
                         .build())
                 .setSslContext(SSLTestContexts.createServerSSLContext())
-                .setSslSetupHandler(new Callback<SSLParameters>() {
-
-                    @Override
-                    public void execute(final SSLParameters sslParameters) {
-                        sslParameters.setNeedClientAuth(true);
-                    }
-
-                })
+                .setSslSetupHandler(sslParameters -> sslParameters.setNeedClientAuth(true))
                 .setExceptionListener(LoggingExceptionListener.INSTANCE)
                 .setStreamListener(LoggingHttp1StreamListener.INSTANCE)
                 .register("*", new EchoHandler())
@@ -228,14 +210,7 @@ public class ClassicTLSIntegrationTest {
     public void testSSLDisabledByDefault() throws Exception {
         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();
         server.start();
 
@@ -290,14 +265,7 @@ public class ClassicTLSIntegrationTest {
         for (final String cipherSuite : weakCiphersSuites) {
             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();
             try {
                 server.start();
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
index fad4491..d8ce77c 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/classic/MonitoringResponseOutOfOrderStrategyIntegrationTest.java
@@ -27,6 +27,12 @@
 
 package org.apache.hc.core5.testing.classic;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.Collection;
+
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ContentType;
@@ -37,12 +43,10 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpRequester;
 import org.apache.hc.core5.http.impl.bootstrap.RequesterBootstrap;
 import org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnectionFactory;
 import org.apache.hc.core5.http.impl.io.MonitoringResponseOutOfOrderStrategy;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
 import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.AbstractHttpEntity;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.testing.SSLTestContexts;
@@ -54,12 +58,6 @@ import org.junit.rules.ExternalResource;
 import org.junit.runner.RunWith;
 import org.junit.runners.Parameterized;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Arrays;
-import java.util.Collection;
-
 @RunWith(Parameterized.class)
 public class MonitoringResponseOutOfOrderStrategyIntegrationTest {
 
@@ -147,17 +145,9 @@ public class MonitoringResponseOutOfOrderStrategyIntegrationTest {
 
     @Test(timeout = 5000) // Failures may hang
     public void testResponseOutOfOrderWithDefaultStrategy() throws Exception {
-        this.server.registerHandler("*", new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws IOException {
-                response.setCode(400);
-                response.setEntity(new AllOnesHttpEntity(200000));
-            }
-
+        this.server.registerHandler("*", (request, response, context) -> {
+            response.setCode(400);
+            response.setEntity(new AllOnesHttpEntity(200000));
         });
 
         this.server.start(null, null, null);
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/H2CompatibilityTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/H2CompatibilityTest.java
index a18c081..b82ad06 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/H2CompatibilityTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/compatibility/http2/H2CompatibilityTest.java
@@ -51,15 +51,12 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
-import org.apache.hc.core5.http.nio.HandlerFactory;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.AbstractAsyncPushHandler;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.config.H2Config;
 import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
@@ -239,31 +236,25 @@ public class H2CompatibilityTest {
                 final Future<Message<HttpResponse, String>> future = endpoint.execute(
                         new BasicRequestProducer(httpget, null),
                         new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
-                        new HandlerFactory<AsyncPushConsumer>() {
+                        (request, context) -> new AbstractAsyncPushHandler<Message<HttpResponse, Void>>(
+                                new BasicResponseConsumer<>(new DiscardingEntityConsumer<>())) {
 
                             @Override
-                            public AsyncPushConsumer create(
-                                    final HttpRequest request, final HttpContext context) throws HttpException {
-                                return new AbstractAsyncPushHandler<Message<HttpResponse, Void>>(new BasicResponseConsumer<>(new NoopEntityConsumer())) {
-
-                                    @Override
-                                    protected void handleResponse(
-                                            final HttpRequest promise,
-                                            final Message<HttpResponse, Void> responseMessage) throws IOException, HttpException {
-                                        final HttpResponse response = responseMessage.getHead();
-                                        logResult(TestResult.OK, target, promise, response,
-                                                "pushed / " + response.getFirstHeader("server"));
-                                        countDownLatch.countDown();
-                                    }
+                            protected void handleResponse(
+                                    final HttpRequest promise,
+                                    final Message<HttpResponse, Void> responseMessage) throws IOException, HttpException {
+                                final HttpResponse response = responseMessage.getHead();
+                                logResult(TestResult.OK, target, promise, response,
+                                        "pushed / " + response.getFirstHeader("server"));
+                                countDownLatch.countDown();
+                            }
 
-                                    @Override
-                                    protected void handleError(
-                                            final HttpRequest promise,
-                                            final Exception cause) {
-                                        logResult(TestResult.NOK, target, promise, null, "(" + cause.getMessage() + ")");
-                                        countDownLatch.countDown();
-                                    }
-                                };
+                            @Override
+                            protected void handleError(
+                                    final HttpRequest promise,
+                                    final Exception cause) {
+                                logResult(TestResult.NOK, target, promise, null, "(" + cause.getMessage() + ")");
+                                countDownLatch.countDown();
                             }
                         },
                         null,
@@ -294,28 +285,28 @@ public class H2CompatibilityTest {
             System.out.println("*** httpbin.org HTTP/1.1 simple request execution ***");
 
             final List<Message<HttpRequest, AsyncEntityProducer>> requestMessages = Arrays.asList(
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.GET, target, "/headers"),
                             null),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.POST, target, "/anything"),
                             new StringAsyncEntityProducer("some important message", ContentType.TEXT_PLAIN)),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.PUT, target, "/anything"),
                             new StringAsyncEntityProducer("some important message", ContentType.TEXT_PLAIN)),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.GET, target, "/drip"),
                             null),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.GET, target, "/bytes/20000"),
                             null),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.GET, target, "/delay/2"),
                             null),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.POST, target, "/delay/2"),
                             new StringAsyncEntityProducer("some important message", ContentType.TEXT_PLAIN)),
-                    new Message<HttpRequest, AsyncEntityProducer>(
+                    new Message<>(
                             new BasicHttpRequest(Method.PUT, target, "/delay/2"),
                             new StringAsyncEntityProducer("some important message", ContentType.TEXT_PLAIN))
             );
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
index ed60fbd..ea8f3cd 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/AsyncServerBootstrapFilterTest.java
@@ -31,9 +31,7 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.concurrent.Future;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
-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;
@@ -47,18 +45,14 @@ import org.apache.hc.core5.http.impl.bootstrap.AsyncRequesterBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncDataConsumer;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.nio.AsyncFilterChain;
-import org.apache.hc.core5.http.nio.AsyncFilterHandler;
 import org.apache.hc.core5.http.nio.AsyncPushProducer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.UriPatternMatcher;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -89,29 +83,14 @@ public class AsyncServerBootstrapFilterTest {
         protected void before() throws Throwable {
             log.debug("Starting up test server");
             server = AsyncServerBootstrap.bootstrap()
-                    .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                    .setLookupRegistry(new UriPatternMatcher<>())
                     .setIOReactorConfig(
                             IOReactorConfig.custom()
                                     .setSoTimeout(TIMEOUT)
                                     .build())
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
-                    .addFilterLast("test-filter", new AsyncFilterHandler() {
-
-                        @Override
-                        public AsyncDataConsumer handle(
-                                final HttpRequest request,
-                                final EntityDetails entityDetails,
-                                final HttpContext context,
-                                final AsyncFilterChain.ResponseTrigger responseTrigger,
-                                final AsyncFilterChain chain) throws HttpException, IOException {
-                            return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
+                    .register("*", () -> new EchoHandler(2048))
+                    .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
+                            chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
 
                                 @Override
                                 public void sendInformation(
@@ -134,9 +113,7 @@ public class AsyncServerBootstrapFilterTest {
                                     responseTrigger.pushPromise(promise, responseProducer);
                                 }
 
-                            });
-                        }
-                    })
+                            }))
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
index b9b7cb6..20d27a0 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2AlpnTest.java
@@ -36,7 +36,6 @@ import java.util.Arrays;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
@@ -45,7 +44,6 @@ import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.ssl.BasicServerTlsStrategy;
@@ -121,14 +119,7 @@ public class H2AlpnTest {
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                     .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .create();
         }
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
index 8493256..086d593 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2IntegrationTest.java
@@ -60,8 +60,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.core5.function.Callback;
-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.EndpointDetails;
@@ -79,19 +77,17 @@ import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
-import org.apache.hc.core5.http.nio.AsyncPushConsumer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncResponseProducer;
 import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.CapacityChannel;
 import org.apache.hc.core5.http.nio.DataStreamChannel;
-import org.apache.hc.core5.http.nio.HandlerFactory;
 import org.apache.hc.core5.http.nio.ResponseChannel;
 import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.DigestingEntityProducer;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.AbstractAsyncPushHandler;
@@ -186,14 +182,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testSimpleGet() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -222,14 +211,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testSimpleHead() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -252,14 +234,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testLargeGet() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcdef", 5000);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcdef", 5000));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -302,14 +277,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testBasicPost() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -339,14 +307,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testLargePost() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new EchoHandler(2048);
-            }
-
-        });
+        server.register("*", () -> new EchoHandler(2048));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -373,14 +334,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testSlowResponseConsumer() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcd", 3);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcd", 3));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start(H2Config.custom().setInitialWindowSize(16).build());
@@ -432,14 +386,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testSlowRequestProducer() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new EchoHandler(2048);
-            }
-
-        });
+        server.register("*", () -> new EchoHandler(2048));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -488,62 +435,55 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testSlowResponseProducer() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new AbstractClassicServerExchangeHandler(2048, Executors.newSingleThreadExecutor()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractClassicServerExchangeHandler(2048, Executors.newSingleThreadExecutor()) {
-
-                    @Override
-                    protected void handle(
-                            final HttpRequest request,
-                            final InputStream requestStream,
-                            final HttpResponse response,
-                            final OutputStream responseStream,
-                            final HttpContext context) throws IOException, HttpException {
-
-                        if (!"/hello".equals(request.getPath())) {
-                            response.setCode(HttpStatus.SC_NOT_FOUND);
-                            return;
-                        }
-                        if (!Method.POST.name().equalsIgnoreCase(request.getMethod())) {
-                            response.setCode(HttpStatus.SC_NOT_IMPLEMENTED);
-                            return;
-                        }
-                        if (requestStream == null) {
-                            return;
-                        }
-                        final Header h1 = request.getFirstHeader(HttpHeaders.CONTENT_TYPE);
-                        final ContentType contentType = h1 != null ? ContentType.parse(h1.getValue()) : null;
-                        Charset charset = contentType != null ? contentType.getCharset() : null;
-                        if (charset == null) {
-                            charset = StandardCharsets.US_ASCII;
-                        }
-                        response.setCode(HttpStatus.SC_OK);
-                        response.setHeader(h1);
-                        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(requestStream, charset));
-                            final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(responseStream, charset))) {
-                            try {
-                                String l;
-                                int count = 0;
-                                while ((l = reader.readLine()) != null) {
-                                    writer.write(l);
-                                    writer.write("\r\n");
-                                    count++;
-                                    if (count % 500 == 0) {
-                                        Thread.sleep(500);
-                                    }
-                                }
-                                writer.flush();
-                            } catch (final InterruptedException ex) {
-                                Thread.currentThread().interrupt();
-                                throw new InterruptedIOException(ex.getMessage());
+            protected void handle(
+                    final HttpRequest request,
+                    final InputStream requestStream,
+                    final HttpResponse response,
+                    final OutputStream responseStream,
+                    final HttpContext context) throws IOException, HttpException {
+
+                if (!"/hello".equals(request.getPath())) {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                    return;
+                }
+                if (!Method.POST.name().equalsIgnoreCase(request.getMethod())) {
+                    response.setCode(HttpStatus.SC_NOT_IMPLEMENTED);
+                    return;
+                }
+                if (requestStream == null) {
+                    return;
+                }
+                final Header h1 = request.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+                final ContentType contentType = h1 != null ? ContentType.parse(h1.getValue()) : null;
+                Charset charset = contentType != null ? contentType.getCharset() : null;
+                if (charset == null) {
+                    charset = StandardCharsets.US_ASCII;
+                }
+                response.setCode(HttpStatus.SC_OK);
+                response.setHeader(h1);
+                try (final BufferedReader reader = new BufferedReader(new InputStreamReader(requestStream, charset));
+                    final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(responseStream, charset))) {
+                    try {
+                        String l;
+                        int count = 0;
+                        while ((l = reader.readLine()) != null) {
+                            writer.write(l);
+                            writer.write("\r\n");
+                            count++;
+                            if (count % 500 == 0) {
+                                Thread.sleep(500);
                             }
                         }
+                        writer.flush();
+                    } catch (final InterruptedException ex) {
+                        Thread.currentThread().interrupt();
+                        throw new InterruptedIOException(ex.getMessage());
                     }
-                };
+                }
             }
-
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -575,28 +515,21 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
     @Test
     public void testPush() throws Exception {
         final InetSocketAddress serverEndpoint = server.start();
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/hello", () -> new MessageExchangeHandler<Void>(new DiscardingEntityConsumer<>()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new MessageExchangeHandler<Void>(new NoopEntityConsumer()) {
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, Void> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        responseTrigger.pushPromise(
-                                new BasicHttpRequest(Method.GET, createRequestURI(serverEndpoint, "/stuff")),
-                                context,
-                                new BasicPushProducer(new MultiLineEntityProducer("Pushing lots of stuff", 500)));
-                        responseTrigger.submitResponse(
-                                AsyncResponseBuilder.create(HttpStatus.SC_OK).setEntity("Hi there", ContentType.TEXT_PLAIN).build(),
-                                context);
-                    }
-                };
+            protected void handle(
+                    final Message<HttpRequest, Void> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                responseTrigger.pushPromise(
+                        new BasicHttpRequest(Method.GET, createRequestURI(serverEndpoint, "/stuff")),
+                        context,
+                        new BasicPushProducer(new MultiLineEntityProducer("Pushing lots of stuff", 500)));
+                responseTrigger.submitResponse(
+                        AsyncResponseBuilder.create(HttpStatus.SC_OK).setEntity("Hi there", ContentType.TEXT_PLAIN).build(),
+                        context);
             }
-
         });
 
         client.start(H2Config.custom().setPushEnabled(true).build());
@@ -610,27 +543,20 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
         final Future<Message<HttpResponse, String>> future1 = streamEndpoint.execute(
                 new BasicRequestProducer(Method.GET, createRequestURI(serverEndpoint, "/hello")),
                 new BasicResponseConsumer<>(new StringAsyncEntityConsumer()),
-                new HandlerFactory<AsyncPushConsumer>() {
+                (request, context) -> new AbstractAsyncPushHandler<Message<HttpResponse, String>>(new BasicResponseConsumer<>(new StringAsyncEntityConsumer())) {
 
                     @Override
-                    public AsyncPushConsumer create(
-                            final HttpRequest request, final HttpContext context) throws HttpException {
-                        return new AbstractAsyncPushHandler<Message<HttpResponse, String>>(new BasicResponseConsumer<>(new StringAsyncEntityConsumer())) {
-
-                            @Override
-                            protected void handleResponse(
-                                    final HttpRequest promise,
-                                    final Message<HttpResponse, String> responseMessage) throws IOException, HttpException {
-                                try {
-                                    pushMessageQueue.put(responseMessage);
-                                } catch (final InterruptedException ex) {
-                                    Thread.currentThread().interrupt();
-                                    throw new InterruptedIOException(ex.getMessage());
-                                }
-                            }
-
-                        };
+                    protected void handleResponse(
+                            final HttpRequest promise,
+                            final Message<HttpResponse, String> responseMessage) throws IOException, HttpException {
+                        try {
+                            pushMessageQueue.put(responseMessage);
+                        } catch (final InterruptedException ex) {
+                            Thread.currentThread().interrupt();
+                            throw new InterruptedIOException(ex.getMessage());
+                        }
                     }
+
                 },
                 null,
                 null);
@@ -662,7 +588,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
             @Override
             public AsyncServerExchangeHandler get() {
-                return new MessageExchangeHandler<Void>(new NoopEntityConsumer()) {
+                return new MessageExchangeHandler<Void>(new DiscardingEntityConsumer<>()) {
 
                     @Override
                     protected void handle(
@@ -731,14 +657,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testExcessOfConcurrentStreams() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcdef", 2000);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcdef", 2000));
         final InetSocketAddress serverEndpoint = server.start(H2Config.custom().setMaxConcurrentStreams(20).build());
 
         client.start(H2Config.custom().setMaxConcurrentStreams(20).build());
@@ -751,7 +670,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
             final HttpRequest request1 = new BasicHttpRequest(Method.GET, createRequestURI(serverEndpoint, "/"));
             final Future<Message<HttpResponse, Void>> future = streamEndpoint.execute(
                     new BasicRequestProducer(request1, null),
-                    new BasicResponseConsumer<>(new NoopEntityConsumer()), null);
+                    new BasicResponseConsumer<>(new DiscardingEntityConsumer<>()), null);
             queue.add(future);
         }
 
@@ -767,42 +686,27 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testExpectationFailed() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
+            protected void handle(
+                    final Message<HttpRequest, String> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
 
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
-
-                    }
-                };
             }
-
         });
-        final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+        final InetSocketAddress serverEndpoint = server.start(null, handler -> new BasicAsyncServerExpectationDecorator(handler) {
 
             @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-
-                return new BasicAsyncServerExpectationDecorator(handler) {
-
-                    @Override
-                    protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
-                        final Header h = request.getFirstHeader("password");
-                        if (h != null && "secret".equals(h.getValue())) {
-                            return null;
-                        } else {
-                            return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
-                        }
-                    }
-                };
-
+            protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
+                final Header h = request.getFirstHeader("password");
+                if (h != null && "secret".equals(h.getValue())) {
+                    return null;
+                } else {
+                    return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
+                }
             }
         }, H2Config.DEFAULT);
 
@@ -919,33 +823,26 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testMessageWithTrailers() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/hello", () -> new AbstractServerExchangeHandler<Message<HttpRequest, String>>() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractServerExchangeHandler<Message<HttpRequest, String>>() {
-
-                    @Override
-                    protected AsyncRequestConsumer<Message<HttpRequest, String>> supplyConsumer(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final HttpContext context) throws HttpException {
-                        return new BasicRequestConsumer<>(entityDetails != null ? new StringAsyncEntityConsumer() : null);
-                    }
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> requestMessage,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws HttpException, IOException {
-                        responseTrigger.submitResponse(new BasicResponseProducer(
-                                HttpStatus.SC_OK,
-                                new DigestingEntityProducer("MD5",
-                                        new StringAsyncEntityProducer("Hello back with some trailers"))), context);
-                    }
-                };
+            protected AsyncRequestConsumer<Message<HttpRequest, String>> supplyConsumer(
+                    final HttpRequest request,
+                    final EntityDetails entityDetails,
+                    final HttpContext context) throws HttpException {
+                return new BasicRequestConsumer<>(entityDetails != null ? new StringAsyncEntityConsumer() : null);
             }
 
+            @Override
+            protected void handle(
+                    final Message<HttpRequest, String> requestMessage,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws HttpException, IOException {
+                responseTrigger.submitResponse(new BasicResponseProducer(
+                        HttpStatus.SC_OK,
+                        new DigestingEntityProducer("MD5",
+                                new StringAsyncEntityProducer("Hello back with some trailers"))), context);
+            }
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -981,14 +878,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testConnectionPing() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -1003,16 +893,11 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
             streamEndpoint.execute(
                     new BasicRequestProducer(Method.GET, createRequestURI(serverEndpoint, "/hello")),
                     new BasicResponseConsumer<>(new StringAsyncEntityConsumer()), null);
-            streamEndpoint.execute(new PingCommand(new BasicPingHandler(new Callback<Boolean>() {
-
-                @Override
-                public void execute(final Boolean result) {
-                    if (result) {
-                        count.incrementAndGet();
-                    }
-                    latch.countDown();
+            streamEndpoint.execute(new PingCommand(new BasicPingHandler(result -> {
+                if (result) {
+                    count.incrementAndGet();
                 }
-
+                latch.countDown();
             })), Command.Priority.NORMAL);
 
         }
@@ -1022,14 +907,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testRequestWithInvalidConnectionHeader() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -1058,14 +936,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testHeaderTooLarge() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start(H2Config.custom()
                 .setMaxHeaderListSize(100)
                 .build());
@@ -1091,14 +962,7 @@ public class H2IntegrationTest extends InternalH2ServerTestBase {
 
     @Test
     public void testHeaderTooLargePost() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start(H2Config.custom()
                 .setMaxHeaderListSize(100)
                 .build());
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
index d97b8f5..624e66f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ProtocolNegotiationTest.java
@@ -32,7 +32,6 @@ import java.util.concurrent.Future;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
@@ -44,7 +43,6 @@ import org.apache.hc.core5.http.ProtocolVersion;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
@@ -95,14 +93,7 @@ public class H2ProtocolNegotiationTest {
                                     .setSoTimeout(TIMEOUT)
                                     .build())
                     .setTlsStrategy(new H2ServerTlsStrategy(SSLTestContexts.createServerSSLContext()))
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .setStreamListener(LoggingH2StreamListener.INSTANCE)
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndMultiplexingRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndMultiplexingRequesterTest.java
index 325e6ea..c048bd0 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndMultiplexingRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndMultiplexingRequesterTest.java
@@ -38,7 +38,6 @@ import java.util.concurrent.Future;
 
 import org.apache.hc.core5.concurrent.Cancellable;
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
@@ -47,7 +46,6 @@ import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.BasicClientExchangeHandler;
@@ -118,14 +116,7 @@ public class H2ServerAndMultiplexingRequesterTest {
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                     .setStreamListener(LoggingH2StreamListener.INSTANCE)
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .create();
         }
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndRequesterTest.java
index f0e789d..c0e7977 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerAndRequesterTest.java
@@ -34,7 +34,6 @@ import java.util.LinkedList;
 import java.util.Queue;
 import java.util.concurrent.Future;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
@@ -45,7 +44,6 @@ import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
@@ -105,7 +103,7 @@ public class H2ServerAndRequesterTest {
         protected void before() throws Throwable {
             log.debug("Starting up test server");
             server = H2ServerBootstrap.bootstrap()
-                    .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                    .setLookupRegistry(new UriPatternMatcher<>())
                     .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
                     .setIOReactorConfig(
                             IOReactorConfig.custom()
@@ -118,14 +116,7 @@ public class H2ServerAndRequesterTest {
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                     .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .create();
         }
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
index e629fb0..73dc943 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2ServerBootstrapFiltersTest.java
@@ -31,9 +31,7 @@ import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.util.concurrent.Future;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
-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;
@@ -45,17 +43,13 @@ import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncDataConsumer;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.nio.AsyncFilterChain;
-import org.apache.hc.core5.http.nio.AsyncFilterHandler;
 import org.apache.hc.core5.http.nio.AsyncPushProducer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.UriPatternMatcher;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
@@ -90,7 +84,7 @@ public class H2ServerBootstrapFiltersTest {
         protected void before() throws Throwable {
             log.debug("Starting up test server");
             server = H2ServerBootstrap.bootstrap()
-                    .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                    .setLookupRegistry(new UriPatternMatcher<>())
                     .setVersionPolicy(HttpVersionPolicy.NEGOTIATE)
                     .setIOReactorConfig(
                             IOReactorConfig.custom()
@@ -101,24 +95,9 @@ public class H2ServerBootstrapFiltersTest {
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                     .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
-                    .addFilterLast("test-filter", new AsyncFilterHandler() {
-
-                        @Override
-                        public AsyncDataConsumer handle(
-                                final HttpRequest request,
-                                final EntityDetails entityDetails,
-                                final HttpContext context,
-                                final AsyncFilterChain.ResponseTrigger responseTrigger,
-                                final AsyncFilterChain chain) throws HttpException, IOException {
-                            return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
+                    .register("*", () -> new EchoHandler(2048))
+                    .addFilterLast("test-filter", (request, entityDetails, context, responseTrigger, chain) ->
+                            chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
 
                                 @Override
                                 public void sendInformation(
@@ -141,9 +120,7 @@ public class H2ServerBootstrapFiltersTest {
                                     responseTrigger.pushPromise(promise, responseProducer);
                                 }
 
-                            });
-                        }
-                    })
+                            }))
                     .create();
         }
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
index e95c460..0d2291c 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/H2TLSIntegrationTest.java
@@ -33,12 +33,9 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
 
-import javax.net.ssl.SSLEngine;
-import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
 import javax.net.ssl.SSLSession;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.HttpResponse;
@@ -50,7 +47,6 @@ import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
@@ -61,12 +57,8 @@ import org.apache.hc.core5.http.protocol.UriPatternMatcher;
 import org.apache.hc.core5.http.ssl.TLS;
 import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
 import org.apache.hc.core5.io.CloseMode;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.IOReactorConfig;
 import org.apache.hc.core5.reactor.ListenerEndpoint;
-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.ssl.SSLContexts;
 import org.apache.hc.core5.testing.SSLTestContexts;
 import org.apache.hc.core5.testing.classic.LoggingConnPoolListener;
@@ -119,7 +111,7 @@ public class H2TLSIntegrationTest {
     @Test
     public void testTLSSuccess() throws Exception {
         server = AsyncServerBootstrap.bootstrap()
-                .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                .setLookupRegistry(new UriPatternMatcher<>())
                 .setIOReactorConfig(
                         IOReactorConfig.custom()
                                 .setSoTimeout(TIMEOUT)
@@ -129,14 +121,7 @@ public class H2TLSIntegrationTest {
                 .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                 .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                 .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new EchoHandler(2048);
-                    }
-
-                })
+                .register("*", () -> new EchoHandler(2048))
                 .create();
         server.start();
 
@@ -148,15 +133,9 @@ public class H2TLSIntegrationTest {
                         .build())
                 .setTlsStrategy(new BasicClientTlsStrategy(
                         SSLTestContexts.createClientSSLContext(),
-                        new SSLSessionVerifier() {
-
-                            @Override
-                            public TlsDetails verify(
-                                    final NamedEndpoint endpoint, final SSLEngine sslEngine) throws SSLException {
-                                sslSessionRef.set(sslEngine.getSession());
-                                return null;
-                            }
-
+                        (endpoint, sslEngine) -> {
+                            sslSessionRef.set(sslEngine.getSession());
+                            return null;
                         }))
                 .setStreamListener(LoggingHttp1StreamListener.INSTANCE_CLIENT)
                 .setConnPoolListener(LoggingConnPoolListener.INSTANCE)
@@ -193,7 +172,7 @@ public class H2TLSIntegrationTest {
     @Test
     public void testTLSTrustFailure() throws Exception {
         server = AsyncServerBootstrap.bootstrap()
-                .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                .setLookupRegistry(new UriPatternMatcher<>())
                 .setIOReactorConfig(
                         IOReactorConfig.custom()
                                 .setSoTimeout(TIMEOUT)
@@ -203,14 +182,7 @@ public class H2TLSIntegrationTest {
                 .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                 .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                 .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new EchoHandler(2048);
-                    }
-
-                })
+                .register("*", () -> new EchoHandler(2048))
                 .create();
         server.start();
 
@@ -249,33 +221,20 @@ public class H2TLSIntegrationTest {
     @Test
     public void testTLSClientAuthFailure() throws Exception {
         server = AsyncServerBootstrap.bootstrap()
-                .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                .setLookupRegistry(new UriPatternMatcher<>())
                 .setIOReactorConfig(
                         IOReactorConfig.custom()
                                 .setSoTimeout(TIMEOUT)
                                 .build())
                 .setTlsStrategy(new BasicServerTlsStrategy(
                         SSLTestContexts.createServerSSLContext(),
-                        new SSLSessionInitializer() {
-
-                            @Override
-                            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                                sslEngine.setNeedClientAuth(true);
-                            }
-                        },
+                        (endpoint, sslEngine) -> sslEngine.setNeedClientAuth(true),
                         null))
                 .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
                 .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                 .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                 .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new EchoHandler(2048);
-                    }
-
-                })
+                .register("*", () -> new EchoHandler(2048))
                 .create();
         server.start();
 
@@ -314,33 +273,20 @@ public class H2TLSIntegrationTest {
     @Test
     public void testSSLDisabledByDefault() throws Exception {
         server = AsyncServerBootstrap.bootstrap()
-                .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                .setLookupRegistry(new UriPatternMatcher<>())
                 .setIOReactorConfig(
                         IOReactorConfig.custom()
                                 .setSoTimeout(TIMEOUT)
                                 .build())
                 .setTlsStrategy(new BasicServerTlsStrategy(
                         SSLTestContexts.createServerSSLContext(),
-                        new SSLSessionInitializer() {
-
-                            @Override
-                            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                                sslEngine.setEnabledProtocols(new String[]{"SSLv3"});
-                            }
-                        },
+                        (endpoint, sslEngine) -> sslEngine.setEnabledProtocols(new String[]{"SSLv3"}),
                         null))
                 .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
                 .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                 .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                 .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new EchoHandler(2048);
-                    }
-
-                })
+                .register("*", () -> new EchoHandler(2048))
                 .create();
         server.start();
 
@@ -411,33 +357,20 @@ public class H2TLSIntegrationTest {
 
         for (final String cipherSuite : weakCiphersSuites) {
             server = AsyncServerBootstrap.bootstrap()
-                    .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                    .setLookupRegistry(new UriPatternMatcher<>())
                     .setIOReactorConfig(
                             IOReactorConfig.custom()
                                     .setSoTimeout(TIMEOUT)
                                     .build())
                     .setTlsStrategy(new BasicServerTlsStrategy(
                             SSLTestContexts.createServerSSLContext(),
-                            new SSLSessionInitializer() {
-
-                                @Override
-                                public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                                    sslEngine.setEnabledCipherSuites(new String[]{cipherSuite});
-                                }
-                            },
+                            (endpoint, sslEngine) -> sslEngine.setEnabledCipherSuites(new String[]{cipherSuite}),
                             null))
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
                     .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                     .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                     .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .create();
             try {
                 server.start();
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
index 9b779cc..29e600e 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1AuthenticationTest.java
@@ -34,7 +34,6 @@ import java.util.Collection;
 import java.util.Random;
 import java.util.concurrent.Future;
 
-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;
@@ -53,7 +52,6 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AbstractAsyncServerAuthFilter;
@@ -110,14 +108,7 @@ public class Http1AuthenticationTest {
                             IOReactorConfig.custom()
                                     .setSoTimeout(TIMEOUT)
                                     .build())
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                        @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
-                        }
-
-                    })
+                    .register("*", () -> new EchoHandler(2048))
                     .replaceFilter(StandardFilter.EXPECT_CONTINUE.name(), new AbstractAsyncServerAuthFilter<String>(respondImmediately) {
 
                         @Override
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
index 8c9a20e..cd0d874 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1IntegrationTest.java
@@ -58,8 +58,6 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.core5.function.Decorator;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.ContentLengthStrategy;
 import org.apache.hc.core5.http.ContentType;
@@ -193,14 +191,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleGet() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -224,14 +215,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleGetConnectionClose() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -258,14 +242,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleGetIdentityTransfer() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final HttpProcessor httpProcessor = new DefaultHttpProcessor(new RequestValidateHost());
         final InetSocketAddress serverEndpoint = server.start(httpProcessor, Http1Config.DEFAULT);
 
@@ -287,14 +264,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleGetsPipelined() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -322,14 +292,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testLargeGet() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcdef", 5000);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcdef", 5000));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -372,14 +335,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testLargeGetsPipelined() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcdef", 2000);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcdef", 2000));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -411,14 +367,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testBasicPost() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -443,14 +392,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testBasicPostPipelined() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -479,14 +421,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testHttp10Post() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -512,14 +447,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testNoEntityPost() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -544,14 +472,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testLargePost() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new EchoHandler(2048);
-            }
-
-        });
+        server.register("*", () -> new EchoHandler(2048));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -580,14 +501,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testPostsPipelinedLargeResponse() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcdef", 2000);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcdef", 2000));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -621,14 +535,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testLargePostsPipelined() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new EchoHandler(2048);
-            }
-
-        });
+        server.register("*", () -> new EchoHandler(2048));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -661,14 +568,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleHead() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -691,14 +591,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSimpleHeadConnectionClose() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -724,14 +617,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testHeadPipelined() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -758,42 +644,27 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testExpectationFailed() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
+            protected void handle(
+                    final Message<HttpRequest, String> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
 
-                    }
-                };
             }
-
         });
-        final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+        final InetSocketAddress serverEndpoint = server.start(null, handler -> new BasicAsyncServerExpectationDecorator(handler) {
 
             @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-
-                return new BasicAsyncServerExpectationDecorator(handler) {
-
-                    @Override
-                    protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
-                        final Header h = request.getFirstHeader("password");
-                        if (h != null && "secret".equals(h.getValue())) {
-                            return null;
-                        } else {
-                            return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
-                        }
-                    }
-                };
-
+            protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
+                final Header h = request.getFirstHeader("password");
+                if (h != null && "secret".equals(h.getValue())) {
+                    return null;
+                } else {
+                    return new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
+                }
             }
         }, Http1Config.DEFAULT);
 
@@ -860,44 +731,29 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testExpectationFailedCloseConnection() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
+            protected void handle(
+                    final Message<HttpRequest, String> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                responseTrigger.submitResponse(new BasicResponseProducer(HttpStatus.SC_OK, "All is well"), context);
 
-                    }
-                };
             }
-
         });
-        final InetSocketAddress serverEndpoint = server.start(null, new Decorator<AsyncServerExchangeHandler>() {
+        final InetSocketAddress serverEndpoint = server.start(null, handler -> new BasicAsyncServerExpectationDecorator(handler) {
 
             @Override
-            public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-
-                return new BasicAsyncServerExpectationDecorator(handler) {
-
-                    @Override
-                    protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
-                        final Header h = request.getFirstHeader("password");
-                        if (h != null && "secret".equals(h.getValue())) {
-                            return null;
-                        } else {
-                            final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
-                            response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-                            return new BasicResponseProducer(response, "You shall not pass");
-                        }
-                    }
-                };
-
+            protected AsyncResponseProducer verify(final HttpRequest request, final HttpContext context) throws IOException, HttpException {
+                final Header h = request.getFirstHeader("password");
+                if (h != null && "secret".equals(h.getValue())) {
+                    return null;
+                } else {
+                    final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_UNAUTHORIZED);
+                    response.addHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                    return new BasicResponseProducer(response, "You shall not pass");
+                }
             }
         }, Http1Config.DEFAULT);
 
@@ -926,84 +782,74 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testDelayedExpectationVerification() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new AsyncServerExchangeHandler() {
 
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncServerExchangeHandler() {
-
-                    private final Random random = new Random(System.currentTimeMillis());
-                    private final AsyncEntityProducer entityProducer = AsyncEntityProducers.create(
-                            "All is well");
+            private final Random random = new Random(System.currentTimeMillis());
+            private final AsyncEntityProducer entityProducer = AsyncEntityProducers.create(
+                    "All is well");
 
-                    @Override
-                    public void handleRequest(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final ResponseChannel responseChannel,
-                            final HttpContext context) throws HttpException, IOException {
-
-                        Executors.newSingleThreadExecutor().execute(new Runnable() {
-                            @Override
-                            public void run() {
-                                try {
-                                    if (entityDetails != null) {
-                                        final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
-                                        if (h != null && HeaderElements.CONTINUE.equalsIgnoreCase(h.getValue())) {
-                                            Thread.sleep(random.nextInt(1000));
-                                            responseChannel.sendInformation(new BasicHttpResponse(HttpStatus.SC_CONTINUE), context);
-                                        }
-                                        final HttpResponse response = new BasicHttpResponse(200);
-                                        synchronized (entityProducer) {
-                                            responseChannel.sendResponse(response, entityProducer, context);
-                                        }
-                                    }
-                                } catch (final Exception ignore) {
-                                    // ignore
-                                }
+            @Override
+            public void handleRequest(
+                    final HttpRequest request,
+                    final EntityDetails entityDetails,
+                    final ResponseChannel responseChannel,
+                    final HttpContext context) throws HttpException, IOException {
+
+                Executors.newSingleThreadExecutor().execute(() -> {
+                    try {
+                        if (entityDetails != null) {
+                            final Header h = request.getFirstHeader(HttpHeaders.EXPECT);
+                            if (h != null && HeaderElements.CONTINUE.equalsIgnoreCase(h.getValue())) {
+                                Thread.sleep(random.nextInt(1000));
+                                responseChannel.sendInformation(new BasicHttpResponse(HttpStatus.SC_CONTINUE), context);
                             }
-                        });
-
-                    }
-
-                    @Override
-                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                        capacityChannel.update(Integer.MAX_VALUE);
+                            final HttpResponse response = new BasicHttpResponse(200);
+                            synchronized (entityProducer) {
+                                responseChannel.sendResponse(response, entityProducer, context);
+                            }
+                        }
+                    } catch (final Exception ignore) {
+                        // ignore
                     }
+                });
 
-                    @Override
-                    public void consume(final ByteBuffer src) throws IOException {
-                    }
+            }
 
-                    @Override
-                    public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                    }
+            @Override
+            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                capacityChannel.update(Integer.MAX_VALUE);
+            }
 
-                    @Override
-                    public int available() {
-                        synchronized (entityProducer) {
-                            return entityProducer.available();
-                        }
-                    }
+            @Override
+            public void consume(final ByteBuffer src) throws IOException {
+            }
 
-                    @Override
-                    public void produce(final DataStreamChannel channel) throws IOException {
-                        synchronized (entityProducer) {
-                            entityProducer.produce(channel);
-                        }
-                    }
+            @Override
+            public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+            }
 
-                    @Override
-                    public void failed(final Exception cause) {
-                    }
+            @Override
+            public int available() {
+                synchronized (entityProducer) {
+                    return entityProducer.available();
+                }
+            }
 
-                    @Override
-                    public void releaseResources() {
-                    }
+            @Override
+            public void produce(final DataStreamChannel channel) throws IOException {
+                synchronized (entityProducer) {
+                    entityProducer.produce(channel);
+                }
+            }
 
-                };
+            @Override
+            public void failed(final Exception cause) {
+            }
 
+            @Override
+            public void releaseResources() {
             }
+
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1032,66 +878,59 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testPrematureResponse() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncServerExchangeHandler() {
+        server.register("*", () -> new AsyncServerExchangeHandler() {
 
-                    private final AtomicReference<AsyncResponseProducer> responseProducer = new AtomicReference<>(null);
+            private final AtomicReference<AsyncResponseProducer> responseProducer = new AtomicReference<>(null);
 
-                    @Override
-                    public void handleRequest(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final ResponseChannel responseChannel,
-                            final HttpContext context) throws HttpException, IOException {
-                        final AsyncResponseProducer producer;
-                        final Header h = request.getFirstHeader("password");
-                        if (h != null && "secret".equals(h.getValue())) {
-                            producer = new BasicResponseProducer(HttpStatus.SC_OK, "All is well");
-                        } else {
-                            producer = new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
-                        }
-                        responseProducer.set(producer);
-                        producer.sendResponse(responseChannel, context);
-                    }
-
-                    @Override
-                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                        capacityChannel.update(Integer.MAX_VALUE);
-                    }
+            @Override
+            public void handleRequest(
+                    final HttpRequest request,
+                    final EntityDetails entityDetails,
+                    final ResponseChannel responseChannel,
+                    final HttpContext context) throws HttpException, IOException {
+                final AsyncResponseProducer producer;
+                final Header h = request.getFirstHeader("password");
+                if (h != null && "secret".equals(h.getValue())) {
+                    producer = new BasicResponseProducer(HttpStatus.SC_OK, "All is well");
+                } else {
+                    producer = new BasicResponseProducer(HttpStatus.SC_UNAUTHORIZED, "You shall not pass");
+                }
+                responseProducer.set(producer);
+                producer.sendResponse(responseChannel, context);
+            }
 
-                    @Override
-                    public void consume(final ByteBuffer src) throws IOException {
-                    }
+            @Override
+            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                capacityChannel.update(Integer.MAX_VALUE);
+            }
 
-                    @Override
-                    public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                    }
+            @Override
+            public void consume(final ByteBuffer src) throws IOException {
+            }
 
-                    @Override
-                    public int available() {
-                        final AsyncResponseProducer producer = responseProducer.get();
-                        return producer.available();
-                    }
+            @Override
+            public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+            }
 
-                    @Override
-                    public void produce(final DataStreamChannel channel) throws IOException {
-                        final AsyncResponseProducer producer = responseProducer.get();
-                        producer.produce(channel);
-                    }
+            @Override
+            public int available() {
+                final AsyncResponseProducer producer = responseProducer.get();
+                return producer.available();
+            }
 
-                    @Override
-                    public void failed(final Exception cause) {
-                    }
+            @Override
+            public void produce(final DataStreamChannel channel) throws IOException {
+                final AsyncResponseProducer producer = responseProducer.get();
+                producer.produce(channel);
+            }
 
-                    @Override
-                    public void releaseResources() {
-                    }
-                };
+            @Override
+            public void failed(final Exception cause) {
             }
 
+            @Override
+            public void releaseResources() {
+            }
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1133,14 +972,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSlowResponseConsumer() throws Exception {
-        server.register("/", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new MultiLineResponseHandler("0123456789abcd", 100);
-            }
-
-        });
+        server.register("/", () -> new MultiLineResponseHandler("0123456789abcd", 100));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start(Http1Config.custom().setBufferSize(256).build());
@@ -1194,14 +1026,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSlowRequestProducer() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new EchoHandler(2048);
-            }
-
-        });
+        server.register("*", () -> new EchoHandler(2048));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -1250,62 +1075,55 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testSlowResponseProducer() throws Exception {
-        server.register("*", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("*", () -> new AbstractClassicServerExchangeHandler(2048, Executors.newSingleThreadExecutor()) {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractClassicServerExchangeHandler(2048, Executors.newSingleThreadExecutor()) {
-
-                    @Override
-                    protected void handle(
-                            final HttpRequest request,
-                            final InputStream requestStream,
-                            final HttpResponse response,
-                            final OutputStream responseStream,
-                            final HttpContext context) throws IOException, HttpException {
-
-                        if (!"/hello".equals(request.getPath())) {
-                            response.setCode(HttpStatus.SC_NOT_FOUND);
-                            return;
-                        }
-                        if (!Method.POST.name().equalsIgnoreCase(request.getMethod())) {
-                            response.setCode(HttpStatus.SC_NOT_IMPLEMENTED);
-                            return;
-                        }
-                        if (requestStream == null) {
-                            return;
-                        }
-                        final Header h1 = request.getFirstHeader(HttpHeaders.CONTENT_TYPE);
-                        final ContentType contentType = h1 != null ? ContentType.parse(h1.getValue()) : null;
-                        Charset charset = contentType != null ? contentType.getCharset() : null;
-                        if (charset == null) {
-                            charset = StandardCharsets.US_ASCII;
-                        }
-                        response.setCode(HttpStatus.SC_OK);
-                        response.setHeader(h1);
-                        try (final BufferedReader reader = new BufferedReader(new InputStreamReader(requestStream, charset));
-                             final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(responseStream, charset))) {
-                            try {
-                                String l;
-                                int count = 0;
-                                while ((l = reader.readLine()) != null) {
-                                    writer.write(l);
-                                    writer.write("\r\n");
-                                    count++;
-                                    if (count % 500 == 0) {
-                                        Thread.sleep(500);
-                                    }
-                                }
-                                writer.flush();
-                            } catch (final InterruptedException ex) {
-                                Thread.currentThread().interrupt();
-                                throw new InterruptedIOException(ex.getMessage());
+            protected void handle(
+                    final HttpRequest request,
+                    final InputStream requestStream,
+                    final HttpResponse response,
+                    final OutputStream responseStream,
+                    final HttpContext context) throws IOException, HttpException {
+
+                if (!"/hello".equals(request.getPath())) {
+                    response.setCode(HttpStatus.SC_NOT_FOUND);
+                    return;
+                }
+                if (!Method.POST.name().equalsIgnoreCase(request.getMethod())) {
+                    response.setCode(HttpStatus.SC_NOT_IMPLEMENTED);
+                    return;
+                }
+                if (requestStream == null) {
+                    return;
+                }
+                final Header h1 = request.getFirstHeader(HttpHeaders.CONTENT_TYPE);
+                final ContentType contentType = h1 != null ? ContentType.parse(h1.getValue()) : null;
+                Charset charset = contentType != null ? contentType.getCharset() : null;
+                if (charset == null) {
+                    charset = StandardCharsets.US_ASCII;
+                }
+                response.setCode(HttpStatus.SC_OK);
+                response.setHeader(h1);
+                try (final BufferedReader reader = new BufferedReader(new InputStreamReader(requestStream, charset));
+                     final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(responseStream, charset))) {
+                    try {
+                        String l;
+                        int count = 0;
+                        while ((l = reader.readLine()) != null) {
+                            writer.write(l);
+                            writer.write("\r\n");
+                            count++;
+                            if (count % 500 == 0) {
+                                Thread.sleep(500);
                             }
                         }
+                        writer.flush();
+                    } catch (final InterruptedException ex) {
+                        Thread.currentThread().interrupt();
+                        throw new InterruptedIOException(ex.getMessage());
                     }
-                };
+                }
             }
-
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1334,14 +1152,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testPipelinedConnectionClose() throws Exception {
-        server.register("/hello*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello*", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -1401,14 +1212,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testPipelinedInvalidRequest() throws Exception {
-        server.register("/hello*", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi back");
-            }
-
-        });
+        server.register("/hello*", () -> new SingleLineResponseHandler("Hi back"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -1503,24 +1307,15 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
     public void testTruncatedChunk() throws Exception {
         final InetSocketAddress serverEndpoint = server.start(new InternalServerHttp1EventHandlerFactory(
                 HttpProcessors.server(),
-                new HandlerFactory<AsyncServerExchangeHandler>() {
+                (request, context) -> new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
 
                     @Override
-                    public AsyncServerExchangeHandler create(
-                            final HttpRequest request,
-                            final HttpContext context) throws HttpException {
-                        return new MessageExchangeHandler<String>(new StringAsyncEntityConsumer()) {
-
-                            @Override
-                            protected void handle(
-                                    final Message<HttpRequest, String> request,
-                                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                                    final HttpContext context) throws IOException, HttpException {
-                                responseTrigger.submitResponse(
-                                        new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")), context);
-                            }
-
-                        };
+                    protected void handle(
+                            final Message<HttpRequest, String> request,
+                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                            final HttpContext context) throws IOException, HttpException {
+                        responseTrigger.submitResponse(
+                                new BasicResponseProducer(new StringAsyncEntityProducer("useful stuff")), context);
                     }
 
                 },
@@ -1595,22 +1390,15 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testExceptionInHandler() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there") {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there") {
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        throw new HttpException("Boom");
-                    }
-                };
+            protected void handle(
+                    final Message<HttpRequest, String> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                throw new HttpException("Boom");
             }
-
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1654,23 +1442,16 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testResponseNoContent() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there") {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there") {
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> request,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws IOException, HttpException {
-                        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT);
-                        responseTrigger.submitResponse(new BasicResponseProducer(response), context);
-                    }
-                };
+            protected void handle(
+                    final Message<HttpRequest, String> request,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws IOException, HttpException {
+                final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_NO_CONTENT);
+                responseTrigger.submitResponse(new BasicResponseProducer(response), context);
             }
-
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1692,14 +1473,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testAbsentHostHeader() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start(new DefaultHttpProcessor(new RequestContent(), new RequestConnControl()), Http1Config.DEFAULT);
@@ -1735,33 +1509,26 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testMessageWithTrailers() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
+        server.register("/hello", () -> new AbstractServerExchangeHandler<Message<HttpRequest, String>>() {
 
             @Override
-            public AsyncServerExchangeHandler get() {
-                return new AbstractServerExchangeHandler<Message<HttpRequest, String>>() {
-
-                    @Override
-                    protected AsyncRequestConsumer<Message<HttpRequest, String>> supplyConsumer(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final HttpContext context) throws HttpException {
-                        return new BasicRequestConsumer<>(entityDetails != null ? new StringAsyncEntityConsumer() : null);
-                    }
-
-                    @Override
-                    protected void handle(
-                            final Message<HttpRequest, String> requestMessage,
-                            final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
-                            final HttpContext context) throws HttpException, IOException {
-                        responseTrigger.submitResponse(new BasicResponseProducer(
-                                HttpStatus.SC_OK,
-                                new DigestingEntityProducer("MD5",
-                                        new StringAsyncEntityProducer("Hello back with some trailers"))), context);
-                    }
-                };
+            protected AsyncRequestConsumer<Message<HttpRequest, String>> supplyConsumer(
+                    final HttpRequest request,
+                    final EntityDetails entityDetails,
+                    final HttpContext context) throws HttpException {
+                return new BasicRequestConsumer<>(entityDetails != null ? new StringAsyncEntityConsumer() : null);
             }
 
+            @Override
+            protected void handle(
+                    final Message<HttpRequest, String> requestMessage,
+                    final AsyncServerRequestHandler.ResponseTrigger responseTrigger,
+                    final HttpContext context) throws HttpException, IOException {
+                responseTrigger.submitResponse(new BasicResponseProducer(
+                        HttpStatus.SC_OK,
+                        new DigestingEntityProducer("MD5",
+                                new StringAsyncEntityProducer("Hello back with some trailers"))), context);
+            }
         });
         final InetSocketAddress serverEndpoint = server.start();
 
@@ -1797,62 +1564,55 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testProtocolException() throws Exception {
-        server.register("/boom", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new AsyncServerExchangeHandler() {
-
-                    private final StringAsyncEntityProducer entityProducer = new StringAsyncEntityProducer("Everyting is OK");
+        server.register("/boom", () -> new AsyncServerExchangeHandler() {
 
-                    @Override
-                    public void releaseResources() {
-                        entityProducer.releaseResources();
-                    }
+            private final StringAsyncEntityProducer entityProducer = new StringAsyncEntityProducer("Everyting is OK");
 
-                    @Override
-                    public void handleRequest(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final ResponseChannel responseChannel,
-                            final HttpContext context) throws HttpException, IOException {
-                        final String requestUri = request.getRequestUri();
-                        if (requestUri.endsWith("boom")) {
-                            throw new ProtocolException("Boom!!!");
-                        }
-                        responseChannel.sendResponse(new BasicHttpResponse(200), entityProducer, context);
-                    }
+            @Override
+            public void releaseResources() {
+                entityProducer.releaseResources();
+            }
 
-                    @Override
-                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                        capacityChannel.update(Integer.MAX_VALUE);
-                    }
+            @Override
+            public void handleRequest(
+                    final HttpRequest request,
+                    final EntityDetails entityDetails,
+                    final ResponseChannel responseChannel,
+                    final HttpContext context) throws HttpException, IOException {
+                final String requestUri = request.getRequestUri();
+                if (requestUri.endsWith("boom")) {
+                    throw new ProtocolException("Boom!!!");
+                }
+                responseChannel.sendResponse(new BasicHttpResponse(200), entityProducer, context);
+            }
 
-                    @Override
-                    public void consume(final ByteBuffer src) throws IOException {
-                    }
+            @Override
+            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                capacityChannel.update(Integer.MAX_VALUE);
+            }
 
-                    @Override
-                    public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                        // empty
-                    }
+            @Override
+            public void consume(final ByteBuffer src) throws IOException {
+            }
 
-                    @Override
-                    public int available() {
-                        return entityProducer.available();
-                    }
+            @Override
+            public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                // empty
+            }
 
-                    @Override
-                    public void produce(final DataStreamChannel channel) throws IOException {
-                        entityProducer.produce(channel);
-                    }
+            @Override
+            public int available() {
+                return entityProducer.available();
+            }
 
-                    @Override
-                    public void failed(final Exception cause) {
-                        releaseResources();
-                    }
+            @Override
+            public void produce(final DataStreamChannel channel) throws IOException {
+                entityProducer.produce(channel);
+            }
 
-                };
+            @Override
+            public void failed(final Exception cause) {
+                releaseResources();
             }
 
         });
@@ -1877,14 +1637,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testHeaderTooLarge() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start(null, Http1Config.custom()
                 .setMaxLineLength(100)
                 .build());
@@ -1910,14 +1663,7 @@ public class Http1IntegrationTest extends InternalHttp1ServerTestBase {
 
     @Test
     public void testHeaderTooLargePost() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start(null, Http1Config.custom()
                 .setMaxLineLength(100)
                 .build());
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
index 4fd8002..8b8f15f 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/Http1ServerAndRequesterTest.java
@@ -35,9 +35,7 @@ import java.util.LinkedList;
 import java.util.Queue;
 import java.util.concurrent.Future;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ContentType;
-import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.HeaderElements;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
@@ -55,19 +53,15 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
 import org.apache.hc.core5.http.message.BasicHttpRequest;
 import org.apache.hc.core5.http.nio.AsyncClientEndpoint;
-import org.apache.hc.core5.http.nio.AsyncDataConsumer;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.nio.AsyncFilterChain;
-import org.apache.hc.core5.http.nio.AsyncFilterHandler;
 import org.apache.hc.core5.http.nio.AsyncPushProducer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityProducer;
 import org.apache.hc.core5.http.nio.ssl.BasicClientTlsStrategy;
 import org.apache.hc.core5.http.nio.ssl.BasicServerTlsStrategy;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.UriPatternMatcher;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.reactor.IOReactorConfig;
@@ -114,56 +108,38 @@ public class Http1ServerAndRequesterTest {
         protected void before() throws Throwable {
             log.debug("Starting up test server");
             server = AsyncServerBootstrap.bootstrap()
-                    .setLookupRegistry(new UriPatternMatcher<Supplier<AsyncServerExchangeHandler>>())
+                    .setLookupRegistry(new UriPatternMatcher<>())
                     .setIOReactorConfig(
                             IOReactorConfig.custom()
                                     .setSoTimeout(TIMEOUT)
                                     .build())
-                    .register("*", new Supplier<AsyncServerExchangeHandler>() {
+                    .register("*", () -> new EchoHandler(2048))
+                    .addFilterBefore(StandardFilter.MAIN_HANDLER.name(), "no-keepalive", (request, entityDetails, context, responseTrigger, chain) -> chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
 
                         @Override
-                        public AsyncServerExchangeHandler get() {
-                            return new EchoHandler(2048);
+                        public void sendInformation(
+                                final HttpResponse response) throws HttpException, IOException {
+                            responseTrigger.sendInformation(response);
                         }
 
-                    })
-                    .addFilterBefore(StandardFilter.MAIN_HANDLER.name(), "no-keepalive", new AsyncFilterHandler() {
+                        @Override
+                        public void submitResponse(
+                                final HttpResponse response,
+                                final AsyncEntityProducer entityProducer) throws HttpException, IOException {
+                            if (request.getPath().startsWith("/no-keep-alive")) {
+                                response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
+                            }
+                            responseTrigger.submitResponse(response, entityProducer);
+                        }
 
                         @Override
-                        public AsyncDataConsumer handle(
-                                final HttpRequest request,
-                                final EntityDetails entityDetails,
-                                final HttpContext context,
-                                final AsyncFilterChain.ResponseTrigger responseTrigger,
-                                final AsyncFilterChain chain) throws HttpException, IOException {
-                            return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
-
-                                @Override
-                                public void sendInformation(
-                                        final HttpResponse response) throws HttpException, IOException {
-                                    responseTrigger.sendInformation(response);
-                                }
-
-                                @Override
-                                public void submitResponse(
-                                        final HttpResponse response,
-                                        final AsyncEntityProducer entityProducer) throws HttpException, IOException {
-                                    if (request.getPath().startsWith("/no-keep-alive")) {
-                                        response.setHeader(HttpHeaders.CONNECTION, HeaderElements.CLOSE);
-                                    }
-                                    responseTrigger.submitResponse(response, entityProducer);
-                                }
-
-                                @Override
-                                public void pushPromise(
-                                        final HttpRequest promise,
-                                        final AsyncPushProducer responseProducer) throws HttpException, IOException {
-                                    responseTrigger.pushPromise(promise, responseProducer);
-                                }
-
-                            });
+                        public void pushPromise(
+                                final HttpRequest promise,
+                                final AsyncPushProducer responseProducer) throws HttpException, IOException {
+                            responseTrigger.pushPromise(promise, responseProducer);
                         }
-                    })
+
+                    }))
                     .setTlsStrategy(scheme == URIScheme.HTTPS  ?
                             new BasicServerTlsStrategy(SSLTestContexts.createServerSSLContext()) : null)
                     .setStreamListener(LoggingHttp1StreamListener.INSTANCE_SERVER)
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java
index 5ddd0c1..160352b 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/nio/JSSEProviderIntegrationTest.java
@@ -38,15 +38,11 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.concurrent.Future;
 
-import javax.net.ssl.SSLEngine;
-
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.Message;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.config.Http1Config;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.entity.StringAsyncEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AsyncRequestBuilder;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
@@ -54,9 +50,7 @@ import org.apache.hc.core5.http.nio.support.BasicResponseConsumer;
 import org.apache.hc.core5.http.protocol.DefaultHttpProcessor;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.http.protocol.RequestValidateHost;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.IOReactorConfig;
-import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 import org.apache.hc.core5.ssl.SSLContextBuilder;
 import org.apache.hc.core5.util.ReflectionUtils;
 import org.apache.hc.core5.util.TimeValue;
@@ -157,15 +151,10 @@ public class JSSEProviderIntegrationTest {
                             .loadKeyMaterial(keyStoreURL, storePassword.toCharArray(), storePassword.toCharArray())
                             .setSecureRandom(new SecureRandom())
                             .build(),
-                    new SSLSessionInitializer() {
-
-                        @Override
-                        public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                            if (protocolVersion != null) {
-                                sslEngine.setEnabledProtocols(new String[]{protocolVersion});
-                            }
+                    (endpoint, sslEngine) -> {
+                        if (protocolVersion != null) {
+                            sslEngine.setEnabledProtocols(new String[]{protocolVersion});
                         }
-
                     },
                     null);
         }
@@ -197,15 +186,10 @@ public class JSSEProviderIntegrationTest {
                             .loadTrustMaterial(keyStoreURL, storePassword.toCharArray())
                             .setSecureRandom(new SecureRandom())
                             .build(),
-                    new SSLSessionInitializer() {
-
-                        @Override
-                        public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                            if (protocolVersion != null) {
-                                sslEngine.setEnabledProtocols(new String[]{protocolVersion});
-                            }
+                    (endpoint, sslEngine) -> {
+                        if (protocolVersion != null) {
+                            sslEngine.setEnabledProtocols(new String[]{protocolVersion});
                         }
-
                     },
                     null);
         }
@@ -230,14 +214,7 @@ public class JSSEProviderIntegrationTest {
 
     @Test
     public void testSimpleGet() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -261,14 +238,7 @@ public class JSSEProviderIntegrationTest {
 
     @Test
     public void testSimpleGetConnectionClose() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final InetSocketAddress serverEndpoint = server.start();
 
         client.start();
@@ -295,14 +265,7 @@ public class JSSEProviderIntegrationTest {
 
     @Test
     public void testSimpleGetIdentityTransfer() throws Exception {
-        server.register("/hello", new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new SingleLineResponseHandler("Hi there");
-            }
-
-        });
+        server.register("/hello", () -> new SingleLineResponseHandler("Hi there"));
         final HttpProcessor httpProcessor = new DefaultHttpProcessor(new RequestValidateHost());
         final InetSocketAddress serverEndpoint = server.start(httpProcessor, Http1Config.DEFAULT);
 
diff --git a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
index 20603d8..ac1e7c1 100644
--- a/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
+++ b/httpcore5-testing/src/test/java/org/apache/hc/core5/testing/reactive/ReactiveClientTest.java
@@ -45,7 +45,6 @@ import java.util.concurrent.Future;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpStreamResetException;
 import org.apache.hc.core5.http.Message;
@@ -53,7 +52,6 @@ import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncRequester;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
-import org.apache.hc.core5.http.nio.AsyncServerExchangeHandler;
 import org.apache.hc.core5.http.nio.support.BasicRequestProducer;
 import org.apache.hc.core5.http2.HttpVersionPolicy;
 import org.apache.hc.core5.http2.impl.nio.bootstrap.H2RequesterBootstrap;
@@ -85,8 +83,6 @@ import org.slf4j.LoggerFactory;
 
 import io.reactivex.Flowable;
 import io.reactivex.Observable;
-import io.reactivex.functions.Action;
-import io.reactivex.functions.Consumer;
 
 @RunWith(Parameterized.class)
 public class ReactiveClientTest {
@@ -130,14 +126,7 @@ public class ReactiveClientTest {
                 .setIOSessionDecorator(LoggingIOSessionDecorator.INSTANCE)
                 .setExceptionCallback(LoggingExceptionCallback.INSTANCE)
                 .setIOSessionListener(LoggingIOSessionListener.INSTANCE)
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new ReactiveServerExchangeHandler(new ReactiveEchoProcessor());
-                    }
-
-                })
+                .register("*", () -> new ReactiveServerExchangeHandler(new ReactiveEchoProcessor()))
                 .create();
         }
 
@@ -285,12 +274,7 @@ public class ReactiveClientTest {
         final InetSocketAddress address = startClientAndServer();
         final AtomicBoolean requestPublisherWasCancelled = new AtomicBoolean(false);
         final Publisher<ByteBuffer> publisher = Flowable.<ByteBuffer>never()
-            .doOnCancel(new Action() {
-                @Override
-                public void run() {
-                    requestPublisherWasCancelled.set(true);
-                }
-            });
+            .doOnCancel(() -> requestPublisherWasCancelled.set(true));
         final ReactiveEntityProducer producer = new ReactiveEntityProducer(publisher, -1, null, null);
         final BasicRequestProducer request = getRequestProducer(address, producer);
 
@@ -320,18 +304,8 @@ public class ReactiveClientTest {
         final AtomicBoolean requestPublisherWasCancelled = new AtomicBoolean(false);
         final AtomicReference<Throwable> requestStreamError = new AtomicReference<>();
         final Publisher<ByteBuffer> stream = ReactiveTestUtils.produceStream(Long.MAX_VALUE, 1024, null)
-            .doOnCancel(new Action() {
-                @Override
-                public void run() throws Exception {
-                    requestPublisherWasCancelled.set(true);
-                }
-            })
-            .doOnError(new Consumer<Throwable>() {
-                @Override
-                public void accept(final Throwable throwable) throws Exception {
-                    requestStreamError.set(throwable);
-                }
-            });
+            .doOnCancel(() -> requestPublisherWasCancelled.set(true))
+            .doOnError(requestStreamError::set);
         final ReactiveEntityProducer producer = new ReactiveEntityProducer(stream, -1, null, null);
         final BasicRequestProducer request = getRequestProducer(address, producer);
 
@@ -342,12 +316,7 @@ public class ReactiveClientTest {
 
         final AtomicBoolean responsePublisherWasCancelled = new AtomicBoolean(false);
         final List<ByteBuffer> outputBuffers = Flowable.fromPublisher(response.getBody())
-            .doOnCancel(new Action() {
-                @Override
-                public void run() throws Exception {
-                    responsePublisherWasCancelled.set(true);
-                }
-            })
+            .doOnCancel(() -> responsePublisherWasCancelled.set(true))
             .take(3)
             .toList()
             .blockingGet();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/concurrent/ComplexFuture.java b/httpcore5/src/main/java/org/apache/hc/core5/concurrent/ComplexFuture.java
index 18fa786..e902e0e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/concurrent/ComplexFuture.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/concurrent/ComplexFuture.java
@@ -63,14 +63,7 @@ public final class ComplexFuture<T> extends BasicFuture<T> implements Cancellabl
         if (dependency instanceof Cancellable) {
             setDependency((Cancellable) dependency);
         } else {
-            setDependency(new Cancellable() {
-
-                @Override
-                public boolean cancel() {
-                    return dependency.cancel(true);
-                }
-
-            });
+            setDependency(() -> dependency.cancel(true));
         }
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
index 604c9e2..44810d9 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncRequesterBootstrap.java
@@ -218,7 +218,7 @@ public class AsyncRequesterBootstrap {
                         defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<IOSession>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
             case STRICT:
@@ -228,7 +228,7 @@ public class AsyncRequesterBootstrap {
                         maxTotal > 0 ? maxTotal : 50,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<IOSession>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
         }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
index c5041bb..640cab8 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/AsyncServerBootstrap.java
@@ -246,14 +246,7 @@ public class AsyncServerBootstrap {
     public final <T> AsyncServerBootstrap register(
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        register(uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        register(uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
         return this;
     }
 
@@ -269,14 +262,7 @@ public class AsyncServerBootstrap {
             final String hostname,
             final String uriPattern,
             final AsyncServerRequestHandler<T> requestHandler) {
-        registerVirtual(hostname, uriPattern, new Supplier<AsyncServerExchangeHandler>() {
-
-            @Override
-            public AsyncServerExchangeHandler get() {
-                return new BasicServerExchangeHandler<>(requestHandler);
-            }
-
-        });
+        registerVirtual(hostname, uriPattern, () -> new BasicServerExchangeHandler<>(requestHandler));
         return this;
     }
 
@@ -335,15 +321,8 @@ public class AsyncServerBootstrap {
     public HttpAsyncServer create() {
         final RequestHandlerRegistry<Supplier<AsyncServerExchangeHandler>> registry = new RequestHandlerRegistry<>(
                 canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName(),
-                new Supplier<LookupRegistry<Supplier<AsyncServerExchangeHandler>>>() {
-
-                    @Override
-                    public LookupRegistry<Supplier<AsyncServerExchangeHandler>> get() {
-                        return lookupRegistry != null ? lookupRegistry :
-                                UriPatternType.<Supplier<AsyncServerExchangeHandler>>newMatcher(UriPatternType.URI_PATTERN);
-                    }
-
-                });
+                () -> lookupRegistry != null ? lookupRegistry :
+                        UriPatternType.<Supplier<AsyncServerExchangeHandler>>newMatcher(UriPatternType.URI_PATTERN));
         for (final HandlerEntry<Supplier<AsyncServerExchangeHandler>> entry: handlerList) {
             registry.register(entry.hostname, entry.uriPattern, entry.handler);
         }
@@ -389,14 +368,7 @@ public class AsyncServerBootstrap {
 
             handlerFactory = new AsyncServerFilterChainExchangeHandlerFactory(execChain, exceptionCallback);
         } else {
-            handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, new Decorator<AsyncServerExchangeHandler>() {
-
-                @Override
-                public AsyncServerExchangeHandler decorate(final AsyncServerExchangeHandler handler) {
-                    return new BasicAsyncServerExpectationDecorator(handler, exceptionCallback);
-                }
-
-            });
+            handlerFactory = new DefaultAsyncResponseExchangeHandlerFactory(registry, handler -> new BasicAsyncServerExpectationDecorator(handler, exceptionCallback));
         }
 
         final ServerHttp1StreamDuplexerFactory streamHandlerFactory = new ServerHttp1StreamDuplexerFactory(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
index 32f8807..6ebe715 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpAsyncRequester.java
@@ -47,7 +47,6 @@ import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
 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.ProtocolException;
 import org.apache.hc.core5.http.impl.DefaultAddressResolver;
@@ -255,104 +254,97 @@ public class HttpAsyncRequester extends AsyncRequester implements ConnPoolContro
         Args.notNull(timeout, "Timeout");
         Args.notNull(executeContext, "Context");
         try {
-            exchangeHandler.produceRequest(new RequestChannel() {
-
-                @Override
-                public void sendRequest(
-                        final HttpRequest request,
-                        final EntityDetails entityDetails, final HttpContext requestContext) throws HttpException, IOException {
-                    final String scheme = request.getScheme();
-                    final URIAuthority authority = request.getAuthority();
-                    if (authority == null) {
-                        throw new ProtocolException("Request authority not specified");
-                    }
-                    final HttpHost target = new HttpHost(scheme, authority);
-                    connect(target, timeout, null, new FutureCallback<AsyncClientEndpoint>() {
-
-                        @Override
-                        public void completed(final AsyncClientEndpoint endpoint) {
-                            endpoint.execute(new AsyncClientExchangeHandler() {
-
-                                @Override
-                                public void releaseResources() {
-                                    endpoint.releaseAndDiscard();
-                                    exchangeHandler.releaseResources();
-                                }
-
-                                @Override
-                                public void failed(final Exception cause) {
-                                    endpoint.releaseAndDiscard();
-                                    exchangeHandler.failed(cause);
-                                }
-
-                                @Override
-                                public void cancel() {
-                                    endpoint.releaseAndDiscard();
-                                    exchangeHandler.cancel();
-                                }
-
-                                @Override
-                                public void produceRequest(final RequestChannel channel, final HttpContext httpContext) throws HttpException, IOException {
-                                    channel.sendRequest(request, entityDetails, httpContext);
-                                }
-
-                                @Override
-                                public int available() {
-                                    return exchangeHandler.available();
-                                }
-
-                                @Override
-                                public void produce(final DataStreamChannel channel) throws IOException {
-                                    exchangeHandler.produce(channel);
-                                }
-
-                                @Override
-                                public void consumeInformation(final HttpResponse response, final HttpContext httpContext) throws HttpException, IOException {
-                                    exchangeHandler.consumeInformation(response, httpContext);
-                                }
-
-                                @Override
-                                public void consumeResponse(
-                                        final HttpResponse response, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
-                                    if (entityDetails == null) {
-                                        endpoint.releaseAndReuse();
-                                    }
-                                    exchangeHandler.consumeResponse(response, entityDetails, httpContext);
-                                }
+            exchangeHandler.produceRequest((request, entityDetails, requestContext) -> {
+                final String scheme = request.getScheme();
+                final URIAuthority authority = request.getAuthority();
+                if (authority == null) {
+                    throw new ProtocolException("Request authority not specified");
+                }
+                final HttpHost target = new HttpHost(scheme, authority);
+                connect(target, timeout, null, new FutureCallback<AsyncClientEndpoint>() {
 
-                                @Override
-                                public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                                    exchangeHandler.updateCapacity(capacityChannel);
+                    @Override
+                    public void completed(final AsyncClientEndpoint endpoint) {
+                        endpoint.execute(new AsyncClientExchangeHandler() {
+
+                            @Override
+                            public void releaseResources() {
+                                endpoint.releaseAndDiscard();
+                                exchangeHandler.releaseResources();
+                            }
+
+                            @Override
+                            public void failed(final Exception cause) {
+                                endpoint.releaseAndDiscard();
+                                exchangeHandler.failed(cause);
+                            }
+
+                            @Override
+                            public void cancel() {
+                                endpoint.releaseAndDiscard();
+                                exchangeHandler.cancel();
+                            }
+
+                            @Override
+                            public void produceRequest(final RequestChannel channel, final HttpContext httpContext) throws HttpException, IOException {
+                                channel.sendRequest(request, entityDetails, httpContext);
+                            }
+
+                            @Override
+                            public int available() {
+                                return exchangeHandler.available();
+                            }
+
+                            @Override
+                            public void produce(final DataStreamChannel channel) throws IOException {
+                                exchangeHandler.produce(channel);
+                            }
+
+                            @Override
+                            public void consumeInformation(final HttpResponse response, final HttpContext httpContext) throws HttpException, IOException {
+                                exchangeHandler.consumeInformation(response, httpContext);
+                            }
+
+                            @Override
+                            public void consumeResponse(
+                                    final HttpResponse response, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
+                                if (entityDetails == null) {
+                                    endpoint.releaseAndReuse();
                                 }
+                                exchangeHandler.consumeResponse(response, entityDetails, httpContext);
+                            }
 
-                                @Override
-                                public void consume(final ByteBuffer src) throws IOException {
-                                    exchangeHandler.consume(src);
-                                }
+                            @Override
+                            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                                exchangeHandler.updateCapacity(capacityChannel);
+                            }
 
-                                @Override
-                                public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
-                                    endpoint.releaseAndReuse();
-                                    exchangeHandler.streamEnd(trailers);
-                                }
+                            @Override
+                            public void consume(final ByteBuffer src) throws IOException {
+                                exchangeHandler.consume(src);
+                            }
 
-                            }, pushHandlerFactory, executeContext);
+                            @Override
+                            public void streamEnd(final List<? extends Header> trailers) throws HttpException, IOException {
+                                endpoint.releaseAndReuse();
+                                exchangeHandler.streamEnd(trailers);
+                            }
 
-                        }
+                        }, pushHandlerFactory, executeContext);
 
-                        @Override
-                        public void failed(final Exception ex) {
-                            exchangeHandler.failed(ex);
-                        }
+                    }
 
-                        @Override
-                        public void cancelled() {
-                            exchangeHandler.cancel();
-                        }
+                    @Override
+                    public void failed(final Exception ex) {
+                        exchangeHandler.failed(ex);
+                    }
 
-                    });
+                    @Override
+                    public void cancelled() {
+                        exchangeHandler.cancel();
+                    }
 
-                }
+                });
 
             }, executeContext);
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
index f618c4e..957509c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpRequester.java
@@ -268,12 +268,9 @@ public class HttpRequester implements ConnPoolControl<HttpHost>, ModalCloseable
         // 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(targetAddress, socketConfig.getSoTimeout().toMillisecondsIntBound());
-                    return null;
-                }
+            AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
+                sock.connect(targetAddress, socketConfig.getSoTimeout().toMillisecondsIntBound());
+                return null;
             });
         } catch (final PrivilegedActionException e) {
             Asserts.check(e.getCause() instanceof  IOException,
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
index dbbcc67..0e293b7 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/HttpServer.java
@@ -106,12 +106,12 @@ public class HttpServer implements ModalCloseable {
         this.exceptionListener = exceptionListener != null ? exceptionListener : ExceptionListener.NO_OP;
         this.listenerExecutorService = new ThreadPoolExecutor(
                 1, 1, 0L, TimeUnit.MILLISECONDS,
-                new SynchronousQueue<Runnable>(),
+                new SynchronousQueue<>(),
                 new DefaultThreadFactory("HTTP-listener-" + this.port));
         this.workerThreads = new ThreadGroup("HTTP-workers");
         this.workerExecutorService = new WorkerPoolExecutor(
                 0, Integer.MAX_VALUE, 1L, TimeUnit.SECONDS,
-                new SynchronousQueue<Runnable>(),
+                new SynchronousQueue<>(),
                 new DefaultThreadFactory("HTTP-worker", this.workerThreads, true));
         this.status = new AtomicReference<>(Status.READY);
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
index fd9268b..15791af 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/RequesterBootstrap.java
@@ -189,7 +189,7 @@ public class RequesterBootstrap {
                         defaultMaxPerRoute > 0 ? defaultMaxPerRoute : 20,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<HttpClientConnection>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
             case STRICT:
@@ -199,7 +199,7 @@ public class RequesterBootstrap {
                         maxTotal > 0 ? maxTotal : 50,
                         timeToLive,
                         poolReusePolicy,
-                        new DefaultDisposalCallback<HttpClientConnection>(),
+                        new DefaultDisposalCallback<>(),
                         connPoolListener);
                 break;
         }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
index 8e445c0..9711772 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/bootstrap/ServerBootstrap.java
@@ -36,7 +36,6 @@ import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLServerSocketFactory;
 
 import org.apache.hc.core5.function.Callback;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.ExceptionListener;
@@ -325,15 +324,8 @@ public class ServerBootstrap {
     public HttpServer create() {
         final RequestHandlerRegistry<HttpRequestHandler> handlerRegistry = new RequestHandlerRegistry<>(
                 canonicalHostName != null ? canonicalHostName : InetAddressUtils.getCanonicalLocalHostName(),
-                new Supplier<LookupRegistry<HttpRequestHandler>>() {
-
-                    @Override
-                    public LookupRegistry<HttpRequestHandler> get() {
-                        return lookupRegistry != null ? lookupRegistry :
-                                UriPatternType.<HttpRequestHandler>newMatcher(UriPatternType.URI_PATTERN);
-                    }
-
-                });
+                () -> lookupRegistry != null ? lookupRegistry :
+                        UriPatternType.<HttpRequestHandler>newMatcher(UriPatternType.URI_PATTERN));
         for (final HandlerEntry<HttpRequestHandler> entry: handlerList) {
             handlerRegistry.register(entry.hostname, entry.uriPattern, entry.handler);
         }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
index 1721b04..0a5a15b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/impl/nio/ClientHttp1StreamHandler.java
@@ -49,9 +49,7 @@ import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.http.nio.AsyncClientExchangeHandler;
 import org.apache.hc.core5.http.nio.CapacityChannel;
 import org.apache.hc.core5.http.nio.DataStreamChannel;
-import org.apache.hc.core5.http.nio.RequestChannel;
 import org.apache.hc.core5.http.nio.ResourceHolder;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.apache.hc.core5.util.Timeout;
@@ -182,15 +180,7 @@ class ClientHttp1StreamHandler implements ResourceHolder {
         switch (requestState) {
             case IDLE:
                 requestState = MessageState.HEADERS;
-                exchangeHandler.produceRequest(new RequestChannel() {
-
-                    @Override
-                    public void sendRequest(
-                            final HttpRequest request, final EntityDetails entityDetails, final HttpContext httpContext) throws HttpException, IOException {
-                        commitRequest(request, entityDetails);
-                    }
-
-                }, context);
+                exchangeHandler.produceRequest((request, entityDetails, httpContext) -> commitRequest(request, entityDetails), context);
                 break;
             case ACK:
                 outputChannel.suspendOutput();
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java
index 6331733..bcdbb98 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/entity/HttpEntities.java
@@ -174,14 +174,7 @@ public final class HttpEntities {
 
             @Override
             public Supplier<List<? extends Header>> getTrailers() {
-                return new Supplier<List<? extends Header>>() {
-
-                    @Override
-                    public List<? extends Header> get() {
-                        return Arrays.asList(trailers);
-                    }
-
-                };
+                return () -> Arrays.asList(trailers);
             }
 
             @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
index 939c468..d9e116e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/io/support/HttpServerFilterChainElement.java
@@ -49,16 +49,7 @@ public final class HttpServerFilterChainElement {
     public HttpServerFilterChainElement(final HttpFilterHandler handler, final HttpServerFilterChainElement next) {
         this.handler = handler;
         this.next = next;
-        this.filterChain = new HttpFilterChain() {
-
-            @Override
-            public void proceed(
-                    final ClassicHttpRequest request,
-                    final ResponseTrigger responseTrigger,
-                    final HttpContext context) throws HttpException, IOException {
-                next.handle(request, responseTrigger, context);
-            }
-        };
+        this.filterChain = next != null ? next::handle : null;
     }
 
     public void handle(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/command/ShutdownCommand.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/command/ShutdownCommand.java
index 7a3a150..fcbf619 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/command/ShutdownCommand.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/command/ShutdownCommand.java
@@ -48,14 +48,7 @@ public final class ShutdownCommand implements Command {
     public static final Callback<IOSession> GRACEFUL_NORMAL_CALLBACK = createIOSessionCallback(Priority.NORMAL);
 
     private static Callback<IOSession> createIOSessionCallback(final Priority priority) {
-        return new Callback<IOSession>() {
-
-            @Override
-            public void execute(final IOSession session) {
-                session.enqueue(ShutdownCommand.GRACEFUL, priority);
-            }
-
-        };
+        return session -> session.enqueue(ShutdownCommand.GRACEFUL, priority);
     }
 
     private final CloseMode type;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/DiscardingEntityConsumer.java
similarity index 90%
copy from httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java
copy to httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/DiscardingEntityConsumer.java
index d3132f9..97746c3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/DiscardingEntityConsumer.java
@@ -40,16 +40,16 @@ import org.apache.hc.core5.http.nio.CapacityChannel;
 /**
  * No-op {@link AsyncEntityConsumer} that discards all data from the data stream.
  *
- * @since 5.0
+ * @since 5.2
  */
-public final class NoopEntityConsumer implements AsyncEntityConsumer<Void> {
+public final class DiscardingEntityConsumer<T> implements AsyncEntityConsumer<T> {
 
-    private volatile FutureCallback<Void> resultCallback;
+    private volatile FutureCallback<T> resultCallback;
 
     @Override
     public void streamStart(
             final EntityDetails entityDetails,
-            final FutureCallback<Void> resultCallback) throws IOException, HttpException {
+            final FutureCallback<T> resultCallback) throws IOException, HttpException {
         this.resultCallback = resultCallback;
     }
 
@@ -77,7 +77,7 @@ public final class NoopEntityConsumer implements AsyncEntityConsumer<Void> {
     }
 
     @Override
-    public Void getContent() {
+    public T getContent() {
         return null;
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java
index d3132f9..554ba5b 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/entity/NoopEntityConsumer.java
@@ -41,7 +41,10 @@ import org.apache.hc.core5.http.nio.CapacityChannel;
  * No-op {@link AsyncEntityConsumer} that discards all data from the data stream.
  *
  * @since 5.0
+ *
+ * @deprecated Use {@link DiscardingEntityConsumer}
  */
+@Deprecated
 public final class NoopEntityConsumer implements AsyncEntityConsumer<Void> {
 
     private volatile FutureCallback<Void> resultCallback;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsSupport.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsSupport.java
index 89fddf8..779f695 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsSupport.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/ssl/TlsSupport.java
@@ -27,12 +27,10 @@
 
 package org.apache.hc.core5.http.nio.ssl;
 
-import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
 
 import org.apache.hc.core5.http.ssl.TLS;
 import org.apache.hc.core5.http.ssl.TlsCiphers;
-import org.apache.hc.core5.net.NamedEndpoint;
 import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 
 /**
@@ -43,19 +41,14 @@ import org.apache.hc.core5.reactor.ssl.SSLSessionInitializer;
 public final class TlsSupport {
 
     public static SSLSessionInitializer enforceStrongSecurity(final SSLSessionInitializer initializer) {
-        return new SSLSessionInitializer() {
-
-            @Override
-            public void initialize(final NamedEndpoint endpoint, final SSLEngine sslEngine) {
-                final SSLParameters sslParameters = sslEngine.getSSLParameters();
-                sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
-                sslParameters.setCipherSuites(TlsCiphers.excludeWeak(sslParameters.getCipherSuites()));
-                sslEngine.setSSLParameters(sslParameters);
-                if (initializer != null) {
-                    initializer.initialize(endpoint, sslEngine);
-                }
+        return (endpoint, sslEngine) -> {
+            final SSLParameters sslParameters = sslEngine.getSSLParameters();
+            sslParameters.setProtocols(TLS.excludeWeak(sslParameters.getProtocols()));
+            sslParameters.setCipherSuites(TlsCiphers.excludeWeak(sslParameters.getCipherSuites()));
+            sslEngine.setSSLParameters(sslParameters);
+            if (initializer != null) {
+                initializer.initialize(endpoint, sslEngine);
             }
-
         };
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncRequesterConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncRequesterConsumer.java
index 02447ca..c5caa92 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncRequesterConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncRequesterConsumer.java
@@ -66,14 +66,7 @@ public abstract class AbstractAsyncRequesterConsumer<T, E> implements AsyncReque
     }
 
     public AbstractAsyncRequesterConsumer(final AsyncEntityConsumer<E> dataConsumer) {
-        this(new Supplier<AsyncEntityConsumer<E>>() {
-
-            @Override
-            public AsyncEntityConsumer<E> get() {
-                return dataConsumer;
-            }
-
-        });
+        this(() -> dataConsumer);
     }
 
     /**
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncResponseConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncResponseConsumer.java
index 168620c..c4a0644 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncResponseConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AbstractAsyncResponseConsumer.java
@@ -66,14 +66,7 @@ public abstract class AbstractAsyncResponseConsumer<T, E> implements AsyncRespon
     }
 
     public AbstractAsyncResponseConsumer(final AsyncEntityConsumer<E> dataConsumer) {
-        this(new Supplier<AsyncEntityConsumer<E>>() {
-
-            @Override
-            public AsyncEntityConsumer<E> get() {
-                return dataConsumer;
-            }
-
-        });
+        this(() -> dataConsumer);
     }
 
     /**
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
index 3e64c5e..5b7d2f2 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/AsyncServerFilterChainElement.java
@@ -51,18 +51,7 @@ public final class AsyncServerFilterChainElement {
     public AsyncServerFilterChainElement(final AsyncFilterHandler handler, final AsyncServerFilterChainElement next) {
         this.handler = handler;
         this.next = next;
-        this.filterChain = new AsyncFilterChain() {
-
-            @Override
-            public AsyncDataConsumer proceed(
-                    final HttpRequest request,
-                    final EntityDetails entityDetails,
-                    final HttpContext context,
-                    final ResponseTrigger responseTrigger) throws HttpException, IOException {
-                return next.handle(request, entityDetails, context, responseTrigger);
-            }
-
-        };
+        this.filterChain = next != null ? next::handle : null;
     }
 
     public AsyncDataConsumer handle(
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicRequestConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicRequestConsumer.java
index 6eaf64c..8802b60 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicRequestConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicRequestConsumer.java
@@ -62,14 +62,7 @@ public class BasicRequestConsumer<T> implements AsyncRequestConsumer<Message<Htt
     }
 
     public BasicRequestConsumer(final AsyncEntityConsumer<T> dataConsumer) {
-        this(new Supplier<AsyncEntityConsumer<T>>() {
-
-            @Override
-            public AsyncEntityConsumer<T> get() {
-                return dataConsumer;
-            }
-
-        });
+        this(() -> dataConsumer);
     }
 
     @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicResponseConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicResponseConsumer.java
index c9d48fa..70fc73e 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicResponseConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/BasicResponseConsumer.java
@@ -63,14 +63,7 @@ public class BasicResponseConsumer<T> implements AsyncResponseConsumer<Message<H
     }
 
     public BasicResponseConsumer(final AsyncEntityConsumer<T> dataConsumer) {
-        this(new Supplier<AsyncEntityConsumer<T>>() {
-
-            @Override
-            public AsyncEntityConsumer<T> get() {
-                return dataConsumer;
-            }
-
-        });
+        this(() -> dataConsumer);
     }
 
     @Override
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityConsumer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityConsumer.java
index 202293c..4cee5ac 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityConsumer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityConsumer.java
@@ -94,22 +94,17 @@ public abstract class AbstractClassicEntityConsumer<T> implements AsyncEntityCon
             throw new UnsupportedEncodingException(ex.getMessage());
         }
         if (state.compareAndSet(State.IDLE, State.ACTIVE)) {
-            executor.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    try {
-                        final T result = consumeData(contentType, new ContentInputStream(buffer));
-                        resultRef.set(result);
-                        resultCallback.completed(result);
-                    } catch (final Exception ex) {
-                        buffer.abort();
-                        resultCallback.failed(ex);
-                    } finally {
-                        state.set(State.COMPLETED);
-                    }
+            executor.execute(() -> {
+                try {
+                    final T result = consumeData(contentType, new ContentInputStream(buffer));
+                    resultRef.set(result);
+                    resultCallback.completed(result);
+                } catch (final Exception ex) {
+                    buffer.abort();
+                    resultCallback.failed(ex);
+                } finally {
+                    state.set(State.COMPLETED);
                 }
-
             });
         }
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityProducer.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityProducer.java
index f9d320a..28ae2b3 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityProducer.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicEntityProducer.java
@@ -83,20 +83,15 @@ public abstract class AbstractClassicEntityProducer implements AsyncEntityProduc
     @Override
     public final void produce(final DataStreamChannel channel) throws IOException {
         if (state.compareAndSet(State.IDLE, State.ACTIVE)) {
-            executor.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    try {
-                        produceData(contentType, new ContentOutputStream(buffer));
-                        buffer.writeCompleted();
-                    } catch (final Exception ex) {
-                        buffer.abort();
-                    } finally {
-                        state.set(State.COMPLETED);
-                    }
+            executor.execute(() -> {
+                try {
+                    produceData(contentType, new ContentOutputStream(buffer));
+                    buffer.writeCompleted();
+                } catch (final Exception ex) {
+                    buffer.abort();
+                } finally {
+                    state.set(State.COMPLETED);
                 }
-
             });
         }
         buffer.flush(channel);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicServerExchangeHandler.java b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicServerExchangeHandler.java
index 549a110..1b18de0 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicServerExchangeHandler.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/nio/support/classic/AbstractClassicServerExchangeHandler.java
@@ -232,25 +232,20 @@ public abstract class AbstractClassicServerExchangeHandler implements AsyncServe
         };
 
         if (state.compareAndSet(State.IDLE, State.ACTIVE)) {
-            executor.execute(new Runnable() {
-
-                @Override
-                public void run() {
-                    try {
-                        handle(request, inputStream, responseWrapper, outputStream, context);
-                        Closer.close(inputStream);
-                        outputStream.close();
-                    } catch (final Exception ex) {
-                        exception.compareAndSet(null, ex);
-                        if (inputBuffer != null) {
-                            inputBuffer.abort();
-                        }
-                        outputBuffer.abort();
-                    } finally {
-                        state.set(State.COMPLETED);
+            executor.execute(() -> {
+                try {
+                    handle(request, inputStream, responseWrapper, outputStream, context);
+                    Closer.close(inputStream);
+                    outputStream.close();
+                } catch (final Exception ex) {
+                    exception.compareAndSet(null, ex);
+                    if (inputBuffer != null) {
+                        inputBuffer.abort();
                     }
+                    outputBuffer.abort();
+                } finally {
+                    state.set(State.COMPLETED);
                 }
-
             });
         }
     }
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
index 581d87a..8262898 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/http/protocol/RequestHandlerRegistry.java
@@ -60,27 +60,13 @@ public class RequestHandlerRegistry<T> implements HttpRequestMapper<T> {
 
     public RequestHandlerRegistry(final String canonicalHostName, final Supplier<LookupRegistry<T>> registrySupplier) {
         this.canonicalHostName = Args.notNull(canonicalHostName, "Canonical hostname").toLowerCase(Locale.ROOT);
-        this.registrySupplier = registrySupplier != null ? registrySupplier : new Supplier<LookupRegistry<T>>() {
-
-            @Override
-            public LookupRegistry<T> get() {
-                return new UriPatternMatcher<>();
-            }
-
-        };
+        this.registrySupplier = registrySupplier != null ? registrySupplier : UriPatternMatcher::new;
         this.primary = this.registrySupplier.get();
         this.virtualMap = new ConcurrentHashMap<>();
     }
 
     public RequestHandlerRegistry(final String canonicalHostName, final UriPatternType patternType) {
-        this(canonicalHostName, new Supplier<LookupRegistry<T>>() {
-
-            @Override
-            public LookupRegistry<T> get() {
-                return UriPatternType.newMatcher(patternType);
-            }
-
-        });
+        this(canonicalHostName, () -> UriPatternType.newMatcher(patternType));
     }
 
     public RequestHandlerRegistry(final UriPatternType patternType) {
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
index 929063c..bdb6c23 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/net/URIBuilder.java
@@ -36,7 +36,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.BitSet;
 import java.util.Collections;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Stack;
@@ -702,12 +701,7 @@ public class URIBuilder {
             this.queryParams = new ArrayList<>();
         }
         if (!this.queryParams.isEmpty()) {
-            for (final Iterator<NameValuePair> it = this.queryParams.iterator(); it.hasNext(); ) {
-                final NameValuePair nvp = it.next();
-                if (nvp.getName().equals(param)) {
-                    it.remove();
-                }
-            }
+            this.queryParams.removeIf(nvp -> nvp.getName().equals(param));
         }
         this.queryParams.add(new BasicNameValuePair(param, value));
         this.encodedQuery = null;
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java b/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
index 26b56e6..ed735cf 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/pool/LaxConnPool.java
@@ -264,30 +264,20 @@ public class LaxConnPool<T, C extends ModalCloseable> implements ManagedConnPool
     @Override
     public void closeIdle(final TimeValue idleTime) {
         final long deadline = System.currentTimeMillis() - (TimeValue.isPositive(idleTime) ? idleTime.toMilliseconds() : 0);
-        enumAvailable(new Callback<PoolEntry<T, C>>() {
-
-            @Override
-            public void execute(final PoolEntry<T, C> entry) {
-                if (entry.getUpdated() <= deadline) {
-                    entry.discardConnection(CloseMode.GRACEFUL);
-                }
+        enumAvailable(entry -> {
+            if (entry.getUpdated() <= deadline) {
+                entry.discardConnection(CloseMode.GRACEFUL);
             }
-
         });
     }
 
     @Override
     public void closeExpired() {
         final long now = System.currentTimeMillis();
-        enumAvailable(new Callback<PoolEntry<T, C>>() {
-
-            @Override
-            public void execute(final PoolEntry<T, C> entry) {
-                if (entry.getExpiryDeadline().isBefore(now)) {
-                    entry.discardConnection(CloseMode.GRACEFUL);
-                }
+        enumAvailable(entry -> {
+            if (entry.getExpiryDeadline().isBefore(now)) {
+                entry.discardConnection(CloseMode.GRACEFUL);
             }
-
         });
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java b/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
index a222bd8..23dd415 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/pool/StrictConnPool.java
@@ -604,30 +604,20 @@ public class StrictConnPool<T, C extends ModalCloseable> implements ManagedConnP
     @Override
     public void closeIdle(final TimeValue idleTime) {
         final long deadline = System.currentTimeMillis() - (TimeValue.isPositive(idleTime) ? idleTime.toMilliseconds() : 0);
-        enumAvailable(new Callback<PoolEntry<T, C>>() {
-
-            @Override
-            public void execute(final PoolEntry<T, C> entry) {
-                if (entry.getUpdated() <= deadline) {
-                    entry.discardConnection(CloseMode.GRACEFUL);
-                }
+        enumAvailable(entry -> {
+            if (entry.getUpdated() <= deadline) {
+                entry.discardConnection(CloseMode.GRACEFUL);
             }
-
         });
     }
 
     @Override
     public void closeExpired() {
         final long now = System.currentTimeMillis();
-        enumAvailable(new Callback<PoolEntry<T, C>>() {
-
-            @Override
-            public void execute(final PoolEntry<T, C> entry) {
-                if (entry.getExpiryDeadline().isBefore(now)) {
-                    entry.discardConnection(CloseMode.GRACEFUL);
-                }
+        enumAvailable(entry -> {
+            if (entry.getExpiryDeadline().isBefore(now)) {
+                entry.discardConnection(CloseMode.GRACEFUL);
             }
-
         });
     }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
index cce68d3..2bc396a 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/AbstractIOSessionPool.java
@@ -133,25 +133,20 @@ public abstract class AbstractIOSessionPool<T> implements ModalCloseable {
 
             @Override
             public void completed(final IOSession ioSession) {
-                validateSession(ioSession, new Callback<Boolean>() {
-
-                    @Override
-                    public void execute(final Boolean result) {
-                        if (result) {
-                            future.completed(ioSession);
-                        } else {
-                            getSessionInternal(poolEntry, true, endpoint, connectTimeout,
-                                new FutureContribution<IOSession>(future) {
-
-                                @Override
-                                public void completed(final IOSession ioSession) {
-                                    future.completed(ioSession);
-                                }
-
-                            });
-                        }
+                validateSession(ioSession, result -> {
+                    if (result) {
+                        future.completed(ioSession);
+                    } else {
+                        getSessionInternal(poolEntry, true, endpoint, connectTimeout,
+                            new FutureContribution<IOSession>(future) {
+
+                            @Override
+                            public void completed(final IOSession ioSession1) {
+                                future.completed(ioSession1);
+                            }
+
+                        });
                     }
-
                 });
             }
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
index b317dfd..944f377 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/DefaultListeningIOReactor.java
@@ -97,14 +97,7 @@ public class DefaultListeningIOReactor extends AbstractIOReactorBase implements
         }
         final IOReactor[] ioReactors = new IOReactor[this.workerCount + 1];
         System.arraycopy(this.workers, 0, ioReactors, 1, this.workerCount);
-        this.listener = new SingleCoreListeningIOReactor(exceptionCallback, ioReactorConfig, new Callback<ChannelEntry>() {
-
-            @Override
-            public void execute(final ChannelEntry entry) {
-                enqueueChannel(entry);
-            }
-
-        });
+        this.listener = new SingleCoreListeningIOReactor(exceptionCallback, ioReactorConfig, this::enqueueChannel);
         ioReactors[0] = this.listener;
         threads[0] = (listenerThreadFactory != null ? listenerThreadFactory : LISTENER_THREAD_FACTORY).newThread(new IOReactorWorker(listener));
 
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
index 8b85962..33ed80d 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/InternalDataChannel.java
@@ -39,7 +39,6 @@ import java.util.concurrent.locks.Lock;
 
 import javax.net.ssl.SSLContext;
 
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.function.Decorator;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.net.NamedEndpoint;
@@ -177,7 +176,7 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
         }
     }
 
-    void onTLSSessionEnd() {
+    void onTLSSessionEnd(final SSLIOSession sslSession) {
         if (closed.compareAndSet(false, true)) {
             closedSessions.add(this);
         }
@@ -210,22 +209,8 @@ final class InternalDataChannel extends InternalChannel implements ProtocolIOSes
                 sslBufferMode,
                 initializer,
                 verifier,
-                new Callback<SSLIOSession>() {
-
-                    @Override
-                    public void execute(final SSLIOSession sslSession) {
-                        onTLSSessionStart(sslSession);
-                    }
-
-                },
-                new Callback<SSLIOSession>() {
-
-                    @Override
-                    public void execute(final SSLIOSession sslSession) {
-                        onTLSSessionEnd();
-                    }
-
-                },
+                this::onTLSSessionStart,
+                this::onTLSSessionEnd,
                 handshakeTimeout);
         if (tlsSessionRef.compareAndSet(null, sslioSession)) {
             currentSessionRef.set(ioSessionDecorator != null ? ioSessionDecorator.decorate(sslioSession) : sslioSession);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
index 5d731a3..be273d1 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/reactor/SingleCoreIOReactor.java
@@ -345,12 +345,7 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
         final boolean connected;
         try {
             connected = AccessController.doPrivileged(
-                        new PrivilegedExceptionAction<Boolean>() {
-                            @Override
-                            public Boolean run() throws IOException {
-                                return socketChannel.connect(targetAddress);
-                            }
-                        });
+                    (PrivilegedExceptionAction<Boolean>) () -> socketChannel.connect(targetAddress));
         } catch (final PrivilegedActionException e) {
             Asserts.check(e.getCause() instanceof  IOException,
                     "method contract violation only checked exceptions are wrapped: " + e.getCause());
@@ -360,26 +355,17 @@ class SingleCoreIOReactor extends AbstractSingleCoreIOReactor implements Connect
 
 
         final SelectionKey key = socketChannel.register(this.selector, SelectionKey.OP_CONNECT | SelectionKey.OP_READ);
-        final InternalChannel channel = new InternalConnectChannel(key, socketChannel, sessionRequest, new InternalDataChannelFactory() {
-
-            @Override
-            public InternalDataChannel create(
-                    final SelectionKey key,
-                    final SocketChannel socketChannel,
-                    final NamedEndpoint namedEndpoint,
-                    final Object attachment) {
-                final IOSession ioSession = new IOSessionImpl("c", key, socketChannel);
-                final InternalDataChannel dataChannel = new InternalDataChannel(
-                        ioSession,
-                        namedEndpoint,
-                        ioSessionDecorator,
-                        sessionListener,
-                        closedSessions);
-                dataChannel.upgrade(eventHandlerFactory.createHandler(dataChannel, attachment));
-                dataChannel.setSocketTimeout(reactorConfig.getSoTimeout());
-                return dataChannel;
-            }
-
+        final InternalChannel channel = new InternalConnectChannel(key, socketChannel, sessionRequest, (k, sc, namedEndpoint, attachment) -> {
+            final IOSession ioSession = new IOSessionImpl("c", k, sc);
+            final InternalDataChannel dataChannel = new InternalDataChannel(
+                    ioSession,
+                    namedEndpoint,
+                    ioSessionDecorator,
+                    sessionListener,
+                    closedSessions);
+            dataChannel.upgrade(eventHandlerFactory.createHandler(dataChannel, attachment));
+            dataChannel.setSocketTimeout(reactorConfig.getSoTimeout());
+            return dataChannel;
         });
         if (connected) {
             channel.handleIOEvent(SelectionKey.OP_CONNECT);
diff --git a/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java b/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java
index f6eaf85..2c5f72c 100644
--- a/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java
+++ b/httpcore5/src/main/java/org/apache/hc/core5/util/ReflectionUtils.java
@@ -58,12 +58,9 @@ public final class ReflectionUtils {
     }
 
     private static void setAccessible(final Method method) {
-        AccessController.doPrivileged(new PrivilegedAction<Object>() {
-            @Override
-            public Object run() {
-                method.setAccessible(true);
-                return null;
-            }
+        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
+            method.setAccessible(true);
+            return null;
         });
     }
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/concurrent/TestBasicFuture.java b/httpcore5/src/test/java/org/apache/hc/core5/concurrent/TestBasicFuture.java
index 3d837e7..62037f6 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/concurrent/TestBasicFuture.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/concurrent/TestBasicFuture.java
@@ -134,18 +134,13 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<>(null);
         final Object result = new Object();
 
-        final Thread t = new Thread() {
-
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(100);
-                    future.completed(result);
-                } catch (final InterruptedException boom) {
-                }
+        final Thread t = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+                future.completed(result);
+            } catch (final InterruptedException boom) {
             }
-
-        };
+        });
         t.setDaemon(true);
         t.start();
         Assert.assertSame(result, future.get(60, TimeUnit.SECONDS));
@@ -158,18 +153,13 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<>(null);
         final Exception boom = new Exception();
 
-        final Thread t = new Thread() {
-
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(100);
-                    future.failed(boom);
-                } catch (final InterruptedException ex) {
-                }
+        final Thread t = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+                future.failed(boom);
+            } catch (final InterruptedException ex) {
             }
-
-        };
+        });
         t.setDaemon(true);
         t.start();
         try {
@@ -185,18 +175,13 @@ public class TestBasicFuture {
     public void testAsyncCancelled() throws Exception {
         final BasicFuture<Object> future = new BasicFuture<>(null);
 
-        final Thread t = new Thread() {
-
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(100);
-                    future.cancel(true);
-                } catch (final InterruptedException ex) {
-                }
+        final Thread t = new Thread(() -> {
+            try {
+                Thread.sleep(100);
+                future.cancel(true);
+            } catch (final InterruptedException ex) {
             }
-
-        };
+        });
         t.setDaemon(true);
         t.start();
         future.get(60, TimeUnit.SECONDS);
@@ -207,18 +192,13 @@ public class TestBasicFuture {
         final BasicFuture<Object> future = new BasicFuture<>(null);
         final Object result = new Object();
 
-        final Thread t = new Thread() {
-
-            @Override
-            public void run() {
-                try {
-                    Thread.sleep(200);
-                    future.completed(result);
-                } catch (final InterruptedException ex) {
-                }
+        final Thread t = new Thread(() -> {
+            try {
+                Thread.sleep(200);
+                future.completed(result);
+            } catch (final InterruptedException ex) {
             }
-
-        };
+        });
         t.setDaemon(true);
         t.start();
         future.get(1, TimeUnit.MILLISECONDS);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
index 7b658d1..6ada5ce 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFileServerExample.java
@@ -49,7 +49,7 @@ import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
 import org.apache.hc.core5.http.nio.entity.AsyncEntityProducers;
-import org.apache.hc.core5.http.nio.entity.NoopEntityConsumer;
+import org.apache.hc.core5.http.nio.entity.DiscardingEntityConsumer;
 import org.apache.hc.core5.http.nio.support.AsyncResponseBuilder;
 import org.apache.hc.core5.http.nio.support.BasicRequestConsumer;
 import org.apache.hc.core5.http.protocol.HttpContext;
@@ -94,7 +94,7 @@ public class AsyncFileServerExample {
                             final HttpRequest request,
                             final EntityDetails entityDetails,
                             final HttpContext context) throws HttpException {
-                        return new BasicRequestConsumer<>(entityDetails != null ? new NoopEntityConsumer() : null);
+                        return new BasicRequestConsumer<>(entityDetails != null ? new DiscardingEntityConsumer<>() : null);
                     }
 
                     @Override
@@ -160,13 +160,10 @@ public class AsyncFileServerExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
@@ -175,7 +172,7 @@ public class AsyncFileServerExample {
         server.awaitShutdown(TimeValue.MAX_VALUE);
     }
 
-    static final void println(final String msg) {
+    static void println(final String msg) {
         System.out.println(HttpDateGenerator.INSTANCE.getCurrentDate() + " | " + msg);
     }
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
index b1aa26b..a47a91a 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexClientExample.java
@@ -73,18 +73,10 @@ public class AsyncFullDuplexClientExample {
                 .build();
 
         // Create and start requester
+        // Disable 'Expect: Continue' handshake some servers cannot handle well
         final HttpAsyncRequester requester = AsyncRequesterBootstrap.bootstrap()
                 .setIOReactorConfig(ioReactorConfig)
-                .setHttpProcessor(HttpProcessors.customClient(null).addLast(new HttpRequestInterceptor() {
-
-                    // Disable 'Expect: Continue' handshake some servers cannot handle well
-                    @Override
-                    public void process(
-                            final HttpRequest request, final EntityDetails entity, final HttpContext context) throws HttpException, IOException {
-                        request.removeHeaders(HttpHeaders.EXPECT);
-                    }
-
-                }).build())
+                .setHttpProcessor(HttpProcessors.customClient(null).addLast((HttpRequestInterceptor) (request, entity, context) -> request.removeHeaders(HttpHeaders.EXPECT)).build())
                 .setStreamListener(new Http1StreamListener() {
 
                     @Override
@@ -110,13 +102,10 @@ public class AsyncFullDuplexClientExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final URI requestUri = new URI("http://httpbin.org/post");
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexServerExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexServerExample.java
index 12dd394..0e3a786 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexServerExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncFullDuplexServerExample.java
@@ -34,7 +34,6 @@ import java.util.List;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.EntityDetails;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.HttpConnection;
@@ -99,122 +98,112 @@ public class AsyncFullDuplexServerExample {
                     }
 
                 })
-                .register("/echo", new Supplier<AsyncServerExchangeHandler>() {
+                .register("/echo", () -> new AsyncServerExchangeHandler() {
+
+                    ByteBuffer buffer = ByteBuffer.allocate(2048);
+                    CapacityChannel inputCapacityChannel;
+                    DataStreamChannel outputDataChannel;
+                    boolean endStream;
+
+                    private void ensureCapacity(final int chunk) {
+                        if (buffer.remaining() < chunk) {
+                            final ByteBuffer oldBuffer = buffer;
+                            oldBuffer.flip();
+                            buffer = ByteBuffer.allocate(oldBuffer.remaining() + (chunk > 2048 ? chunk : 2048));
+                            buffer.put(oldBuffer);
+                        }
+                    }
 
                     @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new AsyncServerExchangeHandler() {
-
-                            ByteBuffer buffer = ByteBuffer.allocate(2048);
-                            CapacityChannel inputCapacityChannel;
-                            DataStreamChannel outputDataChannel;
-                            boolean endStream;
-
-                            private void ensureCapacity(final int chunk) {
-                                if (buffer.remaining() < chunk) {
-                                    final ByteBuffer oldBuffer = buffer;
-                                    oldBuffer.flip();
-                                    buffer = ByteBuffer.allocate(oldBuffer.remaining() + (chunk > 2048 ? chunk : 2048));
-                                    buffer.put(oldBuffer);
-                                }
-                            }
+                    public void handleRequest(
+                            final HttpRequest request,
+                            final EntityDetails entityDetails,
+                            final ResponseChannel responseChannel,
+                            final HttpContext context) throws HttpException, IOException {
+                        final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
+                        responseChannel.sendResponse(response, entityDetails, context);
+                    }
 
-                            @Override
-                            public void handleRequest(
-                                    final HttpRequest request,
-                                    final EntityDetails entityDetails,
-                                    final ResponseChannel responseChannel,
-                                    final HttpContext context) throws HttpException, IOException {
-                                final HttpResponse response = new BasicHttpResponse(HttpStatus.SC_OK);
-                                responseChannel.sendResponse(response, entityDetails, context);
+                    @Override
+                    public void consume(final ByteBuffer src) throws IOException {
+                        if (buffer.position() == 0) {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.write(src);
                             }
-
-                            @Override
-                            public void consume(final ByteBuffer src) throws IOException {
-                                if (buffer.position() == 0) {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.write(src);
-                                    }
-                                }
-                                if (src.hasRemaining()) {
-                                    ensureCapacity(src.remaining());
-                                    buffer.put(src);
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.requestOutput();
-                                    }
-                                }
+                        }
+                        if (src.hasRemaining()) {
+                            ensureCapacity(src.remaining());
+                            buffer.put(src);
+                            if (outputDataChannel != null) {
+                                outputDataChannel.requestOutput();
                             }
+                        }
+                    }
 
-                            @Override
-                            public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
-                                if (buffer.hasRemaining()) {
-                                    capacityChannel.update(buffer.remaining());
-                                    inputCapacityChannel = null;
-                                } else {
-                                    inputCapacityChannel = capacityChannel;
-                                }
-                            }
+                    @Override
+                    public void updateCapacity(final CapacityChannel capacityChannel) throws IOException {
+                        if (buffer.hasRemaining()) {
+                            capacityChannel.update(buffer.remaining());
+                            inputCapacityChannel = null;
+                        } else {
+                            inputCapacityChannel = capacityChannel;
+                        }
+                    }
 
-                            @Override
-                            public void streamEnd(final List<? extends Header> trailers) throws IOException {
-                                endStream = true;
-                                if (buffer.position() == 0) {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.endStream();
-                                    }
-                                } else {
-                                    if (outputDataChannel != null) {
-                                        outputDataChannel.requestOutput();
-                                    }
-                                }
+                    @Override
+                    public void streamEnd(final List<? extends Header> trailers) throws IOException {
+                        endStream = true;
+                        if (buffer.position() == 0) {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.endStream();
                             }
-
-                            @Override
-                            public int available() {
-                                return buffer.position();
+                        } else {
+                            if (outputDataChannel != null) {
+                                outputDataChannel.requestOutput();
                             }
+                        }
+                    }
 
-                            @Override
-                            public void produce(final DataStreamChannel channel) throws IOException {
-                                outputDataChannel = channel;
-                                buffer.flip();
-                                if (buffer.hasRemaining()) {
-                                    channel.write(buffer);
-                                }
-                                buffer.compact();
-                                if (buffer.position() == 0 && endStream) {
-                                    channel.endStream();
-                                }
-                                final CapacityChannel capacityChannel = inputCapacityChannel;
-                                if (capacityChannel != null && buffer.hasRemaining()) {
-                                    capacityChannel.update(buffer.remaining());
-                                }
-                            }
+                    @Override
+                    public int available() {
+                        return buffer.position();
+                    }
 
-                            @Override
-                            public void failed(final Exception cause) {
-                                if (!(cause instanceof SocketException)) {
-                                    cause.printStackTrace(System.out);
-                                }
-                            }
+                    @Override
+                    public void produce(final DataStreamChannel channel) throws IOException {
+                        outputDataChannel = channel;
+                        buffer.flip();
+                        if (buffer.hasRemaining()) {
+                            channel.write(buffer);
+                        }
+                        buffer.compact();
+                        if (buffer.position() == 0 && endStream) {
+                            channel.endStream();
+                        }
+                        final CapacityChannel capacityChannel = inputCapacityChannel;
+                        if (capacityChannel != null && buffer.hasRemaining()) {
+                            capacityChannel.update(buffer.remaining());
+                        }
+                    }
 
-                            @Override
-                            public void releaseResources() {
-                            }
+                    @Override
+                    public void failed(final Exception cause) {
+                        if (!(cause instanceof SocketException)) {
+                            cause.printStackTrace(System.out);
+                        }
+                    }
 
-                        };
+                    @Override
+                    public void releaseResources() {
                     }
 
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncPipelinedRequestExecutionExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncPipelinedRequestExecutionExample.java
index 6b84b07..5989e75 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncPipelinedRequestExecutionExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncPipelinedRequestExecutionExample.java
@@ -88,13 +88,10 @@ public class AsyncPipelinedRequestExecutionExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("httpbin.org");
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncRequestExecutionExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncRequestExecutionExample.java
index 49f41da..30ff900 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncRequestExecutionExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncRequestExecutionExample.java
@@ -85,13 +85,10 @@ public class AsyncRequestExecutionExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP requester shutting down");
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP requester shutting down");
+            requester.close(CloseMode.GRACEFUL);
+        }));
         requester.start();
 
         final HttpHost target = new HttpHost("httpbin.org");
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
index 5771d97..b0f3288 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncReverseProxyExample.java
@@ -43,7 +43,6 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.hc.core5.concurrent.FutureCallback;
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.EntityDetails;
@@ -184,24 +183,14 @@ public class AsyncReverseProxyExample {
                     }
 
                 })
-                .register("*", new Supplier<AsyncServerExchangeHandler>() {
-
-                    @Override
-                    public AsyncServerExchangeHandler get() {
-                        return new IncomingExchangeHandler(targetHost, requester);
-                    }
-
-                })
+                .register("*", () -> new IncomingExchangeHandler(targetHost, requester))
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                println("Reverse proxy shutting down");
-                server.close(CloseMode.GRACEFUL);
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            println("Reverse proxy shutting down");
+            server.close(CloseMode.GRACEFUL);
+            requester.close(CloseMode.GRACEFUL);
+        }));
 
         requester.start();
         server.start();
@@ -690,7 +679,7 @@ public class AsyncReverseProxyExample {
 
     }
 
-    static final void println(final String msg) {
+    static void println(final String msg) {
         if (!quiet) {
             System.out.println(HttpDateGenerator.INSTANCE.getCurrentDate() + " | " + msg);
         }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
index 216bbd9..d13c52d 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/AsyncServerFilterExample.java
@@ -42,10 +42,8 @@ import org.apache.hc.core5.http.impl.bootstrap.AsyncServerBootstrap;
 import org.apache.hc.core5.http.impl.bootstrap.HttpAsyncServer;
 import org.apache.hc.core5.http.impl.bootstrap.StandardFilter;
 import org.apache.hc.core5.http.message.BasicHttpResponse;
-import org.apache.hc.core5.http.nio.AsyncDataConsumer;
 import org.apache.hc.core5.http.nio.AsyncEntityProducer;
 import org.apache.hc.core5.http.nio.AsyncFilterChain;
-import org.apache.hc.core5.http.nio.AsyncFilterHandler;
 import org.apache.hc.core5.http.nio.AsyncPushProducer;
 import org.apache.hc.core5.http.nio.AsyncRequestConsumer;
 import org.apache.hc.core5.http.nio.AsyncServerRequestHandler;
@@ -112,45 +110,35 @@ public class AsyncServerFilterExample {
 
                 // Add a custom request filter at the beginning of the processing pipeline
 
-                .addFilterFirst("my-filter", new AsyncFilterHandler() {
+                .addFilterFirst("my-filter", (request, entityDetails, context, responseTrigger, chain) -> {
+                    if (request.getRequestUri().equals("/back-door")) {
+                        responseTrigger.submitResponse(
+                                new BasicHttpResponse(HttpStatus.SC_OK),
+                                AsyncEntityProducers.create("Welcome"));
+                        return null;
+                    }
+                    return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
 
-                    @Override
-                    public AsyncDataConsumer handle(
-                            final HttpRequest request,
-                            final EntityDetails entityDetails,
-                            final HttpContext context,
-                            final AsyncFilterChain.ResponseTrigger responseTrigger,
-                            final AsyncFilterChain chain) throws HttpException, IOException {
-                        if (request.getRequestUri().equals("/back-door")) {
-                            responseTrigger.submitResponse(
-                                    new BasicHttpResponse(HttpStatus.SC_OK),
-                                    AsyncEntityProducers.create("Welcome"));
-                            return null;
+                        @Override
+                        public void sendInformation(
+                                final HttpResponse response) throws HttpException, IOException {
+                            responseTrigger.sendInformation(response);
+                        }
+
+                        @Override
+                        public void submitResponse(
+                                final HttpResponse response, final AsyncEntityProducer entityProducer) throws HttpException, IOException {
+                            response.addHeader("X-Filter", "My-Filter");
+                            responseTrigger.submitResponse(response, entityProducer);
+                        }
+
+                        @Override
+                        public void pushPromise(
+                                final HttpRequest promise, final AsyncPushProducer responseProducer) throws HttpException, IOException {
+                            responseTrigger.pushPromise(promise, responseProducer);
                         }
-                        return chain.proceed(request, entityDetails, context, new AsyncFilterChain.ResponseTrigger() {
-
-                            @Override
-                            public void sendInformation(
-                                    final HttpResponse response) throws HttpException, IOException {
-                                responseTrigger.sendInformation(response);
-                            }
-
-                            @Override
-                            public void submitResponse(
-                                    final HttpResponse response, final AsyncEntityProducer entityProducer) throws HttpException, IOException {
-                                response.addHeader("X-Filter", "My-Filter");
-                                responseTrigger.submitResponse(response, entityProducer);
-                            }
-
-                            @Override
-                            public void pushPromise(
-                                    final HttpRequest promise, final AsyncPushProducer responseProducer) throws HttpException, IOException {
-                                responseTrigger.pushPromise(promise, responseProducer);
-                            }
-
-                        });
-                    }
 
+                    });
                 })
 
                 // Application request handler
@@ -180,13 +168,10 @@ public class AsyncServerFilterExample {
                 })
                 .create();
 
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                System.out.println("HTTP server shutting down");
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            System.out.println("HTTP server shutting down");
+            server.close(CloseMode.GRACEFUL);
+        }));
 
         server.start();
         final Future<ListenerEndpoint> future = server.listen(new InetSocketAddress(port), URIScheme.HTTP);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicFileServerExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
index a8fc9fd..b8fbfd7 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicFileServerExample.java
@@ -47,8 +47,8 @@ import org.apache.hc.core5.http.HttpConnection;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.MethodNotSupportedException;
 import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.MethodNotSupportedException;
 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;
@@ -124,12 +124,7 @@ public class ClassicFileServerExample {
                 .create();
 
         server.start();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> server.close(CloseMode.GRACEFUL)));
         System.out.println("Listening on port " + port);
 
         server.awaitTermination(TimeValue.MAX_VALUE);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
index 78f7358..fa79ae6 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicPostExecutionExample.java
@@ -27,8 +27,6 @@
 
 package org.apache.hc.core5.http.examples;
 
-import java.io.IOException;
-import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 import java.util.concurrent.TimeUnit;
 
@@ -51,7 +49,6 @@ import org.apache.hc.core5.http.message.BasicHeader;
 import org.apache.hc.core5.http.message.RequestLine;
 import org.apache.hc.core5.http.message.StatusLine;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
-import org.apache.hc.core5.io.IOCallback;
 import org.apache.hc.core5.util.Timeout;
 
 /**
@@ -98,15 +95,8 @@ public class ClassicPostExecutionExample {
                 HttpEntities.create(
                         "This is the second test request".getBytes(StandardCharsets.UTF_8),
                         ContentType.APPLICATION_OCTET_STREAM),
-                HttpEntities.create(new IOCallback<OutputStream>() {
-
-                    @Override
-                    public void execute(final OutputStream outStream) throws IOException {
-                        outStream.write(("This is the third test request " +
-                                "(streaming)").getBytes(StandardCharsets.UTF_8));
-                    }
-
-                }, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)),
+                HttpEntities.create(outStream -> outStream.write(("This is the third test request " +
+                        "(streaming)").getBytes(StandardCharsets.UTF_8)), ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8)),
                 HttpEntities.create(
                         "This is the fourth test request " +
                                 "(streaming with trailers)",
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
index 94ccf2b..c066aec 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicReverseProxyExample.java
@@ -177,13 +177,10 @@ public class ClassicReverseProxyExample {
                 .create();
 
         server.start();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                server.close(CloseMode.GRACEFUL);
-                requester.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+            server.close(CloseMode.GRACEFUL);
+            requester.close(CloseMode.GRACEFUL);
+        }));
 
         System.out.println("Listening on port " + port);
         server.awaitTermination(TimeValue.MAX_VALUE);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicServerFilterExample.java b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicServerFilterExample.java
index 2708b8a..252e47c 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicServerFilterExample.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/examples/ClassicServerFilterExample.java
@@ -30,18 +30,15 @@ package org.apache.hc.core5.http.examples;
 import java.io.IOException;
 import java.util.concurrent.TimeUnit;
 
-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.HttpException;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.io.SocketConfig;
 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.bootstrap.StandardFilter;
 import org.apache.hc.core5.http.io.HttpFilterChain;
-import org.apache.hc.core5.http.io.HttpFilterHandler;
-import org.apache.hc.core5.http.io.HttpRequestHandler;
+import org.apache.hc.core5.http.io.SocketConfig;
 import org.apache.hc.core5.http.io.entity.StringEntity;
 import org.apache.hc.core5.http.io.support.AbstractHttpServerAuthFilter;
 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
@@ -101,60 +98,40 @@ public class ClassicServerFilterExample {
 
                 // Add a custom request filter at the beginning of the processing pipeline
 
-                .addFilterFirst("my-filter", new HttpFilterHandler() {
-
-                    @Override
-                    public void handle(final ClassicHttpRequest request,
-                                       final HttpFilterChain.ResponseTrigger responseTrigger,
-                                       final HttpContext context, final HttpFilterChain chain) throws HttpException, IOException {
-                        if (request.getRequestUri().equals("/back-door")) {
-                            final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK);
-                            response.setEntity(new StringEntity("Welcome", ContentType.TEXT_PLAIN));
-                            responseTrigger.submitResponse(response);
-                        } else {
-                            chain.proceed(request, new HttpFilterChain.ResponseTrigger() {
-
-                                @Override
-                                public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException {
-                                    responseTrigger.sendInformation(response);
-                                }
-
-                                @Override
-                                public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
-                                    response.addHeader("X-Filter", "My-Filter");
-                                    responseTrigger.submitResponse(response);
-                                }
-
-                            }, context);
-                        }
+                .addFilterFirst("my-filter", (request, responseTrigger, context, chain) -> {
+                    if (request.getRequestUri().equals("/back-door")) {
+                        final ClassicHttpResponse response = new BasicClassicHttpResponse(HttpStatus.SC_OK);
+                        response.setEntity(new StringEntity("Welcome", ContentType.TEXT_PLAIN));
+                        responseTrigger.submitResponse(response);
+                    } else {
+                        chain.proceed(request, new HttpFilterChain.ResponseTrigger() {
+
+                            @Override
+                            public void sendInformation(final ClassicHttpResponse response) throws HttpException, IOException {
+                                responseTrigger.sendInformation(response);
+                            }
+
+                            @Override
+                            public void submitResponse(final ClassicHttpResponse response) throws HttpException, IOException {
+                                response.addHeader("X-Filter", "My-Filter");
+                                responseTrigger.submitResponse(response);
+                            }
+
+                        }, context);
                     }
-
                 })
 
                 // Application request handler
 
-                .register("*", new HttpRequestHandler() {
-
-                    @Override
-                    public void handle(
-                            final ClassicHttpRequest request,
-                            final ClassicHttpResponse response,
-                            final HttpContext context) throws HttpException, IOException {
-                        // do something useful
-                        response.setCode(HttpStatus.SC_OK);
-                        response.setEntity(new StringEntity("Hello"));
-                    }
-
+                .register("*", (request, response, context) -> {
+                    // do something useful
+                    response.setCode(HttpStatus.SC_OK);
+                    response.setEntity(new StringEntity("Hello"));
                 })
                 .create();
 
         server.start();
-        Runtime.getRuntime().addShutdownHook(new Thread() {
-            @Override
-            public void run() {
-                server.close(CloseMode.GRACEFUL);
-            }
-        });
+        Runtime.getRuntime().addShutdownHook(new Thread(() -> server.close(CloseMode.GRACEFUL)));
         System.out.println("Listening on port " + port);
 
         server.awaitTermination(TimeValue.MAX_VALUE);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestChunkCoding.java b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestChunkCoding.java
index 448ff1d..313abfa 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestChunkCoding.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestChunkCoding.java
@@ -33,9 +33,7 @@ import java.io.IOException;
 import java.io.InterruptedIOException;
 import java.nio.charset.StandardCharsets;
 import java.util.Arrays;
-import java.util.List;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.ConnectionClosedException;
 import org.apache.hc.core5.http.Header;
 import org.apache.hc.core5.http.MalformedChunkCodingException;
@@ -368,14 +366,9 @@ public class TestChunkCoding {
     public void testChunkedOutputStreamWithTrailers() throws IOException {
         final SessionOutputBuffer outbuffer = new SessionOutputBufferImpl(16);
         final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-        final ChunkedOutputStream out = new ChunkedOutputStream(outbuffer, outputStream, 2, new Supplier<List<? extends Header>>() {
-            @Override
-            public List<? extends Header> get() {
-                return Arrays.asList(
-                        new BasicHeader("E", ""),
-                        new BasicHeader("Y", "Z"));
-                }
-            }
+        final ChunkedOutputStream out = new ChunkedOutputStream(outbuffer, outputStream, 2, () -> Arrays.asList(
+                new BasicHeader("E", ""),
+                new BasicHeader("Y", "Z"))
         );
         out.write('x');
         out.finish();
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestHttpService.java b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestHttpService.java
index 889efe7..4b75ae6 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestHttpService.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/impl/io/TestHttpService.java
@@ -27,7 +27,6 @@
 
 package org.apache.hc.core5.http.impl.io;
 
-import java.io.IOException;
 import java.io.InputStream;
 import java.util.List;
 
@@ -35,14 +34,12 @@ import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
 import org.apache.hc.core5.http.ConnectionReuseStrategy;
 import org.apache.hc.core5.http.HeaderElements;
-import org.apache.hc.core5.http.HttpException;
 import org.apache.hc.core5.http.HttpHeaders;
 import org.apache.hc.core5.http.HttpRequestMapper;
-import org.apache.hc.core5.http.HttpResponse;
 import org.apache.hc.core5.http.HttpResponseFactory;
 import org.apache.hc.core5.http.HttpStatus;
-import org.apache.hc.core5.http.MethodNotSupportedException;
 import org.apache.hc.core5.http.Method;
+import org.apache.hc.core5.http.MethodNotSupportedException;
 import org.apache.hc.core5.http.ProtocolException;
 import org.apache.hc.core5.http.UnsupportedHttpVersionException;
 import org.apache.hc.core5.http.io.HttpRequestHandler;
@@ -50,14 +47,12 @@ import org.apache.hc.core5.http.io.HttpServerConnection;
 import org.apache.hc.core5.http.io.entity.InputStreamEntity;
 import org.apache.hc.core5.http.message.BasicClassicHttpRequest;
 import org.apache.hc.core5.http.message.BasicClassicHttpResponse;
-import org.apache.hc.core5.http.protocol.HttpContext;
 import org.apache.hc.core5.http.protocol.HttpCoreContext;
 import org.apache.hc.core5.http.protocol.HttpProcessor;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.mockito.ArgumentCaptor;
-import org.mockito.ArgumentMatcher;
 import org.mockito.ArgumentMatchers;
 import org.mockito.Mock;
 import org.mockito.Mockito;
@@ -140,14 +135,7 @@ public class TestHttpService {
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
         Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(new ArgumentMatcher<HttpResponse>() {
-
-            @Override
-            public boolean matches(final HttpResponse errorResponse) {
-                return errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED;
-            }
-
-        }), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE);
+        Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(errorResponse -> errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE);
 
         httpservice.handleRequest(conn, context);
         final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class);
@@ -180,14 +168,7 @@ public class TestHttpService {
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
         Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response);
-        Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(new ArgumentMatcher<HttpResponse>() {
-
-            @Override
-            public boolean matches(final HttpResponse errorResponse) {
-                return errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED;
-            }
-
-        }), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE);
+        Mockito.when(connReuseStrategy.keepAlive(ArgumentMatchers.eq(request), ArgumentMatchers.argThat(errorResponse -> errorResponse.getCode() == HttpStatus.SC_NOT_IMPLEMENTED), ArgumentMatchers.eq(context))).thenReturn(Boolean.TRUE);
 
         httpservice.handleRequest(conn, context);
         final ArgumentCaptor<ClassicHttpResponse> responseCaptor = ArgumentCaptor.forClass(ClassicHttpResponse.class);
@@ -326,16 +307,7 @@ public class TestHttpService {
 
         Mockito.when(conn.receiveRequestHeader()).thenReturn(request);
         Mockito.when(responseFactory.newHttpResponse(200)).thenReturn(response);
-        Mockito.when(handlerResolver.resolve(request, context)).thenReturn(new HttpRequestHandler() {
-
-            @Override
-            public void handle(
-                    final ClassicHttpRequest request,
-                    final ClassicHttpResponse response,
-                    final HttpContext context) throws HttpException, IOException {
-                response.setCode(HttpStatus.SC_NO_CONTENT);
-            }
-        });
+        Mockito.when(handlerResolver.resolve(request, context)).thenReturn((request1, response, context1) -> response.setCode(HttpStatus.SC_NO_CONTENT));
         Mockito.when(connReuseStrategy.keepAlive(request, response, context)).thenReturn(Boolean.TRUE);
 
         httpservice.handleRequest(conn, context);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestSerializableEntity.java b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestSerializableEntity.java
index ac72cb5..0a2069f 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestSerializableEntity.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/io/entity/TestSerializableEntity.java
@@ -42,9 +42,9 @@ public class TestSerializableEntity {
 
         private static final long serialVersionUID = 1833335861188359573L;
 
-        public int intValue = 4;
+        public final int intValue = 4;
 
-        public String stringValue = "Hello";
+        public final String stringValue = "Hello";
 
         public SerializableObject() {}
     }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedInputBuffer.java b/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedInputBuffer.java
index bbd7b69..bcacbc9 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedInputBuffer.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedInputBuffer.java
@@ -96,24 +96,14 @@ public class TestSharedInputBuffer {
         Mockito.reset(capacityChannel);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                final Charset charset = StandardCharsets.US_ASCII;
-                inputBuffer.fill(charset.encode("1234567890"));
-                return Boolean.TRUE;
-            }
-
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            final Charset charset = StandardCharsets.US_ASCII;
+            inputBuffer.fill(charset.encode("1234567890"));
+            return Boolean.TRUE;
         });
-        final Future<Integer> task2 = executorService.submit(new Callable<Integer>() {
-
-            @Override
-            public Integer call() throws Exception {
-                final byte[] tmp = new byte[20];
-                return inputBuffer.read(tmp, 0, tmp.length);
-            }
-
+        final Future<Integer> task2 = executorService.submit(() -> {
+            final byte[] tmp = new byte[20];
+            return inputBuffer.read(tmp, 0, tmp.length);
         });
 
         Assert.assertEquals(Boolean.TRUE, task1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
@@ -133,24 +123,12 @@ public class TestSharedInputBuffer {
         Mockito.reset(capacityChannel);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                final Charset charset = StandardCharsets.US_ASCII;
-                inputBuffer.fill(charset.encode("a"));
-                return Boolean.TRUE;
-            }
-
-        });
-        final Future<Integer> task2 = executorService.submit(new Callable<Integer>() {
-
-            @Override
-            public Integer call() throws Exception {
-                return inputBuffer.read();
-            }
-
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            final Charset charset = StandardCharsets.US_ASCII;
+            inputBuffer.fill(charset.encode("a"));
+            return Boolean.TRUE;
         });
+        final Future<Integer> task2 = executorService.submit((Callable<Integer>) inputBuffer::read);
 
         Assert.assertEquals(Boolean.TRUE, task1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
         Assert.assertEquals(Integer.valueOf('a'), task2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
@@ -169,35 +147,25 @@ public class TestSharedInputBuffer {
         Mockito.reset(capacityChannel);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                final Charset charset = StandardCharsets.US_ASCII;
-                final Random rnd = new Random(System.currentTimeMillis());
-                for (int i = 0; i < 5; i++) {
-                    inputBuffer.fill(charset.encode("1234567890"));
-                    Thread.sleep(rnd.nextInt(250));
-                }
-                inputBuffer.markEndStream();
-                return Boolean.TRUE;
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            final Charset charset = StandardCharsets.US_ASCII;
+            final Random rnd = new Random(System.currentTimeMillis());
+            for (int i = 0; i < 5; i++) {
+                inputBuffer.fill(charset.encode("1234567890"));
+                Thread.sleep(rnd.nextInt(250));
             }
-
+            inputBuffer.markEndStream();
+            return Boolean.TRUE;
         });
-        final Future<String> task2 = executorService.submit(new Callable<String>() {
-
-            @Override
-            public String call() throws Exception {
-                final Charset charset = StandardCharsets.US_ASCII;
-                final StringBuilder buf = new StringBuilder();
-                final byte[] tmp = new byte[10];
-                int l;
-                while ((l = inputBuffer.read(tmp, 0, tmp.length)) != -1) {
-                    buf.append(charset.decode(ByteBuffer.wrap(tmp, 0, l)));
-                }
-                return buf.toString();
+        final Future<String> task2 = executorService.submit(() -> {
+            final Charset charset = StandardCharsets.US_ASCII;
+            final StringBuilder buf = new StringBuilder();
+            final byte[] tmp = new byte[10];
+            int l;
+            while ((l = inputBuffer.read(tmp, 0, tmp.length)) != -1) {
+                buf.append(charset.decode(ByteBuffer.wrap(tmp, 0, l)));
             }
-
+            return buf.toString();
         });
 
         Assert.assertEquals(Boolean.TRUE, task1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
@@ -218,24 +186,12 @@ public class TestSharedInputBuffer {
         Mockito.reset(capacityChannel);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                Thread.sleep(1000);
-                inputBuffer.abort();
-                return Boolean.TRUE;
-            }
-
-        });
-        final Future<Integer> task2 = executorService.submit(new Callable<Integer>() {
-
-            @Override
-            public Integer call() throws Exception {
-                return inputBuffer.read();
-            }
-
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            Thread.sleep(1000);
+            inputBuffer.abort();
+            return Boolean.TRUE;
         });
+        final Future<Integer> task2 = executorService.submit((Callable<Integer>) inputBuffer::read);
 
         Assert.assertEquals(Boolean.TRUE, task1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
         Assert.assertEquals(Integer.valueOf(-1), task2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedOutputBuffer.java b/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedOutputBuffer.java
index 6858dc2..61af5c9 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedOutputBuffer.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/nio/support/classic/TestSharedOutputBuffer.java
@@ -33,7 +33,6 @@ import java.nio.ByteBuffer;
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.util.List;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
@@ -148,40 +147,30 @@ public class TestSharedOutputBuffer {
         final DataStreamChannelMock dataStreamChannel = new DataStreamChannelMock(channel);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                final byte[] tmp = "1234567890".getBytes(charset);
-                outputBuffer.write(tmp, 0, tmp.length);
-                outputBuffer.write(tmp, 0, tmp.length);
-                outputBuffer.write('1');
-                outputBuffer.write('2');
-                outputBuffer.write(tmp, 0, tmp.length);
-                outputBuffer.write(tmp, 0, tmp.length);
-                outputBuffer.write(tmp, 0, tmp.length);
-                outputBuffer.writeCompleted();
-                outputBuffer.writeCompleted();
-                return Boolean.TRUE;
-            }
-
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            final byte[] tmp = "1234567890".getBytes(charset);
+            outputBuffer.write(tmp, 0, tmp.length);
+            outputBuffer.write(tmp, 0, tmp.length);
+            outputBuffer.write('1');
+            outputBuffer.write('2');
+            outputBuffer.write(tmp, 0, tmp.length);
+            outputBuffer.write(tmp, 0, tmp.length);
+            outputBuffer.write(tmp, 0, tmp.length);
+            outputBuffer.writeCompleted();
+            outputBuffer.writeCompleted();
+            return Boolean.TRUE;
         });
-        final Future<Boolean> task2 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                for (;;) {
-                    outputBuffer.flush(dataStreamChannel);
-                    if (outputBuffer.isEndStream()) {
-                        break;
-                    }
-                    if (!outputBuffer.hasData()) {
-                        dataStreamChannel.awaitOutputRequest();
-                    }
+        final Future<Boolean> task2 = executorService.submit(() -> {
+            for (;;) {
+                outputBuffer.flush(dataStreamChannel);
+                if (outputBuffer.isEndStream()) {
+                    break;
+                }
+                if (!outputBuffer.hasData()) {
+                    dataStreamChannel.awaitOutputRequest();
                 }
-                return Boolean.TRUE;
             }
-
+            return Boolean.TRUE;
         });
 
         Assert.assertEquals(Boolean.TRUE, task1.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
@@ -197,28 +186,18 @@ public class TestSharedOutputBuffer {
         final SharedOutputBuffer outputBuffer = new SharedOutputBuffer(20);
 
         final ExecutorService executorService = Executors.newFixedThreadPool(2);
-        final Future<Boolean> task1 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                final byte[] tmp = "1234567890".getBytes(charset);
-                for (int i = 0; i < 20; i++) {
-                    outputBuffer.write(tmp, 0, tmp.length);
-                }
-                outputBuffer.writeCompleted();
-                return Boolean.TRUE;
+        final Future<Boolean> task1 = executorService.submit(() -> {
+            final byte[] tmp = "1234567890".getBytes(charset);
+            for (int i = 0; i < 20; i++) {
+                outputBuffer.write(tmp, 0, tmp.length);
             }
-
+            outputBuffer.writeCompleted();
+            return Boolean.TRUE;
         });
-        final Future<Boolean> task2 = executorService.submit(new Callable<Boolean>() {
-
-            @Override
-            public Boolean call() throws Exception {
-                Thread.sleep(200);
-                outputBuffer.abort();
-                return Boolean.TRUE;
-            }
-
+        final Future<Boolean> task2 = executorService.submit(() -> {
+            Thread.sleep(200);
+            outputBuffer.abort();
+            return Boolean.TRUE;
         });
 
         Assert.assertEquals(Boolean.TRUE, task2.get(TIMEOUT.getDuration(), TIMEOUT.getTimeUnit()));
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestRequestHandlerRegistry.java b/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestRequestHandlerRegistry.java
index dbbfa71..7b813c2 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestRequestHandlerRegistry.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/http/protocol/TestRequestHandlerRegistry.java
@@ -27,7 +27,6 @@
 
 package org.apache.hc.core5.http.protocol;
 
-import org.apache.hc.core5.function.Supplier;
 import org.apache.hc.core5.http.HttpHost;
 import org.apache.hc.core5.http.Method;
 import org.apache.hc.core5.http.MisdirectedRequestException;
@@ -43,14 +42,7 @@ public class TestRequestHandlerRegistry {
 
     @Before
     public void setUp() {
-        handlerRegistry = new RequestHandlerRegistry<>("myhost", new Supplier<LookupRegistry<String>>() {
-
-            @Override
-            public LookupRegistry<String> get() {
-                return new UriPatternMatcher<>();
-            }
-
-        });
+        handlerRegistry = new RequestHandlerRegistry<>("myhost", UriPatternMatcher::new);
         context = new BasicHttpContext();
     }
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java
index fcfc750..784c1a0 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/net/TestURIBuilder.java
@@ -317,7 +317,7 @@ public class TestURIBuilder {
     @Test
     public void testSetParametersWithEmptyList() throws Exception {
         final URI uri = new URI("http", null, "localhost", 80, "/test", "param=test", null);
-        final URIBuilder uribuilder = new URIBuilder(uri).setParameters(Arrays.<NameValuePair>asList());
+        final URIBuilder uribuilder = new URIBuilder(uri).setParameters(Collections.<NameValuePair>emptyList());
         final URI result = uribuilder.build();
         Assert.assertEquals(new URI("http://localhost:80/test"), result);
     }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestLaxConnPool.java b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestLaxConnPool.java
index 8547ff2..db64b55 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestLaxConnPool.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestLaxConnPool.java
@@ -114,7 +114,7 @@ public class TestLaxConnPool {
     @Test(expected = IllegalStateException.class)
     public void testReleaseUnknownEntry() throws Exception {
         final LaxConnPool<String, HttpConnection> pool = new LaxConnPool<>(2);
-        pool.release(new PoolEntry<String, HttpConnection>("somehost"), true);
+        pool.release(new PoolEntry<>("somehost"), true);
     }
 
     @Test
@@ -403,7 +403,7 @@ public class TestLaxConnPool {
         } catch (final IllegalStateException expected) {
         }
         // Ignored if shut down
-        pool.release(new PoolEntry<String, HttpConnection>("somehost"), true);
+        pool.release(new PoolEntry<>("somehost"), true);
     }
 
 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestPoolEntry.java b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestPoolEntry.java
index 97aafe6..17d887f 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestPoolEntry.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestPoolEntry.java
@@ -47,14 +47,7 @@ public class TestPoolEntry {
     @Before
     public void setup() {
         count = new AtomicLong(1);
-        currentTimeSupplier = new Supplier<Long>() {
-
-            @Override
-            public Long get() {
-                return count.addAndGet(1);
-            }
-
-        };
+        currentTimeSupplier = () -> count.addAndGet(1);
     }
 
     @Test
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestStrictConnPool.java b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestStrictConnPool.java
index a0484d2..687b714 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/pool/TestStrictConnPool.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/pool/TestStrictConnPool.java
@@ -33,7 +33,6 @@ import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
-import org.apache.hc.core5.function.Callback;
 import org.apache.hc.core5.http.HttpConnection;
 import org.apache.hc.core5.io.CloseMode;
 import org.apache.hc.core5.util.DeadlineTimeoutException;
@@ -129,7 +128,7 @@ public class TestStrictConnPool {
     @Test(expected = IllegalStateException.class)
     public void testReleaseUnknownEntry() throws Exception {
         final StrictConnPool<String, HttpConnection> pool = new StrictConnPool<>(2, 2);
-        pool.release(new PoolEntry<String, HttpConnection>("somehost"), true);
+        pool.release(new PoolEntry<>("somehost"), true);
     }
 
     @Test
@@ -519,21 +518,15 @@ public class TestStrictConnPool {
 
     private static class HoldInternalLockThread extends Thread {
         private HoldInternalLockThread(final StrictConnPool<String, HttpConnection> pool, final CountDownLatch lockHeld) {
-            super(new Runnable() {
-                @Override
-                public void run() {
-                    pool.lease("somehost", null); // lease a connection so we have something to enumLeased()
-                    pool.enumLeased(new Callback<PoolEntry<String, HttpConnection>>() {
-                        @Override
-                        public void execute(final PoolEntry<String, HttpConnection> object) {
-                            try {
-                                lockHeld.countDown();
-                                Thread.sleep(Long.MAX_VALUE);
-                            } catch (final InterruptedException ignored) {
-                            }
-                        }
-                    });
-                }
+            super(() -> {
+                pool.lease("somehost", null); // lease a connection so we have something to enumLeased()
+                pool.enumLeased(object -> {
+                    try {
+                        lockHeld.countDown();
+                        Thread.sleep(Long.MAX_VALUE);
+                    } catch (final InterruptedException ignored) {
+                    }
+                });
             });
         }
     }
@@ -651,7 +644,7 @@ public class TestStrictConnPool {
         } catch (final IllegalStateException expected) {
         }
         // Ignored if shut down
-        pool.release(new PoolEntry<String, HttpConnection>("somehost"), true);
+        pool.release(new PoolEntry<>("somehost"), true);
     }
 
 }
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java b/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
index 83febce..56550d6 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/reactor/TestAbstractIOSessionPool.java
@@ -39,13 +39,10 @@ import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Answers;
-import org.mockito.ArgumentMatcher;
 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;
 
 @RunWith(MockitoJUnitRunner.class)
 public class TestAbstractIOSessionPool {
@@ -78,15 +75,10 @@ public class TestAbstractIOSessionPool {
                 ArgumentMatchers.<Timeout>any(),
                 ArgumentMatchers.<FutureCallback<IOSession>>any())).thenReturn(connectFuture);
 
-        Mockito.doAnswer(new Answer() {
-
-            @Override
-            public Object answer(final InvocationOnMock invocation) throws Throwable {
-                final Callback<Boolean> callback = invocation.getArgument(1);
-                callback.execute(true);
-                return null;
-            }
-
+        Mockito.doAnswer(invocation -> {
+            final Callback<Boolean> callback = invocation.getArgument(1);
+            callback.execute(true);
+            return null;
         }).when(impl).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
 
         Mockito.when(ioSession1.isOpen()).thenReturn(true);
@@ -109,14 +101,9 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.<Timeout>any(),
-                ArgumentMatchers.argThat(new ArgumentMatcher<FutureCallback<IOSession>>() {
-
-                    @Override
-                    public boolean matches(final FutureCallback<IOSession> callback) {
-                        callback.completed(ioSession1);
-                        return true;
-                    }
-
+                ArgumentMatchers.argThat(callback -> {
+                    callback.completed(ioSession1);
+                    return true;
                 }));
 
         MatcherAssert.assertThat(future1.isDone(), CoreMatchers.equalTo(true));
@@ -166,14 +153,9 @@ public class TestAbstractIOSessionPool {
         Mockito.verify(impl, Mockito.times(1)).connectSession(
                 ArgumentMatchers.eq("somehost"),
                 ArgumentMatchers.<Timeout>any(),
-                ArgumentMatchers.argThat(new ArgumentMatcher<FutureCallback<IOSession>>() {
-
-                    @Override
-                    public boolean matches(final FutureCallback<IOSession> callback) {
-                        callback.failed(new Exception("Boom"));
-                        return true;
-                    }
-
+                ArgumentMatchers.argThat(callback -> {
+                    callback.failed(new Exception("Boom"));
+                    return true;
                 }));
 
         MatcherAssert.assertThat(future1.isDone(), CoreMatchers.equalTo(true));
@@ -234,14 +216,7 @@ public class TestAbstractIOSessionPool {
         MatcherAssert.assertThat(entry2, CoreMatchers.notNullValue());
         entry2.session = ioSession2;
 
-        impl.enumAvailable(new Callback<IOSession>() {
-
-            @Override
-            public void execute(final IOSession ioSession) {
-                ioSession.close(CloseMode.GRACEFUL);
-            }
-
-        });
+        impl.enumAvailable(ioSession -> ioSession.close(CloseMode.GRACEFUL));
         Mockito.verify(ioSession1).close(CloseMode.GRACEFUL);
         Mockito.verify(ioSession2).close(CloseMode.GRACEFUL);
     }
@@ -253,15 +228,10 @@ public class TestAbstractIOSessionPool {
         entry1.session = ioSession1;
 
         Mockito.when(ioSession1.isOpen()).thenReturn(true);
-        Mockito.doAnswer(new Answer() {
-
-            @Override
-            public Object answer(final InvocationOnMock invocation) throws Throwable {
-                final Callback<Boolean> callback = invocation.getArgument(1);
-                callback.execute(false);
-                return null;
-            }
-
+        Mockito.doAnswer(invocation -> {
+            final Callback<Boolean> callback = invocation.getArgument(1);
+            callback.execute(false);
+            return null;
         }).when(impl).validateSession(ArgumentMatchers.<IOSession>any(), ArgumentMatchers.<Callback<Boolean>>any());
 
         impl.getSession("somehost", Timeout.ofSeconds(123L), null);
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/ssl/TestSSLContextBuilder.java b/httpcore5/src/test/java/org/apache/hc/core5/ssl/TestSSLContextBuilder.java
index bc36248..819fec3 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/ssl/TestSSLContextBuilder.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/ssl/TestSSLContextBuilder.java
@@ -40,13 +40,10 @@ import java.security.NoSuchAlgorithmException;
 import java.security.Principal;
 import java.security.Security;
 import java.security.UnrecoverableKeyException;
-import java.security.cert.CertificateException;
 import java.security.cert.X509Certificate;
 import java.util.Arrays;
 import java.util.LinkedHashSet;
-import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.Callable;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
@@ -57,7 +54,6 @@ import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLException;
 import javax.net.ssl.SSLHandshakeException;
-import javax.net.ssl.SSLParameters;
 import javax.net.ssl.SSLPeerUnverifiedException;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLSession;
@@ -91,7 +87,7 @@ public class TestSSLContextBuilder {
     }
 
     @Rule
-    public ExpectedException thrown = ExpectedException.none();
+    public final ExpectedException thrown = ExpectedException.none();
 
     private static final Timeout TIMEOUT = Timeout.ofSeconds(5);
     private ExecutorService executorService;
@@ -246,16 +242,13 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        final Future<Boolean> future = this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (Socket socket = serverSocket.accept()) {
-                    final OutputStream outputStream = socket.getOutputStream();
-                    outputStream.write(new byte[]{'H', 'i'});
-                    outputStream.flush();
-                }
-                return Boolean.TRUE;
+        final Future<Boolean> future = this.executorService.submit(() -> {
+            try (Socket socket = serverSocket.accept()) {
+                final OutputStream outputStream = socket.getOutputStream();
+                outputStream.write(new byte[]{'H', 'i'});
+                outputStream.flush();
             }
+            return Boolean.TRUE;
         });
 
         final int localPort = serverSocket.getLocalPort();
@@ -292,14 +285,11 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    socket.getSession();
-                }
-                return Boolean.FALSE;
+        this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                socket.getSession();
             }
+            return Boolean.FALSE;
         });
         final int localPort = serverSocket.getLocalPort();
         try (final SSLSocket clientSocket = (SSLSocket) clientSslContext.getSocketFactory().createSocket()) {
@@ -321,15 +311,9 @@ public class TestSSLContextBuilder {
 
         final AtomicReference<X509Certificate[]> certChainRef = new AtomicReference<>();
 
-        final TrustStrategy trustStrategy = new TrustStrategy() {
-
-            @Override
-            public boolean isTrusted(
-                    final X509Certificate[] chain, final String authType) throws CertificateException {
-                certChainRef.set(chain);
-                return true;
-            }
-
+        final TrustStrategy trustStrategy = (chain, authType) -> {
+            certChainRef.set(chain);
+            return true;
         };
 
         final SSLContext clientSslContext = SSLContextBuilder.create()
@@ -341,16 +325,13 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        final Future<Boolean> future = this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (Socket socket = serverSocket.accept()) {
-                    final OutputStream outputStream = socket.getOutputStream();
-                    outputStream.write(new byte[]{'H', 'i'});
-                    outputStream.flush();
-                }
-                return Boolean.TRUE;
+        final Future<Boolean> future = this.executorService.submit(() -> {
+            try (Socket socket = serverSocket.accept()) {
+                final OutputStream outputStream = socket.getOutputStream();
+                outputStream.write(new byte[]{'H', 'i'});
+                outputStream.flush();
             }
+            return Boolean.TRUE;
         });
 
         final int localPort = serverSocket.getLocalPort();
@@ -404,25 +385,22 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
-            @Override
-            public Principal call() throws Exception {
-                final SSLSocket socket = (SSLSocket) serverSocket.accept();
-                Principal clientPrincipal = null;
+        final Future<Principal> future = this.executorService.submit(() -> {
+            final SSLSocket socket = (SSLSocket) serverSocket.accept();
+            Principal clientPrincipal = null;
+            try {
+                final SSLSession session = socket.getSession();
                 try {
-                    final SSLSession session = socket.getSession();
-                    try {
-                        clientPrincipal = session.getPeerPrincipal();
-                    } catch (final SSLPeerUnverifiedException ignore) {
-                    }
-                    final OutputStream outputStream = socket.getOutputStream();
-                    outputStream.write(new byte [] {'H', 'i'});
-                    outputStream.flush();
-                } finally {
-                    socket.close();
+                    clientPrincipal = session.getPeerPrincipal();
+                } catch (final SSLPeerUnverifiedException ignore) {
                 }
-                return clientPrincipal;
+                final OutputStream outputStream = socket.getOutputStream();
+                outputStream.write(new byte [] {'H', 'i'});
+                outputStream.flush();
+            } finally {
+                socket.close();
             }
+            return clientPrincipal;
         });
 
         final int localPort = serverSocket.getLocalPort();
@@ -461,14 +439,11 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    socket.getSession();
-                }
-                return Boolean.FALSE;
+        this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                socket.getSession();
             }
+            return Boolean.FALSE;
         });
 
         final int localPort = serverSocket.getLocalPort();
@@ -502,17 +477,14 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
-            @Override
-            public Principal call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    final SSLSession session = socket.getSession();
-                    final Principal clientPrincipal = session.getPeerPrincipal();
-                    final OutputStream outputStream = socket.getOutputStream();
-                    outputStream.write(new byte[]{'H', 'i'});
-                    outputStream.flush();
-                    return clientPrincipal;
-                }
+        final Future<Principal> future = this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                final SSLSession session = socket.getSession();
+                final Principal clientPrincipal = session.getPeerPrincipal();
+                final OutputStream outputStream = socket.getOutputStream();
+                outputStream.write(new byte[]{'H', 'i'});
+                outputStream.flush();
+                return clientPrincipal;
             }
         });
         final int localPort = serverSocket.getLocalPort();
@@ -541,13 +513,7 @@ public class TestSSLContextBuilder {
                 .build();
         Assert.assertNotNull(serverSslContext);
 
-        final PrivateKeyStrategy privateKeyStrategy = new PrivateKeyStrategy() {
-            @Override
-            public String chooseAlias(final Map<String, PrivateKeyDetails> aliases,
-                            final SSLParameters sslParameters) {
-                return aliases.containsKey("client2") ? "client2" : null;
-            }
-        };
+        final PrivateKeyStrategy privateKeyStrategy = (aliases, sslParameters) -> aliases.containsKey("client2") ? "client2" : null;
 
         final URL resource2 = getResource("/test-client.p12");
         final SSLContext clientSslContext = SSLContextBuilder.create()
@@ -560,17 +526,14 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        final Future<Principal> future = this.executorService.submit(new Callable<Principal>() {
-            @Override
-            public Principal call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    final SSLSession session = socket.getSession();
-                    final Principal clientPrincipal = session.getPeerPrincipal();
-                    final OutputStream outputStream = socket.getOutputStream();
-                    outputStream.write(new byte[]{'H', 'i'});
-                    outputStream.flush();
-                    return clientPrincipal;
-                }
+        final Future<Principal> future = this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                final SSLSession session = socket.getSession();
+                final Principal clientPrincipal = session.getPeerPrincipal();
+                final OutputStream outputStream = socket.getOutputStream();
+                outputStream.write(new byte[]{'H', 'i'});
+                outputStream.flush();
+                return clientPrincipal;
             }
         });
         final int localPort = serverSocket.getLocalPort();
@@ -617,14 +580,11 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    socket.getSession();
-                }
-                return Boolean.FALSE;
+        this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                socket.getSession();
             }
+            return Boolean.FALSE;
         });
 
         final int localPort = serverSocket.getLocalPort();
@@ -665,14 +625,11 @@ public class TestSSLContextBuilder {
         serverSocket.bind(new InetSocketAddress(0));
 
         this.executorService = Executors.newSingleThreadExecutor();
-        this.executorService.submit(new Callable<Boolean>() {
-            @Override
-            public Boolean call() throws Exception {
-                try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
-                    socket.getSession();
-                }
-                return Boolean.FALSE;
+        this.executorService.submit(() -> {
+            try (SSLSocket socket = (SSLSocket) serverSocket.accept()) {
+                socket.getSession();
             }
+            return Boolean.FALSE;
         });
 
         final int localPort = serverSocket.getLocalPort();
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java b/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
index f21635f..c7efa11 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/util/TestArgs.java
@@ -98,7 +98,7 @@ public class TestArgs {
 
     @Test
     public void testArgCollectionNotEmptyPass() {
-        final List<String> list = Arrays.asList("stuff");
+        final List<String> list = Collections.singletonList("stuff");
         Assert.assertSame(list, Args.notEmpty(list, "List"));
     }
 
diff --git a/httpcore5/src/test/java/org/apache/hc/core5/util/TestAsserts.java b/httpcore5/src/test/java/org/apache/hc/core5/util/TestAsserts.java
index 32cb49c..2bbf1e7 100644
--- a/httpcore5/src/test/java/org/apache/hc/core5/util/TestAsserts.java
+++ b/httpcore5/src/test/java/org/apache/hc/core5/util/TestAsserts.java
@@ -51,7 +51,7 @@ public class TestAsserts {
 
     @Test(expected=IllegalStateException.class)
     public void testExpressionNotEmptyFail1() {
-        Asserts.notEmpty((String) null, "Stuff");
+        Asserts.notEmpty(null, "Stuff");
     }
 
     @Test(expected=IllegalStateException.class)
@@ -61,7 +61,7 @@ public class TestAsserts {
 
     @Test(expected=IllegalStateException.class)
     public void testExpressionNotEmptyBlank1() {
-        Asserts.notBlank((String) null, "Stuff");
+        Asserts.notBlank(null, "Stuff");
     }
 
     @Test(expected=IllegalStateException.class)
diff --git a/pom.xml b/pom.xml
index fa8dbfc..6af4857 100644
--- a/pom.xml
+++ b/pom.xml
@@ -60,8 +60,8 @@
 
   <properties>
     <!-- Override parent 7 setting for deprecation (only - other settings stand)-->
-    <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>
     <maven.compiler.showDeprecation>true</maven.compiler.showDeprecation>
     <conscrypt.version>2.2.1</conscrypt.version>
     <junit.version>4.13</junit.version>