diff --git a/test/http_proxy_advanced_test.dart b/test/http_proxy_advanced_test.dart
new file mode 100644
index 0000000..5276acc
--- /dev/null
+++ b/test/http_proxy_advanced_test.dart
@@ -0,0 +1,632 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io' show Directory, File, Platform, SecurityContext, Socket;
+
+import 'package:convert/convert.dart';
+import 'package:crypto/crypto.dart';
+import 'package:http_io/http_io.dart';
+import 'package:test/test.dart';
+
+String localFile(path) {
+  final localPath = '${Directory.current.path}/test/$path';
+  if (!(new File(localPath).existsSync())) {
+    return Platform.script.resolve(path).toFilePath();
+  }
+  return localPath;
+}
+
+final SecurityContext serverContext = new SecurityContext()
+  ..useCertificateChain(localFile('certificates/server_chain.pem'))
+  ..usePrivateKey(localFile('certificates/server_key.pem'),
+      password: 'dartdart');
+
+final SecurityContext clientContext = new SecurityContext()
+  ..setTrustedCertificates(localFile('certificates/trusted_certs.pem'));
+
+class Server {
+  HttpServer server;
+  bool secure;
+  int proxyHops;
+  List<String> directRequestPaths;
+  int requestCount = 0;
+
+  Server(this.proxyHops, this.directRequestPaths, this.secure);
+
+  Future<Server> start() {
+    return (secure
+        ? HttpServer.bindSecure("localhost", 0, serverContext)
+        : HttpServer.bind("localhost", 0)).then((s) {
+      server = s;
+      server.listen(requestHandler);
+      return this;
+    });
+  }
+
+  void requestHandler(HttpRequest request) {
+    var response = request.response;
+    requestCount++;
+    // Check whether a proxy or direct connection is expected.
+    bool direct = directRequestPaths.fold(
+        false, (prev, path) => prev ? prev : path == request.uri.path);
+    if (!secure && !direct && proxyHops > 0) {
+      expect(request.headers[HttpHeaders.VIA], isNotNull);
+      expect(1, equals(request.headers[HttpHeaders.VIA].length));
+      expect(proxyHops, request.headers[HttpHeaders.VIA][0].split(",").length);
+    } else {
+      expect(request.headers[HttpHeaders.VIA], isNull);
+    }
+    var body = new StringBuffer();
+    onRequestComplete() {
+      String path = request.uri.path.substring(1);
+      if (path != "A") {
+        String content = "$path$path$path";
+        expect(content, equals(body.toString()));
+      }
+      response.write(request.uri.path);
+      response.close();
+    }
+
+    request.listen((data) {
+      body.write(new String.fromCharCodes(data));
+    }, onDone: onRequestComplete);
+  }
+
+  void shutdown() {
+    server.close();
+  }
+
+  int get port => server.port;
+}
+
+Future<Server> setupServer(int proxyHops,
+    {List<String> directRequestPaths: const <String>[], secure: false}) {
+  Server server = new Server(proxyHops, directRequestPaths, secure);
+  return server.start();
+}
+
+class ProxyServer {
+  final bool ipV6;
+  HttpServer server;
+  HttpClient client;
+  int requestCount = 0;
+  String authScheme;
+  String realm = "test";
+  String username;
+  String password;
+
+  var ha1;
+  String serverAlgorithm = "MD5";
+  String serverQop = "auth";
+  Set ncs = new Set();
+
+  var nonce = "12345678"; // No need for random nonce in test.
+
+  ProxyServer({this.ipV6: false}) : client = new HttpClient();
+
+  void useBasicAuthentication(String username, String password) {
+    this.username = username;
+    this.password = password;
+    authScheme = "Basic";
+  }
+
+  void useDigestAuthentication(String username, String password) {
+    this.username = username;
+    this.password = password;
+    authScheme = "Digest";
+
+    // Calculate ha1.
+    var digest = md5.convert("${username}:${realm}:${password}".codeUnits);
+    ha1 = hex.encode(digest.bytes);
+  }
+
+  basicAuthenticationRequired(request) {
+    request.fold(null, (x, y) {}).then((_) {
+      var response = request.response;
+      response.headers
+          .set(HttpHeaders.PROXY_AUTHENTICATE, "Basic, realm=$realm");
+      response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED;
+      response.close();
+    });
+  }
+
+  digestAuthenticationRequired(request, {stale: false}) {
+    request.fold(null, (x, y) {}).then((_) {
+      var response = request.response;
+      response.statusCode = HttpStatus.PROXY_AUTHENTICATION_REQUIRED;
+      StringBuffer authHeader = new StringBuffer();
+      authHeader.write('Digest');
+      authHeader.write(', realm="$realm"');
+      authHeader.write(', nonce="$nonce"');
+      if (stale) authHeader.write(', stale="true"');
+      if (serverAlgorithm != null) {
+        authHeader.write(', algorithm=$serverAlgorithm');
+      }
+      if (serverQop != null) authHeader.write(', qop="$serverQop"');
+      response.headers.set(HttpHeaders.PROXY_AUTHENTICATE, authHeader);
+      response.close();
+    });
+  }
+
+  Future<ProxyServer> start() {
+    var x = new Completer<ProxyServer>();
+    var host = ipV6 ? "::1" : "localhost";
+    HttpServer.bind(host, 0).then((s) {
+      server = s;
+      x.complete(this);
+      server.listen((HttpRequest request) {
+        requestCount++;
+        if (username != null && password != null) {
+          if (request.headers[HttpHeaders.PROXY_AUTHORIZATION] == null) {
+            if (authScheme == "Digest") {
+              digestAuthenticationRequired(request);
+            } else {
+              basicAuthenticationRequired(request);
+            }
+            return;
+          } else {
+            expect(
+                1,
+                equals(
+                    request.headers[HttpHeaders.PROXY_AUTHORIZATION].length));
+            String authorization =
+                request.headers[HttpHeaders.PROXY_AUTHORIZATION][0];
+            if (authScheme == "Basic") {
+              List<String> tokens = authorization.split(" ");
+              expect("Basic", equals(tokens[0]));
+              String auth = base64.encode(utf8.encode("$username:$password"));
+              if (auth != tokens[1]) {
+                basicAuthenticationRequired(request);
+                return;
+              }
+            } else {
+              HeaderValue header =
+                  HeaderValue.parse(authorization, parameterSeparator: ",");
+              expect("Digest", equals(header.value));
+              var uri = header.parameters["uri"];
+              var qop = header.parameters["qop"];
+              var cnonce = header.parameters["cnonce"];
+              var nc = header.parameters["nc"];
+              expect(username, equals(header.parameters["username"]));
+              expect(realm, equals(header.parameters["realm"]));
+              expect("MD5", equals(header.parameters["algorithm"]));
+              expect(nonce, equals(header.parameters["nonce"]));
+              expect(request.uri.toString(), equals(uri));
+              if (qop != null) {
+                // A server qop of auth-int is downgraded to none by the client.
+                expect("auth", equals(serverQop));
+                expect("auth", equals(header.parameters["qop"]));
+                expect(cnonce, isNotNull);
+                expect(nc, isNotNull);
+                expect(ncs.contains(nc), isFalse);
+                ncs.add(nc);
+              } else {
+                expect(cnonce, isNotNull);
+                expect(nc, isNotNull);
+              }
+              expect(header.parameters["response"], isNotNull);
+
+              var digest = md5.convert("${request.method}:${uri}".codeUnits);
+              var ha2 = hex.encode(digest.bytes);
+
+              if (qop == null || qop == "" || qop == "none") {
+                digest = md5.convert("$ha1:${nonce}:$ha2".codeUnits);
+              } else {
+                digest = md5.convert(
+                    "$ha1:${nonce}:${nc}:${cnonce}:${qop}:$ha2".codeUnits);
+              }
+              expect(hex.encode(digest.bytes),
+                  equals(header.parameters["response"]));
+
+              // Add a bogus Proxy-Authentication-Info for testing.
+              var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
+                  'cnonce="8f971178", '
+                  'nc=000002c74, '
+                  'qop=auth';
+              request.response.headers.set("Proxy-Authentication-Info", info);
+            }
+          }
+        }
+        // Open the connection from the proxy.
+        if (request.method == "CONNECT") {
+          var tmp = request.uri.toString().split(":");
+          Socket.connect(tmp[0], int.parse(tmp[1])).then((socket) {
+            request.response.reasonPhrase = "Connection established";
+            request.response.detachSocket().then((detached) {
+              socket.pipe(detached);
+              detached.pipe(socket);
+            });
+          });
+        } else {
+          client
+              .openUrl(request.method, request.uri)
+              .then((HttpClientRequest clientRequest) {
+            // Forward all headers.
+            request.headers.forEach((String name, List<String> values) {
+              values.forEach((String value) {
+                if (name != "content-length" && name != "via") {
+                  clientRequest.headers.add(name, value);
+                }
+              });
+            });
+            // Special handling of Content-Length and Via.
+            clientRequest.contentLength = request.contentLength;
+            List<String> via = request.headers[HttpHeaders.VIA];
+            String viaPrefix = via == null ? "" : "${via[0]}, ";
+            clientRequest.headers
+                .add(HttpHeaders.VIA, "${viaPrefix}1.1 localhost:$port");
+            // Copy all content.
+            return request.pipe(clientRequest);
+          }).then((clientResponse) {
+            (clientResponse as HttpClientResponse).pipe(request.response);
+          });
+        }
+      });
+    });
+    return x.future;
+  }
+
+  void shutdown() {
+    server.close();
+    client.close();
+  }
+
+  int get port => server.port;
+}
+
+Future<ProxyServer> setupProxyServer({ipV6: false}) {
+  ProxyServer proxyServer = new ProxyServer(ipV6: ipV6);
+  return proxyServer.start();
+}
+
+int testProxyIPV6DoneCount = 0;
+Future<Null> testProxyIPV6() {
+  final completer = new Completer<Null>();
+  setupProxyServer(ipV6: true).then((proxyServer) {
+    setupServer(1, directRequestPaths: ["/4"]).then((server) {
+      setupServer(1, directRequestPaths: ["/4"], secure: true)
+          .then((secureServer) {
+        HttpClient client = new HttpClient(context: clientContext);
+
+        List<String> proxy = ["PROXY [::1]:${proxyServer.port}"];
+        client.findProxy = (Uri uri) {
+          // Pick the proxy configuration based on the request path.
+          int index = int.parse(uri.path.substring(1));
+          return proxy[index];
+        };
+
+        for (int i = 0; i < proxy.length; i++) {
+          test(bool secure) {
+            String url = secure
+                ? "https://localhost:${secureServer.port}/$i"
+                : "http://localhost:${server.port}/$i";
+
+            client
+                .postUrl(Uri.parse(url))
+                .then((HttpClientRequest clientRequest) {
+              String content = "$i$i$i";
+              clientRequest.write(content);
+              return clientRequest.close();
+            }).then((HttpClientResponse response) {
+              response.listen((_) {}, onDone: () {
+                testProxyIPV6DoneCount++;
+                if (testProxyIPV6DoneCount == proxy.length * 2) {
+                  expect(proxy.length, equals(server.requestCount));
+                  expect(proxy.length, equals(secureServer.requestCount));
+                  proxyServer.shutdown();
+                  server.shutdown();
+                  secureServer.shutdown();
+                  client.close();
+                  completer.complete();
+                }
+              });
+            });
+          }
+
+          test(false);
+          test(true);
+        }
+      });
+    });
+  });
+  return completer.future;
+}
+
+int testProxyFromEnviromentDoneCount = 0;
+Future<Null> testProxyFromEnviroment() {
+  final completer = new Completer<Null>();
+  setupProxyServer().then((proxyServer) {
+    setupServer(1).then((server) {
+      setupServer(1, secure: true).then((secureServer) {
+        HttpClient client = new HttpClient(context: clientContext);
+
+        client.findProxy = (Uri uri) {
+          return HttpClient.findProxyFromEnvironment(uri, environment: {
+            "http_proxy": "localhost:${proxyServer.port}",
+            "https_proxy": "localhost:${proxyServer.port}"
+          });
+        };
+
+        const int loopCount = 5;
+        for (int i = 0; i < loopCount; i++) {
+          test(bool secure) {
+            String url = secure
+                ? "https://localhost:${secureServer.port}/$i"
+                : "http://localhost:${server.port}/$i";
+
+            client
+                .postUrl(Uri.parse(url))
+                .then((HttpClientRequest clientRequest) {
+              String content = "$i$i$i";
+              clientRequest.write(content);
+              return clientRequest.close();
+            }).then((HttpClientResponse response) {
+              response.listen((_) {}, onDone: () {
+                testProxyFromEnviromentDoneCount++;
+                if (testProxyFromEnviromentDoneCount == loopCount * 2) {
+                  expect(loopCount, equals(server.requestCount));
+                  expect(loopCount, equals(secureServer.requestCount));
+                  proxyServer.shutdown();
+                  server.shutdown();
+                  secureServer.shutdown();
+                  client.close();
+                  completer.complete();
+                }
+              });
+            });
+          }
+
+          test(false);
+          test(true);
+        }
+      });
+    });
+  });
+  return completer.future;
+}
+
+int testProxyAuthenticateCount = 0;
+Future testProxyAuthenticate(bool useDigestAuthentication) {
+  testProxyAuthenticateCount = 0;
+  var completer = new Completer();
+
+  setupProxyServer().then((proxyServer) {
+    setupServer(1).then((server) {
+      setupServer(1, secure: true).then((secureServer) {
+        HttpClient client = new HttpClient(context: clientContext);
+
+        Completer step1 = new Completer();
+        Completer step2 = new Completer();
+
+        if (useDigestAuthentication) {
+          proxyServer.useDigestAuthentication("dart", "password");
+        } else {
+          proxyServer.useBasicAuthentication("dart", "password");
+        }
+
+        // Test with no authentication.
+        client.findProxy = (Uri uri) {
+          return "PROXY localhost:${proxyServer.port}";
+        };
+
+        const int loopCount = 2;
+        for (int i = 0; i < loopCount; i++) {
+          test(bool secure) {
+            String url = secure
+                ? "https://localhost:${secureServer.port}/$i"
+                : "http://localhost:${server.port}/$i";
+
+            client
+                .postUrl(Uri.parse(url))
+                .then((HttpClientRequest clientRequest) {
+              String content = "$i$i$i";
+              clientRequest.write(content);
+              return clientRequest.close();
+            }).then((HttpClientResponse response) {
+              fail("No response expected");
+            }).catchError((e) {
+              testProxyAuthenticateCount++;
+              if (testProxyAuthenticateCount == loopCount * 2) {
+                expect(0, equals(server.requestCount));
+                expect(0, equals(secureServer.requestCount));
+                step1.complete(null);
+              }
+            });
+          }
+
+          test(false);
+          test(true);
+        }
+        step1.future.then((_) {
+          testProxyAuthenticateCount = 0;
+          if (useDigestAuthentication) {
+            client.findProxy =
+                (Uri uri) => "PROXY localhost:${proxyServer.port}";
+            client.addProxyCredentials("localhost", proxyServer.port, "test",
+                new HttpClientDigestCredentials("dart", "password"));
+          } else {
+            client.findProxy = (Uri uri) {
+              return "PROXY dart:password@localhost:${proxyServer.port}";
+            };
+          }
+
+          for (int i = 0; i < loopCount; i++) {
+            test(bool secure) {
+              var path = useDigestAuthentication ? "A" : "$i";
+              String url = secure
+                  ? "https://localhost:${secureServer.port}/$path"
+                  : "http://localhost:${server.port}/$path";
+
+              client
+                  .postUrl(Uri.parse(url))
+                  .then((HttpClientRequest clientRequest) {
+                String content = "$i$i$i";
+                clientRequest.write(content);
+                return clientRequest.close();
+              }).then((HttpClientResponse response) {
+                response.listen((_) {}, onDone: () {
+                  testProxyAuthenticateCount++;
+                  expect(HttpStatus.OK, equals(response.statusCode));
+                  if (testProxyAuthenticateCount == loopCount * 2) {
+                    expect(loopCount, equals(server.requestCount));
+                    expect(loopCount, equals(secureServer.requestCount));
+                    step2.complete(null);
+                  }
+                });
+              });
+            }
+
+            test(false);
+            test(true);
+          }
+        });
+
+        step2.future.then((_) {
+          testProxyAuthenticateCount = 0;
+          client.findProxy = (Uri uri) {
+            return "PROXY localhost:${proxyServer.port}";
+          };
+
+          client.authenticateProxy = (host, port, scheme, realm) {
+            client.addProxyCredentials("localhost", proxyServer.port, "realm",
+                new HttpClientBasicCredentials("dart", "password"));
+            return new Future.value(true);
+          };
+
+          for (int i = 0; i < loopCount; i++) {
+            test(bool secure) {
+              String url = secure
+                  ? "https://localhost:${secureServer.port}/A"
+                  : "http://localhost:${server.port}/A";
+
+              client
+                  .postUrl(Uri.parse(url))
+                  .then((HttpClientRequest clientRequest) {
+                String content = "$i$i$i";
+                clientRequest.write(content);
+                return clientRequest.close();
+              }).then((HttpClientResponse response) {
+                response.listen((_) {}, onDone: () {
+                  testProxyAuthenticateCount++;
+                  expect(HttpStatus.OK, equals(response.statusCode));
+                  if (testProxyAuthenticateCount == loopCount * 2) {
+                    expect(loopCount * 2, equals(server.requestCount));
+                    expect(loopCount * 2, equals(secureServer.requestCount));
+                    proxyServer.shutdown();
+                    server.shutdown();
+                    secureServer.shutdown();
+                    client.close();
+                    completer.complete(null);
+                  }
+                });
+              });
+            }
+
+            test(false);
+            test(true);
+          }
+        });
+      });
+    });
+  });
+
+  return completer.future;
+}
+
+int testRealProxyDoneCount = 0;
+void testRealProxy() {
+  setupServer(1).then((server) {
+    HttpClient client = new HttpClient(context: clientContext);
+    client.addProxyCredentials("localhost", 8080, "test",
+        new HttpClientBasicCredentials("dart", "password"));
+
+    List<String> proxy = [
+      "PROXY localhost:8080",
+      "PROXY localhost:8080; PROXY hede.hule.hest:8080",
+      "PROXY hede.hule.hest:8080; PROXY localhost:8080",
+      "PROXY localhost:8080; DIRECT"
+    ];
+
+    client.findProxy = (Uri uri) {
+      // Pick the proxy configuration based on the request path.
+      int index = int.parse(uri.path.substring(1));
+      return proxy[index];
+    };
+
+    for (int i = 0; i < proxy.length; i++) {
+      client
+          .getUrl(Uri.parse("http://localhost:${server.port}/$i"))
+          .then((HttpClientRequest clientRequest) {
+        String content = "$i$i$i";
+        clientRequest.contentLength = content.length;
+        clientRequest.write(content);
+        return clientRequest.close();
+      }).then((HttpClientResponse response) {
+        response.listen((_) {}, onDone: () {
+          if (++testRealProxyDoneCount == proxy.length) {
+            expect(proxy.length, equals(server.requestCount));
+            server.shutdown();
+            client.close();
+          }
+        });
+      });
+    }
+  });
+}
+
+int testRealProxyAuthDoneCount = 0;
+void testRealProxyAuth() {
+  setupServer(1).then((server) {
+    HttpClient client = new HttpClient(context: clientContext);
+
+    List<String> proxy = [
+      "PROXY dart:password@localhost:8080",
+      "PROXY dart:password@localhost:8080; PROXY hede.hule.hest:8080",
+      "PROXY hede.hule.hest:8080; PROXY dart:password@localhost:8080",
+      "PROXY dart:password@localhost:8080; DIRECT"
+    ];
+
+    client.findProxy = (Uri uri) {
+      // Pick the proxy configuration based on the request path.
+      int index = int.parse(uri.path.substring(1));
+      return proxy[index];
+    };
+
+    for (int i = 0; i < proxy.length; i++) {
+      client
+          .getUrl(Uri.parse("http://localhost:${server.port}/$i"))
+          .then((HttpClientRequest clientRequest) {
+        String content = "$i$i$i";
+        clientRequest.contentLength = content.length;
+        clientRequest.write(content);
+        return clientRequest.close();
+      }).then((HttpClientResponse response) {
+        response.listen((_) {}, onDone: () {
+          if (++testRealProxyAuthDoneCount == proxy.length) {
+            expect(proxy.length, equals(server.requestCount));
+            server.shutdown();
+            client.close();
+          }
+        });
+      });
+    }
+  });
+}
+
+main() {
+  test('proxyIPV6', testProxyIPV6);
+  test('proxyFromEnvironment', testProxyFromEnviroment);
+  // The two invocations use the same global variable for state -
+  // run one after the other.
+  test('proxyAuth', () {
+    testProxyAuthenticate(false).then((_) => testProxyAuthenticate(true));
+  });
+
+  // This test is not normally run. It can be used for locally testing
+  // with a real proxy server (e.g. Apache).
+  // testRealProxy();
+  // testRealProxyAuth();
+}
