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 2017/05/01 11:11:11 UTC

svn commit: r1793308 [6/11] - in /httpcomponents/httpclient/trunk: httpclient5-cache/src/main/java/org/apache/hc/client5/http/impl/cache/ httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/ httpclient5-cache/src/test/java/org/apache/...

Modified: httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestProtocolRequirements.java
URL: http://svn.apache.org/viewvc/httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestProtocolRequirements.java?rev=1793308&r1=1793307&r2=1793308&view=diff
==============================================================================
--- httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestProtocolRequirements.java (original)
+++ httpcomponents/httpclient/trunk/httpclient5-cache/src/test/java/org/apache/hc/client5/http/impl/cache/TestProtocolRequirements.java Mon May  1 11:11:09 2017
@@ -38,9 +38,7 @@ import java.util.regex.Pattern;
 import org.apache.hc.client5.http.HttpRoute;
 import org.apache.hc.client5.http.cache.HttpCacheEntry;
 import org.apache.hc.client5.http.protocol.ClientProtocolException;
-import org.apache.hc.client5.http.protocol.HttpClientContext;
-import org.apache.hc.client5.http.sync.methods.HttpExecutionAware;
-import org.apache.hc.client5.http.impl.sync.RoutedHttpRequest;
+import org.apache.hc.client5.http.sync.ExecChain;
 import org.apache.hc.client5.http.utils.DateUtils;
 import org.apache.hc.core5.http.ClassicHttpRequest;
 import org.apache.hc.core5.http.ClassicHttpResponse;
@@ -78,13 +76,12 @@ public class TestProtocolRequirements ex
     @Test
     public void testCacheMissOnGETUsesOriginResponse() throws Exception {
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(request),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result));
@@ -106,17 +103,16 @@ public class TestProtocolRequirements ex
 
         // tunnel behavior: I don't muck with request or response in
         // any way
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("GET", "/foo"), route);
+        request = new BasicClassicHttpRequest("GET", "/foo");
         request.setVersion(new ProtocolVersion("HTTP", 2, 13));
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(request),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertSame(originResponse, result);
@@ -125,22 +121,19 @@ public class TestProtocolRequirements ex
     @Test
     public void testHigher1_XProtocolVersionsDowngradeTo1_1() throws Exception {
 
-        request = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        request = new BasicClassicHttpRequest("GET", "/foo");
         request.setVersion(new ProtocolVersion("HTTP", 1, 2));
 
-        final RoutedHttpRequest downgraded = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        final ClassicHttpRequest downgraded = new BasicClassicHttpRequest("GET", "/foo");
         downgraded.setVersion(HttpVersion.HTTP_1_1);
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(downgraded),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result));
@@ -158,21 +151,18 @@ public class TestProtocolRequirements ex
     @Test
     public void testRequestsWithLowerProtocolVersionsGetUpgradedTo1_1() throws Exception {
 
-        request = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        request = new BasicClassicHttpRequest("GET", "/foo");
         request.setVersion(new ProtocolVersion("HTTP", 1, 0));
-        final RoutedHttpRequest upgraded = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        final ClassicHttpRequest upgraded = new BasicClassicHttpRequest("GET", "/foo");
         upgraded.setVersion(HttpVersion.HTTP_1_1);
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(upgraded),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertTrue(HttpTestUtils.semanticallyTransparent(originResponse, result));
@@ -197,13 +187,12 @@ public class TestProtocolRequirements ex
         // not testing this internal behavior in this test, just want
         // to check the protocol version that comes out the other end
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertEquals(HttpVersion.HTTP_1_1, result.getVersion());
@@ -211,18 +200,16 @@ public class TestProtocolRequirements ex
 
     @Test
     public void testResponseToA1_0RequestShouldUse1_1() throws Exception {
-        request = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        request = new BasicClassicHttpRequest("GET", "/foo");
         request.setVersion(new ProtocolVersion("HTTP", 1, 0));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertEquals(HttpVersion.HTTP_1_1, result.getVersion());
@@ -234,26 +221,23 @@ public class TestProtocolRequirements ex
      */
     @Test
     public void testForwardsUnknownHeadersOnRequestsFromHigherProtocolVersions() throws Exception {
-        request = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        request = new BasicClassicHttpRequest("GET", "/foo");
         request.setVersion(new ProtocolVersion("HTTP", 1, 2));
         request.removeHeaders("Connection");
         request.addHeader("X-Unknown-Header", "some-value");
 
-        final RoutedHttpRequest downgraded = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/foo"), route);
+        final ClassicHttpRequest downgraded = new BasicClassicHttpRequest("GET", "/foo");
         downgraded.setVersion(HttpVersion.HTTP_1_1);
         downgraded.removeHeaders("Connection");
         downgraded.addHeader("X-Unknown-Header", "some-value");
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(downgraded),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
     }
@@ -269,16 +253,14 @@ public class TestProtocolRequirements ex
 
         final ClassicHttpRequest originalRequest = new BasicClassicHttpRequest("GET", "/foo");
         originalRequest.setVersion(new ProtocolVersion("HTTP", 1, 0));
-        request = RoutedHttpRequest.adapt(originalRequest, route);
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(originalRequest);
 
         verifyMocks();
 
@@ -299,18 +281,16 @@ public class TestProtocolRequirements ex
      * these field values when a message is forwarded."
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2
      */
-    private void testOrderOfMultipleHeadersIsPreservedOnRequests(final String h, final RoutedHttpRequest request)
-            throws Exception {
-        final Capture<RoutedHttpRequest> reqCapture = new Capture<>();
+    private void testOrderOfMultipleHeadersIsPreservedOnRequests(final String h, final ClassicHttpRequest request) throws Exception {
+        final Capture<ClassicHttpRequest> reqCapture = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCapture),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
 
@@ -359,7 +339,7 @@ public class TestProtocolRequirements ex
         put.addHeader("Allow", "GET, HEAD");
         put.addHeader("Allow", "DELETE");
         put.addHeader("Content-Length", "128");
-        testOrderOfMultipleHeadersIsPreservedOnRequests("Allow", RoutedHttpRequest.adapt(put, route));
+        testOrderOfMultipleHeadersIsPreservedOnRequests("Allow", put);
     }
 
     @Test
@@ -376,7 +356,7 @@ public class TestProtocolRequirements ex
         post.addHeader("Content-Encoding", "gzip");
         post.addHeader("Content-Encoding", "compress");
         post.addHeader("Content-Length", "128");
-        testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Encoding", RoutedHttpRequest.adapt(post, route));
+        testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Encoding", post);
     }
 
     @Test
@@ -386,7 +366,7 @@ public class TestProtocolRequirements ex
         post.addHeader("Content-Language", "mi");
         post.addHeader("Content-Language", "en");
         post.addHeader("Content-Length", "128");
-        testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Language", RoutedHttpRequest.adapt(post, route));
+        testOrderOfMultipleHeadersIsPreservedOnRequests("Content-Language", post);
     }
 
     @Test
@@ -396,7 +376,7 @@ public class TestProtocolRequirements ex
         post.addHeader("Expect", "100-continue");
         post.addHeader("Expect", "x-expect=true");
         post.addHeader("Content-Length", "128");
-        testOrderOfMultipleHeadersIsPreservedOnRequests("Expect", RoutedHttpRequest.adapt(post, route));
+        testOrderOfMultipleHeadersIsPreservedOnRequests("Expect", post);
     }
 
     @Test
@@ -422,13 +402,12 @@ public class TestProtocolRequirements ex
 
     private void testOrderOfMultipleHeadersIsPreservedOnResponses(final String h) throws Exception {
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
 
@@ -507,14 +486,13 @@ public class TestProtocolRequirements ex
         originResponse.setEntity(body);
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         // in particular, there were no storage calls on the cache
         verifyMocks();
@@ -548,16 +526,15 @@ public class TestProtocolRequirements ex
     @Test
     public void testUnknownHeadersOnRequestsAreForwarded() throws Exception {
         request.addHeader("X-Unknown-Header", "blahblah");
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
         final ClassicHttpRequest forwarded = reqCap.getValue();
@@ -570,14 +547,13 @@ public class TestProtocolRequirements ex
     public void testUnknownHeadersOnResponsesAreForwarded() throws Exception {
         originResponse.addHeader("X-Unknown-Header", "blahblah");
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         final Header[] hdrs = result.getHeaders("X-Unknown-Header");
@@ -599,21 +575,20 @@ public class TestProtocolRequirements ex
         post.setHeader("Content-Length", "128");
         post.setEntity(new BasicHttpEntity());
 
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(RoutedHttpRequest.adapt(post, route), context, null);
+        execute(post);
 
         verifyMocks();
 
-        final RoutedHttpRequest forwarded = reqCap.getValue();
+        final ClassicHttpRequest forwarded = reqCap.getValue();
         boolean foundExpect = false;
         final Iterator<HeaderElement> it = MessageSupport.iterate(forwarded, HttpHeaders.EXPECT);
         while (it.hasNext()) {
@@ -634,27 +609,25 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
      */
     @Test
-    public void testRequestsNotExpecting100ContinueBehaviorShouldNotSetExpectContinueHeader()
-            throws Exception {
+    public void testRequestsNotExpecting100ContinueBehaviorShouldNotSetExpectContinueHeader() throws Exception {
         final BasicClassicHttpRequest post = new BasicClassicHttpRequest("POST", "/");
         post.setHeader("Content-Length", "128");
         post.setEntity(new BasicHttpEntity());
 
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(RoutedHttpRequest.adapt(post, route), context, null);
+        execute(post);
 
         verifyMocks();
 
-        final RoutedHttpRequest forwarded = reqCap.getValue();
+        final ClassicHttpRequest forwarded = reqCap.getValue();
         boolean foundExpect = false;
         final Iterator<HeaderElement> it = MessageSupport.iterate(forwarded, HttpHeaders.EXPECT);
         while (it.hasNext()) {
@@ -677,15 +650,14 @@ public class TestProtocolRequirements ex
     @Test
     public void testExpect100ContinueIsNotSentIfThereIsNoRequestBody() throws Exception {
         request.addHeader("Expect", "100-continue");
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
         final ClassicHttpRequest forwarded = reqCap.getValue();
         boolean foundExpectContinue = false;
@@ -731,8 +703,7 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.2.3
      */
     @Test
-    public void test100ContinueResponsesAreNotForwardedTo1_0ClientsWhoDidNotAskForThem()
-            throws Exception {
+    public void test100ContinueResponsesAreNotForwardedTo1_0ClientsWhoDidNotAskForThem() throws Exception {
 
         final BasicClassicHttpRequest post = new BasicClassicHttpRequest("POST", "/");
         post.setVersion(new ProtocolVersion("HTTP", 1, 0));
@@ -741,16 +712,15 @@ public class TestProtocolRequirements ex
 
         originResponse = new BasicClassicHttpResponse(100, "Continue");
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
         try {
             // if a 100 response gets up to us from the HttpClient
             // backend, we can't really handle it at that point
-            impl.execute(RoutedHttpRequest.adapt(post, route), context, null);
+            execute(post);
             Assert.fail("should have thrown an exception");
         } catch (final ClientProtocolException expected) {
         }
@@ -766,18 +736,17 @@ public class TestProtocolRequirements ex
     @Test
     public void testResponsesToOPTIONSAreNotCacheable() throws Exception {
         emptyMockCacheExpectsNoPuts();
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "/"), route);
+        request = new BasicClassicHttpRequest("OPTIONS", "/");
         originResponse.addHeader("Cache-Control", "max-age=3600");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
     }
@@ -791,18 +760,17 @@ public class TestProtocolRequirements ex
     @Test
     public void test200ResponseToOPTIONSWithNoBodyShouldIncludeContentLengthZero() throws Exception {
 
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "/"), route);
+        request = new BasicClassicHttpRequest("OPTIONS", "/");
         originResponse.setEntity(null);
         originResponse.setHeader("Content-Length", "0");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         final Header contentLength = result.getFirstHeader("Content-Length");
@@ -820,13 +788,12 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9.2
      */
     @Test
-    public void testDoesNotForwardOPTIONSWhenMaxForwardsIsZeroOnAbsoluteURIRequest()
-            throws Exception {
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "*"), route);
+    public void testDoesNotForwardOPTIONSWhenMaxForwardsIsZeroOnAbsoluteURIRequest() throws Exception {
+        request = new BasicClassicHttpRequest("OPTIONS", "*");
         request.setHeader("Max-Forwards", "0");
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
     }
 
@@ -839,19 +806,18 @@ public class TestProtocolRequirements ex
     @Test
     public void testDecrementsMaxForwardsWhenForwardingOPTIONSRequest() throws Exception {
 
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "*"), route);
+        request = new BasicClassicHttpRequest("OPTIONS", "*");
         request.setHeader("Max-Forwards", "7");
 
-        final Capture<RoutedHttpRequest> cap = new Capture<>();
+        final Capture<ClassicHttpRequest> cap = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(cap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
 
         final ClassicHttpRequest captured = cap.getValue();
@@ -866,16 +832,15 @@ public class TestProtocolRequirements ex
      */
     @Test
     public void testDoesNotAddAMaxForwardsHeaderToForwardedOPTIONSRequests() throws Exception {
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("OPTIONS", "/"), route);
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        request = new BasicClassicHttpRequest("OPTIONS", "/");
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
 
         final ClassicHttpRequest forwarded = reqCap.getValue();
@@ -890,16 +855,15 @@ public class TestProtocolRequirements ex
      */
     @Test
     public void testResponseToAHEADRequestMustNotHaveABody() throws Exception {
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("HEAD", "/"), route);
+        request = new BasicClassicHttpRequest("HEAD", "/");
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
 
@@ -918,55 +882,48 @@ public class TestProtocolRequirements ex
             final String oldVal, final String newVal) throws Exception {
 
         // put something cacheable in the cache
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.addHeader("Cache-Control", "max-age=3600");
         resp1.setHeader(eHeader, oldVal);
 
         // get a head that penetrates the cache
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("HEAD", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("HEAD", "/");
         req2.addHeader("Cache-Control", "no-cache");
         final ClassicHttpResponse resp2 = HttpTestUtils.make200Response();
         resp2.setEntity(null);
         resp2.setHeader(eHeader, newVal);
 
         // next request doesn't tolerate stale entry
-        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req3 = new BasicClassicHttpRequest("GET", "/");
         req3.addHeader("Cache-Control", "max-stale=0");
         final ClassicHttpResponse resp3 = HttpTestUtils.make200Response();
         resp3.setHeader(eHeader, newVal);
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(req1),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(req2),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp3);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp3);
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
-        impl.execute(req3, context, null);
+        execute(req1);
+        execute(req2);
+        execute(req3);
 
         verifyMocks();
     }
 
     @Test
-    public void testHEADResponseWithUpdatedContentLengthFieldMakeACacheEntryStale()
-            throws Exception {
+    public void testHEADResponseWithUpdatedContentLengthFieldMakeACacheEntryStale() throws Exception {
         testHEADResponseWithUpdatedEntityFieldsMakeACacheEntryStale("Content-Length", "128", "127");
     }
 
@@ -1010,14 +967,13 @@ public class TestProtocolRequirements ex
         originResponse.removeHeaders("Expires");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(RoutedHttpRequest.adapt(post, route), context, null);
+        execute(post);
 
         verifyMocks();
     }
@@ -1038,14 +994,13 @@ public class TestProtocolRequirements ex
         originResponse.setHeader("Cache-Control", "max-age=3600");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(RoutedHttpRequest.adapt(put, route), context, null);
+        execute(put);
 
         verifyMocks();
     }
@@ -1059,18 +1014,17 @@ public class TestProtocolRequirements ex
     public void testResponsesToDELETEsAreNotCached() throws Exception {
         emptyMockCacheExpectsNoPuts();
 
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("DELETE", "/"), route);
+        request = new BasicClassicHttpRequest("DELETE", "/");
         originResponse.setHeader("Cache-Control", "max-age=3600");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
     }
@@ -1086,16 +1040,15 @@ public class TestProtocolRequirements ex
         trace.setEntity(HttpTestUtils.makeBody(entityLength));
         trace.setHeader("Content-Length", Integer.toString(entityLength));
 
-        final Capture<RoutedHttpRequest> reqCap = new Capture<>();
+        final Capture<ClassicHttpRequest> reqCap = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.capture(reqCap),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        impl.execute(RoutedHttpRequest.adapt(trace, route), context, null);
+        execute(trace);
         verifyMocks();
 
         final ClassicHttpRequest bodyReq = reqCap.getValue();
@@ -1111,18 +1064,17 @@ public class TestProtocolRequirements ex
     public void testResponsesToTRACEsAreNotCached() throws Exception {
         emptyMockCacheExpectsNoPuts();
 
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("TRACE", "/"), route);
+        request = new BasicClassicHttpRequest("TRACE", "/");
         originResponse.setHeader("Cache-Control", "max-age=3600");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        impl.execute(request, context, null);
+        execute(request);
 
         verifyMocks();
     }
@@ -1139,14 +1091,13 @@ public class TestProtocolRequirements ex
         originResponse.setEntity(HttpTestUtils.makeBody(entityLength));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
 
@@ -1164,14 +1115,13 @@ public class TestProtocolRequirements ex
         originResponse.setEntity(HttpTestUtils.makeBody(entityLength));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
 
@@ -1198,24 +1148,21 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
      */
     @Test
-    public void test206ResponseGeneratedFromCacheMustHaveContentRangeOrMultipartByteRangesContentType()
-            throws Exception {
+    public void test206ResponseGeneratedFromCacheMustHaveContentRangeOrMultipartByteRangesContentType() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "\"etag\"");
         resp1.setHeader("Cache-Control", "max-age=3600");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Range", "bytes=0-50");
 
         backendExpectsAnyRequestAndReturn(resp1).times(1, 2);
 
         replayMocks();
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
         verifyMocks();
 
         if (HttpStatus.SC_PARTIAL_CONTENT == result.getCode()) {
@@ -1230,24 +1177,21 @@ public class TestProtocolRequirements ex
     }
 
     @Test
-    public void test206ResponseGeneratedFromCacheMustHaveABodyThatMatchesContentLengthHeaderIfPresent()
-            throws Exception {
+    public void test206ResponseGeneratedFromCacheMustHaveABodyThatMatchesContentLengthHeaderIfPresent() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "\"etag\"");
         resp1.setHeader("Cache-Control", "max-age=3600");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Range", "bytes=0-50");
 
         backendExpectsAnyRequestAndReturn(resp1).times(1, 2);
 
         replayMocks();
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
         verifyMocks();
 
         if (HttpStatus.SC_PARTIAL_CONTENT == result.getCode()) {
@@ -1267,21 +1211,19 @@ public class TestProtocolRequirements ex
 
     @Test
     public void test206ResponseGeneratedFromCacheMustHaveDateHeader() throws Exception {
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "\"etag\"");
         resp1.setHeader("Cache-Control", "max-age=3600");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Range", "bytes=0-50");
 
         backendExpectsAnyRequestAndReturn(resp1).times(1, 2);
 
         replayMocks();
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
         verifyMocks();
 
         if (HttpStatus.SC_PARTIAL_CONTENT == result.getCode()) {
@@ -1300,14 +1242,13 @@ public class TestProtocolRequirements ex
         originResponse.removeHeaders("Date");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         Assert.assertTrue(result.getCode() != HttpStatus.SC_PARTIAL_CONTENT
                 || result.getFirstHeader("Date") != null);
 
@@ -1316,22 +1257,20 @@ public class TestProtocolRequirements ex
 
     @Test
     public void test206ContainsETagIfA200ResponseWouldHaveIncludedIt() throws Exception {
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
 
         originResponse.addHeader("Cache-Control", "max-age=3600");
         originResponse.addHeader("ETag", "\"etag1\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.addHeader("Range", "bytes=0-50");
 
         backendExpectsAnyRequest().andReturn(originResponse).times(1, 2);
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
 
@@ -1342,22 +1281,20 @@ public class TestProtocolRequirements ex
 
     @Test
     public void test206ContainsContentLocationIfA200ResponseWouldHaveIncludedIt() throws Exception {
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
 
         originResponse.addHeader("Cache-Control", "max-age=3600");
         originResponse.addHeader("Content-Location", "http://foo.example.com/other/url");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.addHeader("Range", "bytes=0-50");
 
         backendExpectsAnyRequest().andReturn(originResponse).times(1, 2);
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
 
@@ -1369,8 +1306,7 @@ public class TestProtocolRequirements ex
     @Test
     public void test206ResponseIncludesVariantHeadersIfValueMightDiffer() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         req1.addHeader("Accept-Encoding", "gzip");
 
         final Date now = new Date();
@@ -1379,8 +1315,7 @@ public class TestProtocolRequirements ex
         originResponse.addHeader("Expires", DateUtils.formatDate(inOneHour));
         originResponse.addHeader("Vary", "Accept-Encoding");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.addHeader("Cache-Control", "no-cache");
         req2.addHeader("Accept-Encoding", "gzip");
         final Date nextSecond = new Date(now.getTime() + 1000L);
@@ -1392,8 +1327,7 @@ public class TestProtocolRequirements ex
         originResponse2.setHeader("Expires", DateUtils.formatDate(inTwoHoursPlusASec));
         originResponse2.setHeader("Vary", "Accept-Encoding");
 
-        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req3 = new BasicClassicHttpRequest("GET", "/");
         req3.addHeader("Range", "bytes=0-50");
         req3.addHeader("Accept-Encoding", "gzip");
 
@@ -1402,9 +1336,9 @@ public class TestProtocolRequirements ex
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
-        final ClassicHttpResponse result = impl.execute(req3, context, null);
+        execute(req1);
+        execute(req2);
+        final ClassicHttpResponse result = execute(req3);
 
         verifyMocks();
 
@@ -1424,11 +1358,9 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
      */
     @Test
-    public void test206ResponseToConditionalRangeRequestDoesNotIncludeOtherEntityHeaders()
-            throws Exception {
+    public void test206ResponseToConditionalRangeRequestDoesNotIncludeOtherEntityHeaders() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
 
         final Date now = new Date();
         final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
@@ -1443,8 +1375,7 @@ public class TestProtocolRequirements ex
         originResponse.addHeader("Last-Modified", DateUtils.formatDate(oneHourAgo));
         originResponse.addHeader("ETag", "W/\"weak-tag\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.addHeader("If-Range", "W/\"weak-tag\"");
         req2.addHeader("Range", "bytes=0-50");
 
@@ -1452,8 +1383,8 @@ public class TestProtocolRequirements ex
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
 
@@ -1474,11 +1405,9 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
      */
     @Test
-    public void test206ResponseToIfRangeWithStrongValidatorReturnsAllEntityHeaders()
-            throws Exception {
+    public void test206ResponseToIfRangeWithStrongValidatorReturnsAllEntityHeaders() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
 
         final Date now = new Date();
         final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
@@ -1492,8 +1421,7 @@ public class TestProtocolRequirements ex
         originResponse.addHeader("Last-Modified", DateUtils.formatDate(oneHourAgo));
         originResponse.addHeader("ETag", "\"strong-tag\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.addHeader("If-Range", "\"strong-tag\"");
         req2.addHeader("Range", "bytes=0-50");
 
@@ -1501,8 +1429,8 @@ public class TestProtocolRequirements ex
 
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
 
@@ -1526,13 +1454,11 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
      */
     @Test
-    public void test206ResponseIsNotCombinedWithPreviousContentIfETagDoesNotMatch()
-            throws Exception {
+    public void test206ResponseIsNotCombinedWithPreviousContentIfETagDoesNotMatch() throws Exception {
 
         final Date now = new Date();
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("Cache-Control", "max-age=3600");
         resp1.setHeader("ETag", "\"etag1\"");
@@ -1542,8 +1468,7 @@ public class TestProtocolRequirements ex
         }
         resp1.setEntity(new ByteArrayEntity(bytes1));
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Cache-Control", "no-cache");
         req2.setHeader("Range", "bytes=0-50");
 
@@ -1561,8 +1486,7 @@ public class TestProtocolRequirements ex
         resp2.setEntity(new ByteArrayEntity(bytes2));
 
         final Date inTwoSeconds = new Date(now.getTime() + 2000L);
-        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req3 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp3 = HttpTestUtils.make200Response();
         resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds));
         resp3.setHeader("Cache-Control", "max-age=3600");
@@ -1574,25 +1498,22 @@ public class TestProtocolRequirements ex
         resp3.setEntity(new ByteArrayEntity(bytes3));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp1);
-        EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp2);
-        EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp3).times(0, 1);
-        replayMocks();
-
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
-        final ClassicHttpResponse result = impl.execute(req3, context, null);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp1);
+        EasyMock.expect(
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp2);
+        EasyMock.expect(
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp3).times(0, 1);
+        replayMocks();
+
+        execute(req1);
+        execute(req2);
+        final ClassicHttpResponse result = execute(req3);
 
         verifyMocks();
 
@@ -1613,13 +1534,11 @@ public class TestProtocolRequirements ex
     }
 
     @Test
-    public void test206ResponseIsNotCombinedWithPreviousContentIfLastModifiedDoesNotMatch()
-            throws Exception {
+    public void test206ResponseIsNotCombinedWithPreviousContentIfLastModifiedDoesNotMatch() throws Exception {
 
         final Date now = new Date();
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         final Date oneHourAgo = new Date(now.getTime() - 3600L);
         resp1.setHeader("Cache-Control", "max-age=3600");
@@ -1630,8 +1549,7 @@ public class TestProtocolRequirements ex
         }
         resp1.setEntity(new ByteArrayEntity(bytes1));
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Cache-Control", "no-cache");
         req2.setHeader("Range", "bytes=0-50");
 
@@ -1649,8 +1567,7 @@ public class TestProtocolRequirements ex
         resp2.setEntity(new ByteArrayEntity(bytes2));
 
         final Date inTwoSeconds = new Date(now.getTime() + 2000L);
-        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req3 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp3 = HttpTestUtils.make200Response();
         resp3.setHeader("Date", DateUtils.formatDate(inTwoSeconds));
         resp3.setHeader("Cache-Control", "max-age=3600");
@@ -1662,25 +1579,22 @@ public class TestProtocolRequirements ex
         resp3.setEntity(new ByteArrayEntity(bytes3));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp1);
-        EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp2);
-        EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp3).times(0, 1);
-        replayMocks();
-
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
-        final ClassicHttpResponse result = impl.execute(req3, context, null);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp1);
+        EasyMock.expect(
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp2);
+        EasyMock.expect(
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp3).times(0, 1);
+        replayMocks();
+
+        execute(req1);
+        execute(req2);
+        final ClassicHttpResponse result = execute(req3);
 
         verifyMocks();
 
@@ -1707,14 +1621,12 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.2.7
      */
     @Test
-    public void test206ResponsesAreNotCachedIfTheCacheDoesNotSupportRangeAndContentRangeHeaders()
-            throws Exception {
+    public void test206ResponsesAreNotCachedIfTheCacheDoesNotSupportRangeAndContentRangeHeaders() throws Exception {
 
         if (!supportsRangeAndContentRangeHeaders(impl)) {
             emptyMockCacheExpectsNoPuts();
 
-            request = RoutedHttpRequest.adapt(
-                    new BasicClassicHttpRequest("GET", "/"), route);
+            request = new BasicClassicHttpRequest("GET", "/");
             request.addHeader("Range", "bytes=0-50");
 
             originResponse = new BasicClassicHttpResponse(HttpStatus.SC_PARTIAL_CONTENT,"Partial Content");
@@ -1725,13 +1637,12 @@ public class TestProtocolRequirements ex
             originResponse.setEntity(new ByteArrayEntity(bytes));
 
             EasyMock.expect(
-                    mockBackend.execute(
-                            EasyMock.isA(RoutedHttpRequest.class),
-                            EasyMock.isA(HttpClientContext.class),
-                            EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                    mockExecChain.proceed(
+                            EasyMock.isA(ClassicHttpRequest.class),
+                            EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
             replayMocks();
-            impl.execute(request, context, null);
+            execute(request);
             verifyMocks();
         }
     }
@@ -1746,7 +1657,7 @@ public class TestProtocolRequirements ex
     public void test303ResponsesAreNotCached() throws Exception {
         emptyMockCacheExpectsNoPuts();
 
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("GET", "/"), route);
+        request = new BasicClassicHttpRequest("GET", "/");
 
         originResponse = new BasicClassicHttpResponse(HttpStatus.SC_SEE_OTHER, "See Other");
         originResponse.setHeader("Date", DateUtils.formatDate(new Date()));
@@ -1757,13 +1668,12 @@ public class TestProtocolRequirements ex
         originResponse.setEntity(HttpTestUtils.makeBody(entityLength));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
     }
 
@@ -1784,14 +1694,13 @@ public class TestProtocolRequirements ex
         originResponse.setEntity(HttpTestUtils.makeBody(entityLength));
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
 
@@ -1806,8 +1715,7 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
      */
     @Test
-    public void test304ResponseWithDateHeaderForwardedFromOriginIncludesDateHeader()
-            throws Exception {
+    public void test304ResponseWithDateHeaderForwardedFromOriginIncludesDateHeader() throws Exception {
 
         request.setHeader("If-None-Match", "\"etag\"");
 
@@ -1817,13 +1725,12 @@ public class TestProtocolRequirements ex
         originResponse.setHeader("ETag", "\"etag\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
 
         verifyMocks();
         Assert.assertNotNull(result.getFirstHeader("Date"));
@@ -1832,24 +1739,21 @@ public class TestProtocolRequirements ex
     @Test
     public void test304ResponseGeneratedFromCacheIncludesDateHeader() throws Exception {
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         originResponse.setHeader("Cache-Control", "max-age=3600");
         originResponse.setHeader("ETag", "\"etag\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("If-None-Match", "\"etag\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse).times(1, 2);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse).times(1, 2);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
         if (result.getCode() == HttpStatus.SC_NOT_MODIFIED) {
@@ -1866,24 +1770,21 @@ public class TestProtocolRequirements ex
      */
     @Test
     public void test304ResponseGeneratedFromCacheIncludesEtagIfOriginResponseDid() throws Exception {
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         originResponse.setHeader("Cache-Control", "max-age=3600");
         originResponse.setHeader("ETag", "\"etag\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("If-None-Match", "\"etag\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse).times(1, 2);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse).times(1, 2);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
         if (result.getCode() == HttpStatus.SC_NOT_MODIFIED) {
@@ -1892,27 +1793,23 @@ public class TestProtocolRequirements ex
     }
 
     @Test
-    public void test304ResponseGeneratedFromCacheIncludesContentLocationIfOriginResponseDid()
-            throws Exception {
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+    public void test304ResponseGeneratedFromCacheIncludesContentLocationIfOriginResponseDid() throws Exception {
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         originResponse.setHeader("Cache-Control", "max-age=3600");
         originResponse.setHeader("Content-Location", "http://foo.example.com/other");
         originResponse.setHeader("ETag", "\"etag\"");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("If-None-Match", "\"etag\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse).times(1, 2);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse).times(1, 2);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
         if (result.getCode() == HttpStatus.SC_NOT_MODIFIED) {
@@ -1928,14 +1825,12 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
      */
     @Test
-    public void test304ResponseGeneratedFromCacheIncludesExpiresCacheControlAndOrVaryIfResponseMightDiffer()
-            throws Exception {
+    public void test304ResponseGeneratedFromCacheIncludesExpiresCacheControlAndOrVaryIfResponseMightDiffer() throws Exception {
 
         final Date now = new Date();
         final Date inTwoHours = new Date(now.getTime() + 2 * 3600 * 1000L);
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         req1.setHeader("Accept-Encoding", "gzip");
 
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
@@ -1945,8 +1840,7 @@ public class TestProtocolRequirements ex
         resp1.setHeader("Vary", "Accept-Encoding");
         resp1.setEntity(HttpTestUtils.makeBody(entityLength));
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req1.setHeader("Accept-Encoding", "gzip");
         req1.setHeader("Cache-Control", "no-cache");
 
@@ -1957,26 +1851,23 @@ public class TestProtocolRequirements ex
         resp2.setHeader("Vary", "Accept-Encoding");
         resp2.setEntity(HttpTestUtils.makeBody(entityLength));
 
-        final RoutedHttpRequest req3 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req3 = new BasicClassicHttpRequest("GET", "/");
         req3.setHeader("Accept-Encoding", "gzip");
         req3.setHeader("If-None-Match", "\"v2\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp1);
-        EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp2).times(1, 2);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp1);
+        EasyMock.expect(
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp2).times(1, 2);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
-        final ClassicHttpResponse result = impl.execute(req3, context, null);
+        execute(req1);
+        execute(req2);
+        final ClassicHttpResponse result = execute(req3);
 
         verifyMocks();
 
@@ -1995,14 +1886,12 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
      */
     @Test
-    public void test304GeneratedFromCacheOnWeakValidatorDoesNotIncludeOtherEntityHeaders()
-            throws Exception {
+    public void test304GeneratedFromCacheOnWeakValidatorDoesNotIncludeOtherEntityHeaders() throws Exception {
 
         final Date now = new Date();
         final Date oneHourAgo = new Date(now.getTime() - 3600 * 1000L);
 
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
 
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "W/\"v1\"");
@@ -2015,19 +1904,17 @@ public class TestProtocolRequirements ex
         resp1.setHeader("Last-Modified", DateUtils.formatDate(oneHourAgo));
         resp1.setHeader("Cache-Control", "max-age=7200");
 
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("If-None-Match", "W/\"v1\"");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp1).times(1, 2);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp1).times(1, 2);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        final ClassicHttpResponse result = impl.execute(req2, context, null);
+        execute(req1);
+        final ClassicHttpResponse result = execute(req2);
 
         verifyMocks();
 
@@ -2049,21 +1936,18 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5
      */
     @Test
-    public void testNotModifiedOfNonCachedEntityShouldRevalidateWithUnconditionalGET()
-            throws Exception {
+    public void testNotModifiedOfNonCachedEntityShouldRevalidateWithUnconditionalGET() throws Exception {
 
         final Date now = new Date();
 
         // load cache with cacheable entry
-        final RoutedHttpRequest req1 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req1 = new BasicClassicHttpRequest("GET", "/");
         final ClassicHttpResponse resp1 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "\"etag1\"");
         resp1.setHeader("Cache-Control", "max-age=3600");
 
         // force a revalidation
-        final RoutedHttpRequest req2 = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest req2 = new BasicClassicHttpRequest("GET", "/");
         req2.setHeader("Cache-Control", "max-age=0,max-stale=0");
 
         // updated ETag provided to a conditional revalidation
@@ -2074,39 +1958,34 @@ public class TestProtocolRequirements ex
         resp2.setHeader("ETag", "\"etag2\"");
 
         // conditional validation uses If-None-Match
-        final RoutedHttpRequest conditionalValidation = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest conditionalValidation = new BasicClassicHttpRequest("GET", "/");
         conditionalValidation.setHeader("If-None-Match", "\"etag1\"");
 
         // unconditional validation doesn't use If-None-Match
-        final RoutedHttpRequest unconditionalValidation = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest unconditionalValidation = new BasicClassicHttpRequest("GET", "/");
         // new response to unconditional validation provides new body
         final ClassicHttpResponse resp3 = HttpTestUtils.make200Response();
         resp1.setHeader("ETag", "\"etag2\"");
         resp1.setHeader("Cache-Control", "max-age=3600");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp1);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp1);
         // this next one will happen once if the cache tries to
         // conditionally validate, zero if it goes full revalidation
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(conditionalValidation),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp2).times(0, 1);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp2).times(0, 1);
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(unconditionalValidation),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(resp3);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(resp3);
         replayMocks();
 
-        impl.execute(req1, context, null);
-        impl.execute(req2, context, null);
+        execute(req1);
+        execute(req2);
 
         verifyMocks();
     }
@@ -2124,23 +2003,19 @@ public class TestProtocolRequirements ex
         final Date now = new Date();
         final Date inFiveSeconds = new Date(now.getTime() + 5000L);
 
-        final RoutedHttpRequest initialRequest = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest initialRequest = new BasicClassicHttpRequest("GET", "/");
 
         final ClassicHttpResponse cachedResponse = HttpTestUtils.make200Response();
         cachedResponse.setHeader("Cache-Control", "max-age=3600");
         cachedResponse.setHeader("ETag", "\"etag\"");
 
-        final RoutedHttpRequest secondRequest = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest secondRequest = new BasicClassicHttpRequest("GET", "/");
         secondRequest.setHeader("Cache-Control", "max-age=0,max-stale=0");
 
-        final RoutedHttpRequest conditionalValidationRequest = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest conditionalValidationRequest = new BasicClassicHttpRequest("GET", "/");
         conditionalValidationRequest.setHeader("If-None-Match", "\"etag\"");
 
-        final RoutedHttpRequest unconditionalValidationRequest = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest unconditionalValidationRequest = new BasicClassicHttpRequest("GET", "/");
 
         // to be used if the cache generates a conditional validation
         final ClassicHttpResponse conditionalResponse = HttpTestUtils.make304Response();
@@ -2154,29 +2029,26 @@ public class TestProtocolRequirements ex
         unconditionalResponse.setHeader("Date", DateUtils.formatDate(inFiveSeconds));
         unconditionalResponse.setHeader("ETag", "\"etag\"");
 
-        final Capture<RoutedHttpRequest> cap1 = new Capture<>();
-        final Capture<RoutedHttpRequest> cap2 = new Capture<>();
+        final Capture<ClassicHttpRequest> cap1 = new Capture<>();
+        final Capture<ClassicHttpRequest> cap2 = new Capture<>();
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(cachedResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(cachedResponse);
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.and(eqRequest(conditionalValidationRequest), EasyMock.capture(cap1)),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(conditionalResponse).times(0, 1);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(conditionalResponse).times(0, 1);
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         EasyMock.and(eqRequest(unconditionalValidationRequest), EasyMock.capture(cap2)),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(unconditionalResponse).times(0, 1);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(unconditionalResponse).times(0, 1);
 
         replayMocks();
 
-        impl.execute(initialRequest, context, null);
-        final ClassicHttpResponse result = impl.execute(secondRequest, context, null);
+        execute(initialRequest);
+        final ClassicHttpResponse result = execute(secondRequest);
 
         verifyMocks();
 
@@ -2203,13 +2075,12 @@ public class TestProtocolRequirements ex
         originResponse.setHeader("WWW-Authenticate", "x-scheme x-param");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         if (result.getCode() == 401) {
             Assert.assertNotNull(result.getFirstHeader("WWW-Authenticate"));
         }
@@ -2232,7 +2103,7 @@ public class TestProtocolRequirements ex
 
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         if (result.getCode() == 405) {
             Assert.assertNotNull(result.getFirstHeader("Allow"));
         }
@@ -2253,13 +2124,12 @@ public class TestProtocolRequirements ex
         originResponse.setHeader("Proxy-Authenticate", "x-scheme x-param");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         replayMocks();
 
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         if (result.getCode() == 407) {
             Assert.assertNotNull(result.getFirstHeader("Proxy-Authenticate"));
         }
@@ -2278,13 +2148,12 @@ public class TestProtocolRequirements ex
         originResponse = new BasicClassicHttpResponse(416, "Requested Range Not Satisfiable");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
 
         replayMocks();
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         verifyMocks();
 
         if (result.getCode() == 416) {
@@ -2297,36 +2166,32 @@ public class TestProtocolRequirements ex
     }
 
     @Test
-    public void testMustNotUseMultipartByteRangeContentTypeOnCacheGenerated416Responses()
-            throws Exception {
+    public void testMustNotUseMultipartByteRangeContentTypeOnCacheGenerated416Responses() throws Exception {
 
         originResponse.setEntity(HttpTestUtils.makeBody(entityLength));
         originResponse.setHeader("Content-Length", "128");
         originResponse.setHeader("Cache-Control", "max-age=3600");
 
-        final RoutedHttpRequest rangeReq = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/"), route);
+        final ClassicHttpRequest rangeReq = new BasicClassicHttpRequest("GET", "/");
         rangeReq.setHeader("Range", "bytes=1000-1200");
 
         final ClassicHttpResponse orig416 = new BasicClassicHttpResponse(416,
                 "Requested Range Not Satisfiable");
 
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(originResponse);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(originResponse);
         // cache may 416 me right away if it understands byte ranges,
         // ok to delegate to origin though
         EasyMock.expect(
-                mockBackend.execute(
-                        EasyMock.isA(RoutedHttpRequest.class),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(orig416).times(0, 1);
+                mockExecChain.proceed(
+                        EasyMock.isA(ClassicHttpRequest.class),
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(orig416).times(0, 1);
 
         replayMocks();
-        impl.execute(request, context, null);
-        final ClassicHttpResponse result = impl.execute(rangeReq, context, null);
+        execute(request);
+        final ClassicHttpResponse result = execute(rangeReq);
         verifyMocks();
 
         // might have gotten a 416 from the origin or the cache
@@ -2387,13 +2252,11 @@ public class TestProtocolRequirements ex
 
         final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
-        impl = new CachingExec(mockBackend, mockCache, config);
+        impl = new CachingExec(mockCache, config);
 
-        request = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/thing"), route);
+        request = new BasicClassicHttpRequest("GET", "/thing");
 
-        final RoutedHttpRequest validate = RoutedHttpRequest.adapt(
-                new BasicClassicHttpRequest("GET", "/thing"), route);
+        final ClassicHttpRequest validate = new BasicClassicHttpRequest("GET", "/thing");
         validate.setHeader("If-None-Match", "\"etag\"");
 
         final ClassicHttpResponse notModified = new BasicClassicHttpResponse(HttpStatus.SC_NOT_MODIFIED, "Not Modified");
@@ -2406,10 +2269,9 @@ public class TestProtocolRequirements ex
                 mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request)))
                 .andReturn(entry);
         EasyMock.expect(
-                mockBackend.execute(
+                mockExecChain.proceed(
                         eqRequest(validate),
-                        EasyMock.isA(HttpClientContext.class),
-                        EasyMock.<HttpExecutionAware>isNull())).andReturn(notModified);
+                        EasyMock.isA(ExecChain.Scope.class))).andReturn(notModified);
         EasyMock.expect(mockCache.updateCacheEntry(
                 EasyMock.eq(host),
                 eqRequest(request),
@@ -2420,7 +2282,7 @@ public class TestProtocolRequirements ex
             .andReturn(HttpTestUtils.makeCacheEntry());
 
         replayMocks();
-        impl.execute(request, context, null);
+        execute(request);
         verifyMocks();
     }
 
@@ -2443,14 +2305,14 @@ public class TestProtocolRequirements ex
 
         final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
-        impl = new CachingExec(mockBackend, mockCache, config);
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("GET", "/thing"), route);
+        impl = new CachingExec(mockCache, config);
+        request = new BasicClassicHttpRequest("GET", "/thing");
 
         mockCache.flushInvalidatedCacheEntriesFor(EasyMock.eq(host), eqRequest(request));
         EasyMock.expect(mockCache.getCacheEntry(EasyMock.eq(host), eqRequest(request))).andReturn(entry);
 
         replayMocks();
-        final ClassicHttpResponse result = impl.execute(request, context, null);
+        final ClassicHttpResponse result = execute(request);
         verifyMocks();
 
         Assert.assertEquals(200, result.getCode());
@@ -2471,8 +2333,7 @@ public class TestProtocolRequirements ex
      * http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.46
      */
     @Test
-    public void testMustServeAppropriateErrorOrWarningIfNoOriginCommunicationPossible()
-            throws Exception {
+    public void testMustServeAppropriateErrorOrWarningIfNoOriginCommunicationPossible() throws Exception {
 
         final Date now = new Date();
         final Date tenSecondsAgo = new Date(now.getTime() - 10 * 1000L);
@@ -2491,21 +2352,20 @@ public class TestProtocolRequirements ex
 
         final HttpCacheEntry entry = HttpTestUtils.makeCacheEntry(tenSecondsAgo, eightSecondsAgo, hdrs, bytes);
 
-        impl = new CachingExec(mockBackend, mockCache, config);
-        request = RoutedHttpRequest.adapt(new BasicClassicHttpRequest("GET", "/thing"), route);

[... 2792 lines stripped ...]