diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/MODULE_LICENSE_APACHE2
diff --git a/README.android b/README.android
new file mode 100644
index 0000000..7ce5ec6
--- /dev/null
+++ b/README.android
@@ -0,0 +1,4 @@
+URL: https://github.com/square/okhttp
+License: Apache 2
+Description: "OkHttp: An HTTP+SPDY client for Android and Java applications."
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..410f18b
--- /dev/null
+++ b/README.md
@@ -0,0 +1,71 @@
+OkHttp
+======
+
+An HTTP+SPDY client for Android and Java applications.
+
+
+Download
+--------
+
+Downloadable .jars can be found on the [GitHub download page][1].
+
+You can also depend on the .jar through Maven:
+
+```xml
+<dependency>
+    <groupId>com.squareup</groupId>
+    <artifactId>okhttp</artifactId>
+    <version>(insert latest version)</version>
+</dependency>
+```
+
+
+Known Issues
+------------
+
+The SPDY implementation is incomplete:
+
+* Settings frames are not honored. Flow control is not implemented.
+* It assumes a well-behaved peer. If the peer sends an invalid frame, OkHttp's SPDY client will not respond with the required `RST` frame.
+
+OkHttp uses the platform's [ProxySelector][2]. Prior to Android 4.0, `ProxySelector` didn't honor the `proxyHost` and `proxyPort` system properties for HTTPS connections. Work around this by specifying the `https.proxyHost` and `https.proxyPort` system properties when using a proxy with HTTPS.
+
+OkHttp's test suite creates an in-process HTTPS server. Prior to Android 2.3, SSL server sockets were broken, and so HTTPS tests will time out when run on such devices.
+
+
+Contributing
+------------
+
+If you would like to contribute code to OkHttp you can do so through GitHub by
+forking the repository and sending a pull request.
+
+When submitting code, please make every effort to follow existing conventions
+and style in order to keep the code as readable as possible. Please also make
+sure your code compiles by running `mvn clean verify`. Checkstyle failures
+during compilation indicate errors in your style and can be viewed in the
+`checkstyle-result.xml` file.
+
+Before your code can be accepted into the project you must also sign the
+[Individual Contributor License Agreement (CLA)][3].
+
+
+License
+-------
+
+    Licensed under the Apache License, Version 2.0 (the "License");
+    you may not use this file except in compliance with the License.
+    You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing, software
+    distributed under the License is distributed on an "AS IS" BASIS,
+    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+    See the License for the specific language governing permissions and
+    limitations under the License.
+
+
+
+ [1]: http://github.com/square/okhttp/downloads
+ [2]: http://developer.android.com/reference/java/net/ProxySelector.html
+ [3]: https://spreadsheets.google.com/spreadsheet/viewform?formkey=dDViT2xzUHAwRkI3X3k5Z0lQM091OGc6MQ&ndplr=1
diff --git a/checkstyle.xml b/checkstyle.xml
new file mode 100644
index 0000000..2864215
--- /dev/null
+++ b/checkstyle.xml
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<!DOCTYPE module PUBLIC
+    "-//Puppy Crawl//DTD Check Configuration 1.2//EN"
+    "http://www.puppycrawl.com/dtds/configuration_1_2.dtd">
+
+<module name="Checker">
+    <module name="NewlineAtEndOfFile"/>
+    <module name="FileLength"/>
+    <module name="FileTabCharacter"/>
+
+    <!-- Trailing spaces -->
+    <module name="RegexpSingleline">
+        <property name="format" value="\s+$"/>
+        <property name="message" value="Line has trailing spaces."/>
+    </module>
+
+    <module name="TreeWalker">
+        <property name="cacheFile" value="${checkstyle.cache.file}"/>
+
+        <!-- Checks for Javadoc comments.                     -->
+        <!-- See http://checkstyle.sf.net/config_javadoc.html -->
+        <!--module name="JavadocMethod"/-->
+        <!--module name="JavadocType"/-->
+        <!--module name="JavadocVariable"/-->
+        <module name="JavadocStyle"/>
+
+
+        <!-- Checks for Naming Conventions.                  -->
+        <!-- See http://checkstyle.sf.net/config_naming.html -->
+        <module name="ConstantName"/>
+        <module name="LocalFinalVariableName"/>
+        <module name="LocalVariableName"/>
+        <module name="MemberName"/>
+        <module name="MethodName"/>
+        <module name="PackageName"/>
+        <module name="ParameterName"/>
+        <module name="StaticVariableName"/>
+        <module name="TypeName"/>
+
+
+        <!-- Checks for imports                              -->
+        <!-- See http://checkstyle.sf.net/config_import.html -->
+        <module name="AvoidStarImport"/>
+        <module name="IllegalImport"/> <!-- defaults to sun.* packages -->
+        <module name="RedundantImport"/>
+        <module name="UnusedImports"/>
+
+
+        <!-- Checks for Size Violations.                    -->
+        <!-- See http://checkstyle.sf.net/config_sizes.html -->
+        <module name="LineLength">
+            <property name="max" value="120"/>
+        </module>
+        <module name="MethodLength"/>
+        <module name="ParameterNumber"/>
+
+
+        <!-- Checks for whitespace                               -->
+        <!-- See http://checkstyle.sf.net/config_whitespace.html -->
+        <module name="GenericWhitespace"/>
+        <module name="EmptyForIteratorPad"/>
+        <module name="MethodParamPad"/>
+        <module name="NoWhitespaceAfter"/>
+        <module name="NoWhitespaceBefore"/>
+        <module name="OperatorWrap"/>
+        <module name="ParenPad"/>
+        <module name="TypecastParenPad"/>
+        <module name="WhitespaceAfter"/>
+        <module name="WhitespaceAround"/>
+
+
+        <!-- Modifier Checks                                    -->
+        <!-- See http://checkstyle.sf.net/config_modifiers.html -->
+        <!--module name="ModifierOrder"/-->
+        <module name="RedundantModifier"/>
+
+
+        <!-- Checks for blocks. You know, those {}'s         -->
+        <!-- See http://checkstyle.sf.net/config_blocks.html -->
+        <module name="AvoidNestedBlocks"/>
+        <!--module name="EmptyBlock"/-->
+        <module name="LeftCurly"/>
+        <module name="NeedBraces"/>
+        <module name="RightCurly"/>
+
+
+        <!-- Checks for common coding problems               -->
+        <!-- See http://checkstyle.sf.net/config_coding.html -->
+        <!--module name="AvoidInlineConditionals"/-->
+        <module name="CovariantEquals"/>
+        <module name="DoubleCheckedLocking"/>
+        <module name="EmptyStatement"/>
+        <!--<module name="EqualsAvoidNull"/>-->
+        <module name="EqualsHashCode"/>
+        <!--module name="HiddenField"/-->
+        <module name="IllegalInstantiation"/>
+        <!--module name="InnerAssignment"/-->
+        <!--module name="MagicNumber"/-->
+        <!--module name="MissingSwitchDefault"/-->
+        <module name="RedundantThrows"/>
+        <module name="SimplifyBooleanExpression"/>
+        <module name="SimplifyBooleanReturn"/>
+
+        <!-- Checks for class design                         -->
+        <!-- See http://checkstyle.sf.net/config_design.html -->
+        <!--module name="DesignForExtension"/-->
+        <module name="FinalClass"/>
+        <module name="HideUtilityClassConstructor"/>
+        <module name="InterfaceIsType"/>
+        <!--s/module name="VisibilityModifier"/-->
+
+
+        <!-- Miscellaneous other checks.                   -->
+        <!-- See http://checkstyle.sf.net/config_misc.html -->
+        <module name="ArrayTypeStyle"/>
+        <!--module name="FinalParameters"/-->
+        <!--module name="TodoComment"/-->
+        <module name="UpperEll"/>
+    </module>
+</module>
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..336c964
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ Copyright (C) 2012 Square, Inc.
+ Copyright (C) 2012 The Android Open Source Project
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.sonatype.oss</groupId>
+        <artifactId>oss-parent</artifactId>
+        <version>7</version>
+    </parent>
+    <groupId>com.squareup</groupId>
+    <artifactId>okhttp</artifactId>
+    <version>0.8-SNAPSHOT</version>
+    <packaging>jar</packaging>
+
+    <name>okhttp</name>
+    <description>An HTTP+SPDY client for Android and Java applications</description>
+    <url>https://github.com/square/okhttp</url>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+        <!-- Compilation -->
+        <java.version>1.6</java.version>
+        <npn.version>8.1.2.v20120308</npn.version>
+        <mockwebserver.version>20120731</mockwebserver.version>
+        <bouncycastle.version>1.47</bouncycastle.version>
+
+        <!-- Test Dependencies -->
+        <junit.version>3.8.2</junit.version>
+    </properties>
+
+    <scm>
+        <url>https://github.com/square/okhttp/</url>
+        <connection>scm:git:https://github.com/square/okhttp.git</connection>
+        <developerConnection>scm:git:git@github.com:square/okhttp.git</developerConnection>
+    </scm>
+
+    <issueManagement>
+        <system>GitHub Issues</system>
+        <url>https://github.com/square/okhttp/issues</url>
+    </issueManagement>
+
+    <licenses>
+        <license>
+            <name>Apache 2.0</name>
+            <url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
+        </license>
+    </licenses>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.mortbay.jetty.npn</groupId>
+            <artifactId>npn-boot</artifactId>
+            <version>${npn.version}</version>
+        </dependency>
+        <dependency>
+            <groupId>com.google.mockwebserver</groupId>
+            <artifactId>mockwebserver</artifactId>
+            <version>${mockwebserver.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>${junit.version}</version>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.bouncycastle</groupId>
+            <artifactId>bcprov-jdk15on</artifactId>
+            <version>${bouncycastle.version}</version>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <version>2.5</version>
+                <configuration>
+                    <source>${java.version}</source>
+                    <target>${java.version}</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.sonatype.plugins</groupId>
+                <artifactId>jarjar-maven-plugin</artifactId>
+                <version>1.5</version>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>jarjar</goal>
+                        </goals>
+                        <configuration>
+                            <includes>
+                                <include>asm:asm</include>
+                                <include>org.sonatype.sisu.inject:cglib</include>
+                            </includes>
+                            <rules>
+                                <rule>
+                                    <pattern>libcore.**</pattern>
+                                    <result>com.squareup.okhttp.libcore.@1</result>
+                                </rule>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.9</version>
+                <configuration>
+                    <argLine>-Xbootclasspath/p:${settings.localRepository}/org/mortbay/jetty/npn/npn-boot/${npn.version}/npn-boot-${npn.version}.jar</argLine>
+                </configuration>
+            </plugin>
+            <plugin>
+                <!--
+                  OkHttp requires with javac >= 1.7 for syncFlush on DeflaterOutputStream.
+                  Its language version must be <= 1.6 for dx.
+
+                  Running this code on Java 6 or earlier will fail at runtime due to the missing
+                  syncFlush API.
+
+                  Dalvik's core library includes syncFlush, but with an @hide tag so that it doesn't
+                  show up in the documentation or the android.jar stubs. This code works fine on
+                  Dalvik.
+                -->
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-enforcer-plugin</artifactId>
+                <version>1.1</version>
+                <executions>
+                    <execution>
+                        <id>enforce-java</id>
+                        <goals>
+                            <goal>enforce</goal>
+                        </goals>
+                        <configuration>
+                            <rules>
+                                <requireJavaVersion>
+                                    <version>[1.7.0,)</version>
+                                </requireJavaVersion>
+                            </rules>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-checkstyle-plugin</artifactId>
+                <version>2.9.1</version>
+                <configuration>
+                    <failsOnError>true</failsOnError>
+                    <configLocation>checkstyle.xml</configLocation>
+                    <excludes>**/OsConstants.java</excludes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <phase>verify</phase>
+                        <goals>
+                            <goal>checkstyle</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
+
diff --git a/src/main/java/com/squareup/okhttp/OkHttpConnection.java b/src/main/java/com/squareup/okhttp/OkHttpConnection.java
new file mode 100644
index 0000000..5df657a
--- /dev/null
+++ b/src/main/java/com/squareup/okhttp/OkHttpConnection.java
@@ -0,0 +1,829 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.squareup.okhttp;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+import libcore.net.http.HttpEngine;
+
+/**
+ * An {@link java.net.URLConnection} for HTTP (<a
+ * href="http://tools.ietf.org/html/rfc2616">RFC 2616</a>) used to send and
+ * receive data over the web. Data may be of any type and length. This class may
+ * be used to send and receive streaming data whose length is not known in
+ * advance.
+ *
+ * <p>Uses of this class follow a pattern:
+ * <ol>
+ *   <li>Obtain a new {@code HttpURLConnection} by calling {@link
+ *       java.net.URL#openConnection() URL.openConnection()} and casting the result to
+ *       {@code HttpURLConnection}.
+ *   <li>Prepare the request. The primary property of a request is its URI.
+ *       Request headers may also include metadata such as credentials, preferred
+ *       content types, and session cookies.
+ *   <li>Optionally upload a request body. Instances must be configured with
+ *       {@link #setDoOutput(boolean) setDoOutput(true)} if they include a
+ *       request body. Transmit data by writing to the stream returned by {@link
+ *       #getOutputStream()}.
+ *   <li>Read the response. Response headers typically include metadata such as
+ *       the response body's content type and length, modified dates and session
+ *       cookies. The response body may be read from the stream returned by {@link
+ *       #getInputStream()}. If the response has no body, that method returns an
+ *       empty stream.
+ *   <li>Disconnect. Once the response body has been read, the {@code
+ *       HttpURLConnection} should be closed by calling {@link #disconnect()}.
+ *       Disconnecting releases the resources held by a connection so they may
+ *       be closed or reused.
+ * </ol>
+ *
+ * <p>For example, to retrieve the webpage at {@code http://www.android.com/}:
+ * <pre>   {@code
+ *   URL url = new URL("http://www.android.com/");
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     readStream(in);
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>Secure Communication with HTTPS</h3>
+ * Calling {@link java.net.URL#openConnection()} on a URL with the "https"
+ * scheme will return an {@code HttpsURLConnection}, which allows for
+ * overriding the default {@link javax.net.ssl.HostnameVerifier
+ * HostnameVerifier} and {@link javax.net.ssl.SSLSocketFactory
+ * SSLSocketFactory}. An application-supplied {@code SSLSocketFactory}
+ * created from an {@link javax.net.ssl.SSLContext SSLContext} can
+ * provide a custom {@link javax.net.ssl.X509TrustManager
+ * X509TrustManager} for verifying certificate chains and a custom
+ * {@link javax.net.ssl.X509KeyManager X509KeyManager} for supplying
+ * client certificates. See {@link OkHttpsConnection HttpsURLConnection} for
+ * more details.
+ *
+ * <h3>Response Handling</h3>
+ * {@code HttpURLConnection} will follow up to five HTTP redirects. It will
+ * follow redirects from one origin server to another. This implementation
+ * doesn't follow redirects from HTTPS to HTTP or vice versa.
+ *
+ * <p>If the HTTP response indicates that an error occurred, {@link
+ * #getInputStream()} will throw an {@link java.io.IOException}. Use {@link
+ * #getErrorStream()} to read the error response. The headers can be read in
+ * the normal way using {@link #getHeaderFields()},
+ *
+ * <h3>Posting Content</h3>
+ * To upload data to a web server, configure the connection for output using
+ * {@link #setDoOutput(boolean) setDoOutput(true)}.
+ *
+ * <p>For best performance, you should call either {@link
+ * #setFixedLengthStreamingMode(int)} when the body length is known in advance,
+ * or {@link #setChunkedStreamingMode(int)} when it is not. Otherwise {@code
+ * HttpURLConnection} will be forced to buffer the complete request body in
+ * memory before it is transmitted, wasting (and possibly exhausting) heap and
+ * increasing latency.
+ *
+ * <p>For example, to perform an upload: <pre>   {@code
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     urlConnection.setDoOutput(true);
+ *     urlConnection.setChunkedStreamingMode(0);
+ *
+ *     OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());
+ *     writeStream(out);
+ *
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     readStream(in);
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>Performance</h3>
+ * The input and output streams returned by this class are <strong>not
+ * buffered</strong>. Most callers should wrap the returned streams with {@link
+ * java.io.BufferedInputStream BufferedInputStream} or {@link
+ * java.io.BufferedOutputStream BufferedOutputStream}. Callers that do only bulk
+ * reads or writes may omit buffering.
+ *
+ * <p>When transferring large amounts of data to or from a server, use streams
+ * to limit how much data is in memory at once. Unless you need the entire
+ * body to be in memory at once, process it as a stream (rather than storing
+ * the complete body as a single byte array or string).
+ *
+ * <p>To reduce latency, this class may reuse the same underlying {@code Socket}
+ * for multiple request/response pairs. As a result, HTTP connections may be
+ * held open longer than necessary. Calls to {@link #disconnect()} may return
+ * the socket to a pool of connected sockets. This behavior can be disabled by
+ * setting the {@code http.keepAlive} system property to {@code false} before
+ * issuing any HTTP requests. The {@code http.maxConnections} property may be
+ * used to control how many idle connections to each server will be held.
+ *
+ * <p>By default, this implementation of {@code HttpURLConnection} requests that
+ * servers use gzip compression. Since {@link #getContentLength()} returns the
+ * number of bytes transmitted, you cannot use that method to predict how many
+ * bytes can be read from {@link #getInputStream()}. Instead, read that stream
+ * until it is exhausted: when {@link java.io.InputStream#read} returns -1. Gzip
+ * compression can be disabled by setting the acceptable encodings in the
+ * request header: <pre>   {@code
+ *   urlConnection.setRequestProperty("Accept-Encoding", "identity");
+ * }</pre>
+ *
+ * <h3>Handling Network Sign-On</h3>
+ * Some Wi-Fi networks block Internet access until the user clicks through a
+ * sign-on page. Such sign-on pages are typically presented by using HTTP
+ * redirects. You can use {@link #getURL()} to test if your connection has been
+ * unexpectedly redirected. This check is not valid until <strong>after</strong>
+ * the response headers have been received, which you can trigger by calling
+ * {@link #getHeaderFields()} or {@link #getInputStream()}. For example, to
+ * check that a response was not redirected to an unexpected host:
+ * <pre>   {@code
+ *   HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
+ *   try {
+ *     InputStream in = new BufferedInputStream(urlConnection.getInputStream());
+ *     if (!url.getHost().equals(urlConnection.getURL().getHost())) {
+ *       // we were redirected! Kick the user out to the browser to sign on?
+ *     }
+ *     ...
+ *   } finally {
+ *     urlConnection.disconnect();
+ *   }
+ * }</pre>
+ *
+ * <h3>HTTP Authentication</h3>
+ * {@code HttpURLConnection} supports <a
+ * href="http://www.ietf.org/rfc/rfc2617">HTTP basic authentication</a>. Use
+ * {@link java.net.Authenticator} to set the VM-wide authentication handler:
+ * <pre>   {@code
+ *   Authenticator.setDefault(new Authenticator() {
+ *     protected PasswordAuthentication getPasswordAuthentication() {
+ *       return new PasswordAuthentication(username, password.toCharArray());
+ *     }
+ *   });
+ * }</pre>
+ * Unless paired with HTTPS, this is <strong>not</strong> a secure mechanism for
+ * user authentication. In particular, the username, password, request and
+ * response are all transmitted over the network without encryption.
+ *
+ * <h3>Sessions with Cookies</h3>
+ * To establish and maintain a potentially long-lived session between client
+ * and server, {@code HttpURLConnection} includes an extensible cookie manager.
+ * Enable VM-wide cookie management using {@link java.net.CookieHandler} and {@link
+ * java.net.CookieManager}: <pre>   {@code
+ *   CookieManager cookieManager = new CookieManager();
+ *   CookieHandler.setDefault(cookieManager);
+ * }</pre>
+ * By default, {@code CookieManager} accepts cookies from the <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
+ * server</a> only. Two other policies are included: {@link
+ * java.net.CookiePolicy#ACCEPT_ALL} and {@link java.net.CookiePolicy#ACCEPT_NONE}. Implement
+ * {@link java.net.CookiePolicy} to define a custom policy.
+ *
+ * <p>The default {@code CookieManager} keeps all accepted cookies in memory. It
+ * will forget these cookies when the VM exits. Implement {@link java.net.CookieStore} to
+ * define a custom cookie store.
+ *
+ * <p>In addition to the cookies set by HTTP responses, you may set cookies
+ * programmatically. To be included in HTTP request headers, cookies must have
+ * the domain and path properties set.
+ *
+ * <p>By default, new instances of {@code HttpCookie} work only with servers
+ * that support <a href="http://www.ietf.org/rfc/rfc2965.txt">RFC 2965</a>
+ * cookies. Many web servers support only the older specification, <a
+ * href="http://www.ietf.org/rfc/rfc2109.txt">RFC 2109</a>. For compatibility
+ * with the most web servers, set the cookie version to 0.
+ *
+ * <p>For example, to receive {@code www.twitter.com} in French: <pre>   {@code
+ *   HttpCookie cookie = new HttpCookie("lang", "fr");
+ *   cookie.setDomain("twitter.com");
+ *   cookie.setPath("/");
+ *   cookie.setVersion(0);
+ *   cookieManager.getCookieStore().add(new URI("http://twitter.com/"), cookie);
+ * }</pre>
+ *
+ * <h3>HTTP Methods</h3>
+ * <p>{@code HttpURLConnection} uses the {@code GET} method by default. It will
+ * use {@code POST} if {@link #setDoOutput setDoOutput(true)} has been called.
+ * Other HTTP methods ({@code OPTIONS}, {@code HEAD}, {@code PUT}, {@code
+ * DELETE} and {@code TRACE}) can be used with {@link #setRequestMethod}.
+ *
+ * <h3>Proxies</h3>
+ * By default, this class will connect directly to the <a
+ * href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec1.html">origin
+ * server</a>. It can also connect via an {@link java.net.Proxy.Type#HTTP HTTP} or {@link
+ * java.net.Proxy.Type#SOCKS SOCKS} proxy. To use a proxy, use {@link
+ * java.net.URL#openConnection(java.net.Proxy) URL.openConnection(Proxy)} when creating the
+ * connection.
+ *
+ * <h3>IPv6 Support</h3>
+ * <p>This class includes transparent support for IPv6. For hosts with both IPv4
+ * and IPv6 addresses, it will attempt to connect to each of a host's addresses
+ * until a connection is established.
+ *
+ * <h3>Response Caching</h3>
+ * Android 4.0 (Ice Cream Sandwich) includes a response cache. See {@code
+ * android.net.http.HttpResponseCache} for instructions on enabling HTTP caching
+ * in your application.
+ *
+ * <h3>Avoiding Bugs In Earlier Releases</h3>
+ * Prior to Android 2.2 (Froyo), this class had some frustrating bugs. In
+ * particular, calling {@code close()} on a readable {@code InputStream} could
+ * <a href="http://code.google.com/p/android/issues/detail?id=2939">poison the
+ * connection pool</a>. Work around this by disabling connection pooling:
+ * <pre>   {@code
+ * private void disableConnectionReuseIfNecessary() {
+ *   // Work around pre-Froyo bugs in HTTP connection reuse.
+ *   if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO) {
+ *     System.setProperty("http.keepAlive", "false");
+ *   }
+ * }}</pre>
+ *
+ * <p>Each instance of {@code HttpURLConnection} may be used for one
+ * request/response pair. Instances of this class are not thread safe.
+ */
+public abstract class OkHttpConnection extends URLConnection {
+
+    /**
+     * The subset of HTTP methods that the user may select via {@link
+     * #setRequestMethod(String)}.
+     */
+    private static final String[] PERMITTED_USER_METHODS = {
+            HttpEngine.OPTIONS,
+            HttpEngine.GET,
+            HttpEngine.HEAD,
+            HttpEngine.POST,
+            HttpEngine.PUT,
+            HttpEngine.DELETE,
+            HttpEngine.TRACE
+            // Note: we don't allow users to specify "CONNECT"
+    };
+
+    /**
+     * The HTTP request method of this {@code HttpURLConnection}. The default
+     * value is {@code "GET"}.
+     */
+    protected String method = HttpEngine.GET;
+
+    /**
+     * The status code of the response obtained from the HTTP request. The
+     * default value is {@code -1}.
+     * <p>
+     * <li>1xx: Informational</li>
+     * <li>2xx: Success</li>
+     * <li>3xx: Relocation/Redirection</li>
+     * <li>4xx: Client Error</li>
+     * <li>5xx: Server Error</li>
+     */
+    protected int responseCode = -1;
+
+    /**
+     * The HTTP response message which corresponds to the response code.
+     */
+    protected String responseMessage;
+
+    /**
+     * Flag to define whether the protocol will automatically follow redirects
+     * or not. The default value is {@code true}.
+     */
+    protected boolean instanceFollowRedirects = followRedirects;
+
+    private static boolean followRedirects = true;
+
+    /**
+     * If the HTTP chunked encoding is enabled this parameter defines the
+     * chunk-length. Default value is {@code -1} that means the chunked encoding
+     * mode is disabled.
+     */
+    protected int chunkLength = -1;
+
+    /**
+     * If using HTTP fixed-length streaming mode this parameter defines the
+     * fixed length of content. Default value is {@code -1} that means the
+     * fixed-length streaming mode is disabled.
+     */
+    protected int fixedContentLength = -1;
+
+    // 2XX: generally "OK"
+    // 3XX: relocation/redirect
+    // 4XX: client error
+    // 5XX: server error
+    /**
+     * Numeric status code, 202: Accepted.
+     */
+    public static final int HTTP_ACCEPTED = 202;
+
+    /**
+     * Numeric status code, 502: Bad Gateway.
+     */
+    public static final int HTTP_BAD_GATEWAY = 502;
+
+    /**
+     * Numeric status code, 405: Bad Method.
+     */
+    public static final int HTTP_BAD_METHOD = 405;
+
+    /**
+     * Numeric status code, 400: Bad Request.
+     */
+    public static final int HTTP_BAD_REQUEST = 400;
+
+    /**
+     * Numeric status code, 408: Client Timeout.
+     */
+    public static final int HTTP_CLIENT_TIMEOUT = 408;
+
+    /**
+     * Numeric status code, 409: Conflict.
+     */
+    public static final int HTTP_CONFLICT = 409;
+
+    /**
+     * Numeric status code, 201: Created.
+     */
+    public static final int HTTP_CREATED = 201;
+
+    /**
+     * Numeric status code, 413: Entity too large.
+     */
+    public static final int HTTP_ENTITY_TOO_LARGE = 413;
+
+    /**
+     * Numeric status code, 403: Forbidden.
+     */
+    public static final int HTTP_FORBIDDEN = 403;
+
+    /**
+     * Numeric status code, 504: Gateway timeout.
+     */
+    public static final int HTTP_GATEWAY_TIMEOUT = 504;
+
+    /**
+     * Numeric status code, 410: Gone.
+     */
+    public static final int HTTP_GONE = 410;
+
+    /**
+     * Numeric status code, 500: Internal error.
+     */
+    public static final int HTTP_INTERNAL_ERROR = 500;
+
+    /**
+     * Numeric status code, 411: Length required.
+     */
+    public static final int HTTP_LENGTH_REQUIRED = 411;
+
+    /**
+     * Numeric status code, 301 Moved permanently.
+     */
+    public static final int HTTP_MOVED_PERM = 301;
+
+    /**
+     * Numeric status code, 302: Moved temporarily.
+     */
+    public static final int HTTP_MOVED_TEMP = 302;
+
+    /**
+     * Numeric status code, 300: Multiple choices.
+     */
+    public static final int HTTP_MULT_CHOICE = 300;
+
+    /**
+     * Numeric status code, 204: No content.
+     */
+    public static final int HTTP_NO_CONTENT = 204;
+
+    /**
+     * Numeric status code, 406: Not acceptable.
+     */
+    public static final int HTTP_NOT_ACCEPTABLE = 406;
+
+    /**
+     * Numeric status code, 203: Not authoritative.
+     */
+    public static final int HTTP_NOT_AUTHORITATIVE = 203;
+
+    /**
+     * Numeric status code, 404: Not found.
+     */
+    public static final int HTTP_NOT_FOUND = 404;
+
+    /**
+     * Numeric status code, 501: Not implemented.
+     */
+    public static final int HTTP_NOT_IMPLEMENTED = 501;
+
+    /**
+     * Numeric status code, 304: Not modified.
+     */
+    public static final int HTTP_NOT_MODIFIED = 304;
+
+    /**
+     * Numeric status code, 200: OK.
+     */
+    public static final int HTTP_OK = 200;
+
+    /**
+     * Numeric status code, 206: Partial.
+     */
+    public static final int HTTP_PARTIAL = 206;
+
+    /**
+     * Numeric status code, 402: Payment required.
+     */
+    public static final int HTTP_PAYMENT_REQUIRED = 402;
+
+    /**
+     * Numeric status code, 412: Precondition failed.
+     */
+    public static final int HTTP_PRECON_FAILED = 412;
+
+    /**
+     * Numeric status code, 407: Proxy authentication required.
+     */
+    public static final int HTTP_PROXY_AUTH = 407;
+
+    /**
+     * Numeric status code, 414: Request too long.
+     */
+    public static final int HTTP_REQ_TOO_LONG = 414;
+
+    /**
+     * Numeric status code, 205: Reset.
+     */
+    public static final int HTTP_RESET = 205;
+
+    /**
+     * Numeric status code, 303: See other.
+     */
+    public static final int HTTP_SEE_OTHER = 303;
+
+    /**
+     * Numeric status code, 500: Internal error.
+     *
+     * @deprecated Use {@link #HTTP_INTERNAL_ERROR}
+     */
+    @Deprecated
+    public static final int HTTP_SERVER_ERROR = 500;
+
+    /**
+     * Numeric status code, 305: Use proxy.
+     *
+     * <p>Like Firefox and Chrome, this class doesn't honor this response code.
+     * Other implementations respond to this status code by retrying the request
+     * using the HTTP proxy named by the response's Location header field.
+     */
+    public static final int HTTP_USE_PROXY = 305;
+
+    /**
+     * Numeric status code, 401: Unauthorized.
+     */
+    public static final int HTTP_UNAUTHORIZED = 401;
+
+    /**
+     * Numeric status code, 415: Unsupported type.
+     */
+    public static final int HTTP_UNSUPPORTED_TYPE = 415;
+
+    /**
+     * Numeric status code, 503: Unavailable.
+     */
+    public static final int HTTP_UNAVAILABLE = 503;
+
+    /**
+     * Numeric status code, 505: Version not supported.
+     */
+    public static final int HTTP_VERSION = 505;
+
+    /**
+     * Returns a new OkHttpConnection or OkHttpsConnection to {@code url}.
+     */
+    public static OkHttpConnection open(URL url) {
+        String protocol = url.getProtocol();
+        if (protocol.equals("http")) {
+            return new libcore.net.http.HttpURLConnectionImpl(url, 80);
+        } else if (protocol.equals("https")) {
+            return new libcore.net.http.HttpsURLConnectionImpl(url, 443);
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Returns a new OkHttpConnection or OkHttpsConnection to {@code url} that
+     * connects via {@code proxy}.
+     */
+    public static OkHttpConnection open(URL url, Proxy proxy) {
+        String protocol = url.getProtocol();
+        if (protocol.equals("http")) {
+            return new libcore.net.http.HttpURLConnectionImpl(url, 80, proxy);
+        } else if (protocol.equals("https")) {
+            return new libcore.net.http.HttpsURLConnectionImpl(url, 443, proxy);
+        } else {
+            throw new IllegalArgumentException();
+        }
+    }
+
+    /**
+     * Constructs a new {@code HttpURLConnection} instance pointing to the
+     * resource specified by the {@code url}.
+     *
+     * @param url
+     *            the URL of this connection.
+     * @see java.net.URL
+     * @see java.net.URLConnection
+     */
+    protected OkHttpConnection(URL url) {
+        super(url);
+    }
+
+    /**
+     * Releases this connection so that its resources may be either reused or
+     * closed.
+     *
+     * <p>Unlike other Java implementations, this will not necessarily close
+     * socket connections that can be reused. You can disable all connection
+     * reuse by setting the {@code http.keepAlive} system property to {@code
+     * false} before issuing any HTTP requests.
+     */
+    public abstract void disconnect();
+
+    /**
+     * Returns an input stream from the server in the case of an error such as
+     * the requested file has not been found on the remote server. This stream
+     * can be used to read the data the server will send back.
+     *
+     * @return the error input stream returned by the server.
+     */
+    public InputStream getErrorStream() {
+        return null;
+    }
+
+    /**
+     * Returns the value of {@code followRedirects} which indicates if this
+     * connection follows a different URL redirected by the server. It is
+     * enabled by default.
+     *
+     * @return the value of the flag.
+     * @see #setFollowRedirects
+     */
+    public static boolean getFollowRedirects() {
+        return followRedirects;
+    }
+
+    /**
+     * Returns the permission object (in this case {@code SocketPermission})
+     * with the host and the port number as the target name and {@code
+     * "resolve, connect"} as the action list. If the port number of this URL
+     * instance is lower than {@code 0} the port will be set to {@code 80}.
+     *
+     * @return the permission object required for this connection.
+     * @throws java.io.IOException
+     *             if an IO exception occurs during the creation of the
+     *             permission object.
+     */
+    @Override
+    public java.security.Permission getPermission() throws IOException {
+        int port = url.getPort();
+        if (port < 0) {
+            port = 80;
+        }
+        return new SocketPermission(url.getHost() + ":" + port,
+                "connect, resolve");
+    }
+
+    /**
+     * Returns the request method which will be used to make the request to the
+     * remote HTTP server. All possible methods of this HTTP implementation is
+     * listed in the class definition.
+     *
+     * @return the request method string.
+     * @see #method
+     * @see #setRequestMethod
+     */
+    public String getRequestMethod() {
+        return method;
+    }
+
+    /**
+     * Returns the response code returned by the remote HTTP server.
+     *
+     * @return the response code, -1 if no valid response code.
+     * @throws java.io.IOException
+     *             if there is an IO error during the retrieval.
+     * @see #getResponseMessage
+     */
+    public int getResponseCode() throws IOException {
+        // Call getInputStream() first since getHeaderField() doesn't return
+        // exceptions
+        getInputStream();
+        String response = getHeaderField(0);
+        if (response == null) {
+            return -1;
+        }
+        response = response.trim();
+        int mark = response.indexOf(" ") + 1;
+        if (mark == 0) {
+            return -1;
+        }
+        int last = mark + 3;
+        if (last > response.length()) {
+            last = response.length();
+        }
+        responseCode = Integer.parseInt(response.substring(mark, last));
+        if (last + 1 <= response.length()) {
+            responseMessage = response.substring(last + 1);
+        }
+        return responseCode;
+    }
+
+    /**
+     * Returns the response message returned by the remote HTTP server.
+     *
+     * @return the response message. {@code null} if no such response exists.
+     * @throws java.io.IOException
+     *             if there is an error during the retrieval.
+     * @see #getResponseCode()
+     */
+    public String getResponseMessage() throws IOException {
+        if (responseMessage != null) {
+            return responseMessage;
+        }
+        getResponseCode();
+        return responseMessage;
+    }
+
+    /**
+     * Sets the flag of whether this connection will follow redirects returned
+     * by the remote server.
+     *
+     * @param auto
+     *            the value to enable or disable this option.
+     */
+    public static void setFollowRedirects(boolean auto) {
+        followRedirects = auto;
+    }
+
+    /**
+     * Sets the request command which will be sent to the remote HTTP server.
+     * This method can only be called before the connection is made.
+     *
+     * @param method
+     *            the string representing the method to be used.
+     * @throws java.net.ProtocolException
+     *             if this is called after connected, or the method is not
+     *             supported by this HTTP implementation.
+     * @see #getRequestMethod()
+     * @see #method
+     */
+    public void setRequestMethod(String method) throws ProtocolException {
+        if (connected) {
+            throw new ProtocolException("Connection already established");
+        }
+        for (String permittedUserMethod : PERMITTED_USER_METHODS) {
+            if (permittedUserMethod.equals(method)) {
+                // if there is a supported method that matches the desired
+                // method, then set the current method and return
+                this.method = permittedUserMethod;
+                return;
+            }
+        }
+        // if none matches, then throw ProtocolException
+        throw new ProtocolException("Unknown method '" + method + "'; must be one of "
+                + Arrays.toString(PERMITTED_USER_METHODS));
+    }
+
+    /**
+     * Returns whether this connection uses a proxy server or not.
+     *
+     * @return {@code true} if this connection passes a proxy server, false
+     *         otherwise.
+     */
+    public abstract boolean usingProxy();
+
+    /**
+     * Returns the encoding used to transmit the response body over the network.
+     * This is null or "identity" if the content was not encoded, or "gzip" if
+     * the body was gzip compressed. Most callers will be more interested in the
+     * {@link #getContentType() content type}, which may also include the
+     * content's character encoding.
+     */
+    @Override public String getContentEncoding() {
+        return super.getContentEncoding(); // overridden for Javadoc only
+    }
+
+    /**
+     * Returns whether this connection follows redirects.
+     *
+     * @return {@code true} if this connection follows redirects, false
+     *         otherwise.
+     */
+    public boolean getInstanceFollowRedirects() {
+        return instanceFollowRedirects;
+    }
+
+    /**
+     * Sets whether this connection follows redirects.
+     *
+     * @param followRedirects
+     *            {@code true} if this connection will follows redirects, false
+     *            otherwise.
+     */
+    public void setInstanceFollowRedirects(boolean followRedirects) {
+        instanceFollowRedirects = followRedirects;
+    }
+
+    /**
+     * Returns the date value in milliseconds since {@code 01.01.1970, 00:00h}
+     * corresponding to the header field {@code field}. The {@code defaultValue}
+     * will be returned if no such field can be found in the response header.
+     *
+     * @param field
+     *            the header field name.
+     * @param defaultValue
+     *            the default value to use if the specified header field wont be
+     *            found.
+     * @return the header field represented in milliseconds since January 1,
+     *         1970 GMT.
+     */
+    @Override
+    public long getHeaderFieldDate(String field, long defaultValue) {
+        return super.getHeaderFieldDate(field, defaultValue);
+    }
+
+    /**
+     * If the length of a HTTP request body is known ahead, sets fixed length to
+     * enable streaming without buffering. Sets after connection will cause an
+     * exception.
+     *
+     * @see #setChunkedStreamingMode
+     * @param contentLength
+     *            the fixed length of the HTTP request body.
+     * @throws IllegalStateException
+     *             if already connected or another mode already set.
+     * @throws IllegalArgumentException
+     *             if {@code contentLength} is less than zero.
+     */
+    public void setFixedLengthStreamingMode(int contentLength) {
+        if (super.connected) {
+            throw new IllegalStateException("Already connected");
+        }
+        if (chunkLength > 0) {
+            throw new IllegalStateException("Already in chunked mode");
+        }
+        if (contentLength < 0) {
+            throw new IllegalArgumentException("contentLength < 0");
+        }
+        this.fixedContentLength = contentLength;
+    }
+
+    /**
+     * Stream a request body whose length is not known in advance. Old HTTP/1.0
+     * only servers may not support this mode.
+     *
+     * <p>When HTTP chunked encoding is used, the stream is divided into
+     * chunks, each prefixed with a header containing the chunk's size. Setting
+     * a large chunk length requires a large internal buffer, potentially
+     * wasting memory. Setting a small chunk length increases the number of
+     * bytes that must be transmitted because of the header on every chunk.
+     * Most caller should use {@code 0} to get the system default.
+     *
+     * @see #setFixedLengthStreamingMode
+     * @param chunkLength the length to use, or {@code 0} for the default chunk
+     *     length.
+     * @throws IllegalStateException if already connected or another mode
+     *     already set.
+     */
+    public void setChunkedStreamingMode(int chunkLength) {
+        if (super.connected) {
+            throw new IllegalStateException("Already connected");
+        }
+        if (fixedContentLength >= 0) {
+            throw new IllegalStateException("Already in fixed-length mode");
+        }
+        if (chunkLength <= 0) {
+            this.chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
+        } else {
+            this.chunkLength = chunkLength;
+        }
+    }
+}
diff --git a/src/main/java/com/squareup/okhttp/OkHttpsConnection.java b/src/main/java/com/squareup/okhttp/OkHttpsConnection.java
new file mode 100644
index 0000000..669a26e
--- /dev/null
+++ b/src/main/java/com/squareup/okhttp/OkHttpsConnection.java
@@ -0,0 +1,300 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package com.squareup.okhttp;
+
+import java.net.URL;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocketFactory;
+
+/**
+ * An {@link java.net.HttpURLConnection} for HTTPS (<a
+ * href="http://tools.ietf.org/html/rfc2818">RFC 2818</a>). A
+ * connected {@code HttpsURLConnection} allows access to the
+ * negotiated cipher suite, the server certificate chain, and the
+ * client certificate chain if any.
+ *
+ * <h3>Providing an application specific X509TrustManager</h3>
+ *
+ * If an application wants to trust Certificate Authority (CA)
+ * certificates that are not part of the system, it should specify its
+ * own {@code X509TrustManager} via a {@code SSLSocketFactory} set on
+ * the {@code HttpsURLConnection}. The {@code X509TrustManager} can be
+ * created based on a {@code KeyStore} using a {@code
+ * TrustManagerFactory} to supply trusted CA certificates. Note that
+ * self-signed certificates are effectively their own CA and can be
+ * trusted by including them in a {@code KeyStore}.
+ *
+ * <p>For example, to trust a set of certificates specified by a {@code KeyStore}:
+ * <pre>   {@code
+ *   KeyStore keyStore = ...;
+ *   TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
+ *   tmf.init(keyStore);
+ *
+ *   SSLContext context = SSLContext.getInstance("TLS");
+ *   context.init(null, tmf.getTrustManagers(), null);
+ *
+ *   URL url = new URL("https://www.example.com/");
+ *   HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
+ *   urlConnection.setSSLSocketFactory(context.getSocketFactory());
+ *   InputStream in = urlConnection.getInputStream();
+ * }</pre>
+ *
+ * <p>It is possible to implement {@code X509TrustManager} directly
+ * instead of using one created by a {@code
+ * TrustManagerFactory}. While this is straightforward in the insecure
+ * case of allowing all certificate chains to pass verification,
+ * writing a proper implementation will usually want to take advantage
+ * of {@link java.security.cert.CertPathValidator
+ * CertPathValidator}. In general, it might be better to write a
+ * custom {@code KeyStore} implementation to pass to the {@code
+ * TrustManagerFactory} than to try and write a custom {@code
+ * X509TrustManager}.
+ *
+ * <h3>Providing an application specific X509KeyManager</h3>
+ *
+ * A custom {@code X509KeyManager} can be used to supply a client
+ * certificate and its associated private key to authenticate a
+ * connection to the server. The {@code X509KeyManager} can be created
+ * based on a {@code KeyStore} using a {@code KeyManagerFactory}.
+ *
+ * <p>For example, to supply client certificates from a {@code KeyStore}:
+ * <pre>   {@code
+ *   KeyStore keyStore = ...;
+ *   KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
+ *   kmf.init(keyStore);
+ *
+ *   SSLContext context = SSLContext.getInstance("TLS");
+ *   context.init(kmf.getKeyManagers(), null, null);
+ *
+ *   URL url = new URL("https://www.example.com/");
+ *   HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
+ *   urlConnection.setSSLSocketFactory(context.getSocketFactory());
+ *   InputStream in = urlConnection.getInputStream();
+ * }</pre>
+ *
+ * <p>A {@code X509KeyManager} can also be implemented directly. This
+ * can allow an application to return a certificate and private key
+ * from a non-{@code KeyStore} source or to specify its own logic for
+ * selecting a specific credential to use when many may be present in
+ * a single {@code KeyStore}.
+ *
+ * <h3>TLS Intolerance Support</h3>
+ *
+ * This class attempts to create secure connections using common TLS
+ * extensions and SSL deflate compression. Should that fail, the
+ * connection will be retried with SSLv3 only.
+ */
+public abstract class OkHttpsConnection extends OkHttpConnection {
+
+    private static HostnameVerifier defaultHostnameVerifier
+            = HttpsURLConnection.getDefaultHostnameVerifier();
+
+    private static SSLSocketFactory defaultSSLSocketFactory = (SSLSocketFactory) SSLSocketFactory
+            .getDefault();
+
+    /**
+     * Sets the default hostname verifier to be used by new instances.
+     *
+     * @param v
+     *            the new default hostname verifier
+     * @throws IllegalArgumentException
+     *             if the specified verifier is {@code null}.
+     */
+    public static void setDefaultHostnameVerifier(HostnameVerifier v) {
+        if (v == null) {
+            throw new IllegalArgumentException("HostnameVerifier is null");
+        }
+        defaultHostnameVerifier = v;
+    }
+
+    /**
+     * Returns the default hostname verifier.
+     *
+     * @return the default hostname verifier.
+     */
+    public static HostnameVerifier getDefaultHostnameVerifier() {
+        return defaultHostnameVerifier;
+    }
+
+    /**
+     * Sets the default SSL socket factory to be used by new instances.
+     *
+     * @param sf
+     *            the new default SSL socket factory.
+     * @throws IllegalArgumentException
+     *             if the specified socket factory is {@code null}.
+     */
+    public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) {
+        if (sf == null) {
+            throw new IllegalArgumentException("SSLSocketFactory is null");
+        }
+        defaultSSLSocketFactory = sf;
+    }
+
+    /**
+     * Returns the default SSL socket factory for new instances.
+     *
+     * @return the default SSL socket factory for new instances.
+     */
+    public static SSLSocketFactory getDefaultSSLSocketFactory() {
+        return defaultSSLSocketFactory;
+    }
+
+    /**
+     * The host name verifier used by this connection. It is initialized from
+     * the default hostname verifier
+     * {@link #setDefaultHostnameVerifier(javax.net.ssl.HostnameVerifier)} or
+     * {@link #getDefaultHostnameVerifier()}.
+     */
+    protected HostnameVerifier hostnameVerifier;
+
+    private SSLSocketFactory sslSocketFactory;
+
+    /**
+     * Creates a new {@code HttpsURLConnection} with the specified {@code URL}.
+     *
+     * @param url
+     *            the {@code URL} to connect to.
+     */
+    protected OkHttpsConnection(URL url) {
+        super(url);
+        hostnameVerifier = defaultHostnameVerifier;
+        sslSocketFactory = defaultSSLSocketFactory;
+    }
+
+    /**
+     * Returns the name of the cipher suite negotiated during the SSL handshake.
+     *
+     * @return the name of the cipher suite negotiated during the SSL handshake.
+     * @throws IllegalStateException
+     *             if no connection has been established yet.
+     */
+    public abstract String getCipherSuite();
+
+    /**
+     * Returns the list of local certificates used during the handshake. These
+     * certificates were sent to the peer.
+     *
+     * @return Returns the list of certificates used during the handshake with
+     *         the local identity certificate followed by CAs, or {@code null}
+     *         if no certificates were used during the handshake.
+     * @throws IllegalStateException
+     *             if no connection has been established yet.
+     */
+    public abstract Certificate[] getLocalCertificates();
+
+    /**
+     * Return the list of certificates identifying the peer during the
+     * handshake.
+     *
+     * @return the list of certificates identifying the peer with the peer's
+     *         identity certificate followed by CAs.
+     * @throws javax.net.ssl.SSLPeerUnverifiedException
+     *             if the identity of the peer has not been verified..
+     * @throws IllegalStateException
+     *             if no connection has been established yet.
+     */
+    public abstract Certificate[] getServerCertificates() throws SSLPeerUnverifiedException;
+
+    /**
+     * Returns the {@code Principal} identifying the peer.
+     *
+     * @return the {@code Principal} identifying the peer.
+     * @throws javax.net.ssl.SSLPeerUnverifiedException
+     *             if the identity of the peer has not been verified.
+     * @throws IllegalStateException
+     *             if no connection has been established yet.
+     */
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        Certificate[] certs = getServerCertificates();
+        if (certs == null || certs.length == 0 || (!(certs[0] instanceof X509Certificate))) {
+            throw new SSLPeerUnverifiedException("No server's end-entity certificate");
+        }
+        return ((X509Certificate) certs[0]).getSubjectX500Principal();
+    }
+
+    /**
+     * Returns the {@code Principal} used to identify the local host during the handshake.
+     *
+     * @return the {@code Principal} used to identify the local host during the handshake, or
+     *         {@code null} if none was used.
+     * @throws IllegalStateException
+     *             if no connection has been established yet.
+     */
+    public Principal getLocalPrincipal() {
+        Certificate[] certs = getLocalCertificates();
+        if (certs == null || certs.length == 0 || (!(certs[0] instanceof X509Certificate))) {
+            return null;
+        }
+        return ((X509Certificate) certs[0]).getSubjectX500Principal();
+    }
+
+    /**
+     * Sets the hostname verifier for this instance.
+     *
+     * @param v
+     *            the hostname verifier for this instance.
+     * @throws IllegalArgumentException
+     *             if the specified verifier is {@code null}.
+     */
+    public void setHostnameVerifier(HostnameVerifier v) {
+        if (v == null) {
+            throw new IllegalArgumentException("HostnameVerifier is null");
+        }
+        hostnameVerifier = v;
+    }
+
+    /**
+     * Returns the hostname verifier used by this instance.
+     *
+     * @return the hostname verifier used by this instance.
+     */
+    public HostnameVerifier getHostnameVerifier() {
+        return hostnameVerifier;
+    }
+
+    /**
+     * Sets the SSL socket factory for this instance.
+     *
+     * @param sf
+     *            the SSL socket factory to be used by this instance.
+     * @throws IllegalArgumentException
+     *             if the specified socket factory is {@code null}.
+     */
+    public void setSSLSocketFactory(SSLSocketFactory sf) {
+        if (sf == null) {
+            throw new IllegalArgumentException("SSLSocketFactory is null");
+        }
+        sslSocketFactory = sf;
+    }
+
+    /**
+     * Returns the SSL socket factory used by this instance.
+     *
+     * @return the SSL socket factory used by this instance.
+     */
+    public SSLSocketFactory getSSLSocketFactory() {
+        return sslSocketFactory;
+    }
+
+}
diff --git a/src/main/java/libcore/io/AsynchronousCloseMonitor.java b/src/main/java/libcore/io/AsynchronousCloseMonitor.java
new file mode 100644
index 0000000..62eec24
--- /dev/null
+++ b/src/main/java/libcore/io/AsynchronousCloseMonitor.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import java.io.FileDescriptor;
+
+public final class AsynchronousCloseMonitor {
+    private AsynchronousCloseMonitor() {
+    }
+
+    public static native void signalBlockedThreads(FileDescriptor fd);
+}
diff --git a/src/main/java/libcore/io/Base64.java b/src/main/java/libcore/io/Base64.java
new file mode 100644
index 0000000..96d3b9d
--- /dev/null
+++ b/src/main/java/libcore/io/Base64.java
@@ -0,0 +1,165 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+* @author Alexander Y. Kleymenov
+*/
+
+package libcore.io;
+
+import java.io.UnsupportedEncodingException;
+import libcore.util.EmptyArray;
+
+/**
+ * <a href="http://www.ietf.org/rfc/rfc2045.txt">Base64</a> encoder/decoder.
+ * In violation of the RFC, this encoder doesn't wrap lines at 76 columns.
+ */
+public final class Base64 {
+    private Base64() {
+    }
+
+    public static byte[] decode(byte[] in) {
+        return decode(in, in.length);
+    }
+
+    public static byte[] decode(byte[] in, int len) {
+        // approximate output length
+        int length = len / 4 * 3;
+        // return an empty array on empty or short input without padding
+        if (length == 0) {
+            return EmptyArray.BYTE;
+        }
+        // temporary array
+        byte[] out = new byte[length];
+        // number of padding characters ('=')
+        int pad = 0;
+        byte chr;
+        // compute the number of the padding characters
+        // and adjust the length of the input
+        for (;; len--) {
+            chr = in[len - 1];
+            // skip the neutral characters
+            if ((chr == '\n') || (chr == '\r')
+                    || (chr == ' ') || (chr == '\t')) {
+                continue;
+            }
+            if (chr == '=') {
+                pad++;
+            } else {
+                break;
+            }
+        }
+        // index in the output array
+        int outIndex = 0;
+        // index in the input array
+        int inIndex = 0;
+        // holds the value of the input character
+        int bits = 0;
+        // holds the value of the input quantum
+        int quantum = 0;
+        for (int i = 0; i < len; i++) {
+            chr = in[i];
+            // skip the neutral characters
+            if ((chr == '\n') || (chr == '\r')
+                    || (chr == ' ') || (chr == '\t')) {
+                continue;
+            }
+            if ((chr >= 'A') && (chr <= 'Z')) {
+                // char ASCII value
+                //  A    65    0
+                //  Z    90    25 (ASCII - 65)
+                bits = chr - 65;
+            } else if ((chr >= 'a') && (chr <= 'z')) {
+                // char ASCII value
+                //  a    97    26
+                //  z    122   51 (ASCII - 71)
+                bits = chr - 71;
+            } else if ((chr >= '0') && (chr <= '9')) {
+                // char ASCII value
+                //  0    48    52
+                //  9    57    61 (ASCII + 4)
+                bits = chr + 4;
+            } else if (chr == '+') {
+                bits = 62;
+            } else if (chr == '/') {
+                bits = 63;
+            } else {
+                return null;
+            }
+            // append the value to the quantum
+            quantum = (quantum << 6) | (byte) bits;
+            if (inIndex % 4 == 3) {
+                // 4 characters were read, so make the output:
+                out[outIndex++] = (byte) (quantum >> 16);
+                out[outIndex++] = (byte) (quantum >> 8);
+                out[outIndex++] = (byte) quantum;
+            }
+            inIndex++;
+        }
+        if (pad > 0) {
+            // adjust the quantum value according to the padding
+            quantum = quantum << (6 * pad);
+            // make output
+            out[outIndex++] = (byte) (quantum >> 16);
+            if (pad == 1) {
+                out[outIndex++] = (byte) (quantum >> 8);
+            }
+        }
+        // create the resulting array
+        byte[] result = new byte[outIndex];
+        System.arraycopy(out, 0, result, 0, outIndex);
+        return result;
+    }
+
+    private static final byte[] MAP = new byte[]
+        {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
+         'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b',
+         'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
+         'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+         '4', '5', '6', '7', '8', '9', '+', '/'};
+
+    public static String encode(byte[] in) {
+        int length = (in.length + 2) * 4 / 3;
+        byte[] out = new byte[length];
+        int index = 0, end = in.length - in.length % 3;
+        for (int i = 0; i < end; i += 3) {
+            out[index++] = MAP[(in[i] & 0xff) >> 2];
+            out[index++] = MAP[((in[i] & 0x03) << 4) | ((in[i + 1] & 0xff) >> 4)];
+            out[index++] = MAP[((in[i + 1] & 0x0f) << 2) | ((in[i + 2] & 0xff) >> 6)];
+            out[index++] = MAP[(in[i + 2] & 0x3f)];
+        }
+        switch (in.length % 3) {
+            case 1:
+                out[index++] = MAP[(in[end] & 0xff) >> 2];
+                out[index++] = MAP[(in[end] & 0x03) << 4];
+                out[index++] = '=';
+                out[index++] = '=';
+                break;
+            case 2:
+                out[index++] = MAP[(in[end] & 0xff) >> 2];
+                out[index++] = MAP[((in[end] & 0x03) << 4) | ((in[end + 1] & 0xff) >> 4)];
+                out[index++] = MAP[((in[end + 1] & 0x0f) << 2)];
+                out[index++] = '=';
+                break;
+        }
+        try {
+            return new String(out, 0, index, "US-ASCII");
+        } catch (UnsupportedEncodingException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
diff --git a/src/main/java/libcore/io/BufferIterator.java b/src/main/java/libcore/io/BufferIterator.java
new file mode 100644
index 0000000..7f3ad47
--- /dev/null
+++ b/src/main/java/libcore/io/BufferIterator.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+/**
+ * Iterates over big- or little-endian bytes. See {@link MemoryMappedFile#bigEndianIterator} and
+ * {@link MemoryMappedFile#littleEndianIterator}.
+ *
+ * @hide don't make this public without adding bounds checking.
+ */
+public abstract class BufferIterator {
+    /**
+     * Seeks to the absolute position {@code offset}, measured in bytes from the start.
+     */
+    public abstract void seek(int offset);
+
+    /**
+     * Skips forwards or backwards {@code byteCount} bytes from the current position.
+     */
+    public abstract void skip(int byteCount);
+
+    /**
+     * Copies {@code byteCount} bytes from the current position into {@code dst}, starting at
+     * {@code dstOffset}, and advances the current position {@code byteCount} bytes.
+     */
+    public abstract void readByteArray(byte[] dst, int dstOffset, int byteCount);
+
+    /**
+     * Returns the byte at the current position, and advances the current position one byte.
+     */
+    public abstract byte readByte();
+
+    /**
+     * Returns the 32-bit int at the current position, and advances the current position four bytes.
+     */
+    public abstract int readInt();
+
+    /**
+     * Copies {@code intCount} 32-bit ints from the current position into {@code dst}, starting at
+     * {@code dstOffset}, and advances the current position {@code 4 * intCount} bytes.
+     */
+    public abstract void readIntArray(int[] dst, int dstOffset, int intCount);
+
+    /**
+     * Returns the 16-bit short at the current position, and advances the current position two bytes.
+     */
+    public abstract short readShort();
+}
diff --git a/src/main/java/libcore/io/DiskLruCache.java b/src/main/java/libcore/io/DiskLruCache.java
new file mode 100644
index 0000000..6911834
--- /dev/null
+++ b/src/main/java/libcore/io/DiskLruCache.java
@@ -0,0 +1,834 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.Closeable;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import libcore.util.Charsets;
+import libcore.util.Libcore;
+
+/**
+ * A cache that uses a bounded amount of space on a filesystem. Each cache
+ * entry has a string key and a fixed number of values. Values are byte
+ * sequences, accessible as streams or files. Each value must be between {@code
+ * 0} and {@code Integer.MAX_VALUE} bytes in length.
+ *
+ * <p>The cache stores its data in a directory on the filesystem. This
+ * directory must be exclusive to the cache; the cache may delete or overwrite
+ * files from its directory. It is an error for multiple processes to use the
+ * same cache directory at the same time.
+ *
+ * <p>This cache limits the number of bytes that it will store on the
+ * filesystem. When the number of stored bytes exceeds the limit, the cache will
+ * remove entries in the background until the limit is satisfied. The limit is
+ * not strict: the cache may temporarily exceed it while waiting for files to be
+ * deleted. The limit does not include filesystem overhead or the cache
+ * journal so space-sensitive applications should set a conservative limit.
+ *
+ * <p>Clients call {@link #edit} to create or update the values of an entry. An
+ * entry may have only one editor at one time; if a value is not available to be
+ * edited then {@link #edit} will return null.
+ * <ul>
+ *     <li>When an entry is being <strong>created</strong> it is necessary to
+ *         supply a full set of values; the empty value should be used as a
+ *         placeholder if necessary.
+ *     <li>When an entry is being <strong>edited</strong>, it is not necessary
+ *         to supply data for every value; values default to their previous
+ *         value.
+ * </ul>
+ * Every {@link #edit} call must be matched by a call to {@link Editor#commit}
+ * or {@link Editor#abort}. Committing is atomic: a read observes the full set
+ * of values as they were before or after the commit, but never a mix of values.
+ *
+ * <p>Clients call {@link #get} to read a snapshot of an entry. The read will
+ * observe the value at the time that {@link #get} was called. Updates and
+ * removals after the call do not impact ongoing reads.
+ *
+ * <p>This class is tolerant of some I/O errors. If files are missing from the
+ * filesystem, the corresponding entries will be dropped from the cache. If
+ * an error occurs while writing a cache value, the edit will fail silently.
+ * Callers should handle other problems by catching {@code IOException} and
+ * responding appropriately.
+ */
+public final class DiskLruCache implements Closeable {
+    static final String JOURNAL_FILE = "journal";
+    static final String JOURNAL_FILE_TMP = "journal.tmp";
+    static final String MAGIC = "libcore.io.DiskLruCache";
+    static final String VERSION_1 = "1";
+    static final long ANY_SEQUENCE_NUMBER = -1;
+    private static final String CLEAN = "CLEAN";
+    private static final String DIRTY = "DIRTY";
+    private static final String REMOVE = "REMOVE";
+    private static final String READ = "READ";
+
+    /*
+     * This cache uses a journal file named "journal". A typical journal file
+     * looks like this:
+     *     libcore.io.DiskLruCache
+     *     1
+     *     100
+     *     2
+     *
+     *     CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054
+     *     DIRTY 335c4c6028171cfddfbaae1a9c313c52
+     *     CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342
+     *     REMOVE 335c4c6028171cfddfbaae1a9c313c52
+     *     DIRTY 1ab96a171faeeee38496d8b330771a7a
+     *     CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234
+     *     READ 335c4c6028171cfddfbaae1a9c313c52
+     *     READ 3400330d1dfc7f3f7f4b8d4d803dfcf6
+     *
+     * The first five lines of the journal form its header. They are the
+     * constant string "libcore.io.DiskLruCache", the disk cache's version,
+     * the application's version, the value count, and a blank line.
+     *
+     * Each of the subsequent lines in the file is a record of the state of a
+     * cache entry. Each line contains space-separated values: a state, a key,
+     * and optional state-specific values.
+     *   o DIRTY lines track that an entry is actively being created or updated.
+     *     Every successful DIRTY action should be followed by a CLEAN or REMOVE
+     *     action. DIRTY lines without a matching CLEAN or REMOVE indicate that
+     *     temporary files may need to be deleted.
+     *   o CLEAN lines track a cache entry that has been successfully published
+     *     and may be read. A publish line is followed by the lengths of each of
+     *     its values.
+     *   o READ lines track accesses for LRU.
+     *   o REMOVE lines track entries that have been deleted.
+     *
+     * The journal file is appended to as cache operations occur. The journal may
+     * occasionally be compacted by dropping redundant lines. A temporary file named
+     * "journal.tmp" will be used during compaction; that file should be deleted if
+     * it exists when the cache is opened.
+     */
+
+    private final File directory;
+    private final File journalFile;
+    private final File journalFileTmp;
+    private final int appVersion;
+    private final long maxSize;
+    private final int valueCount;
+    private long size = 0;
+    private Writer journalWriter;
+    private final LinkedHashMap<String, Entry> lruEntries
+            = new LinkedHashMap<String, Entry>(0, 0.75f, true);
+    private int redundantOpCount;
+
+    /**
+     * To differentiate between old and current snapshots, each entry is given
+     * a sequence number each time an edit is committed. A snapshot is stale if
+     * its sequence number is not equal to its entry's sequence number.
+     */
+    private long nextSequenceNumber = 0;
+
+    /** This cache uses a single background thread to evict entries. */
+    private final ExecutorService executorService = new ThreadPoolExecutor(0, 1,
+            60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
+    private final Callable<Void> cleanupCallable = new Callable<Void>() {
+        @Override public Void call() throws Exception {
+            synchronized (DiskLruCache.this) {
+                if (journalWriter == null) {
+                    return null; // closed
+                }
+                trimToSize();
+                if (journalRebuildRequired()) {
+                    rebuildJournal();
+                    redundantOpCount = 0;
+                }
+            }
+            return null;
+        }
+    };
+
+    private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) {
+        this.directory = directory;
+        this.appVersion = appVersion;
+        this.journalFile = new File(directory, JOURNAL_FILE);
+        this.journalFileTmp = new File(directory, JOURNAL_FILE_TMP);
+        this.valueCount = valueCount;
+        this.maxSize = maxSize;
+    }
+
+    /**
+     * Opens the cache in {@code directory}, creating a cache if none exists
+     * there.
+     *
+     * @param directory a writable directory
+     * @param appVersion
+     * @param valueCount the number of values per cache entry. Must be positive.
+     * @param maxSize the maximum number of bytes this cache should use to store
+     * @throws IOException if reading or writing the cache directory fails
+     */
+    public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize)
+            throws IOException {
+        if (maxSize <= 0) {
+            throw new IllegalArgumentException("maxSize <= 0");
+        }
+        if (valueCount <= 0) {
+            throw new IllegalArgumentException("valueCount <= 0");
+        }
+
+        // prefer to pick up where we left off
+        DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
+        if (cache.journalFile.exists()) {
+            try {
+                cache.readJournal();
+                cache.processJournal();
+                cache.journalWriter = new BufferedWriter(new FileWriter(cache.journalFile, true));
+                return cache;
+            } catch (IOException journalIsCorrupt) {
+                Libcore.logW("DiskLruCache " + directory + " is corrupt: "
+                        + journalIsCorrupt.getMessage() + ", removing");
+                cache.delete();
+            }
+        }
+
+        // create a new empty cache
+        directory.mkdirs();
+        cache = new DiskLruCache(directory, appVersion, valueCount, maxSize);
+        cache.rebuildJournal();
+        return cache;
+    }
+
+    private void readJournal() throws IOException {
+        InputStream in = new BufferedInputStream(new FileInputStream(journalFile));
+        try {
+            String magic = Streams.readAsciiLine(in);
+            String version = Streams.readAsciiLine(in);
+            String appVersionString = Streams.readAsciiLine(in);
+            String valueCountString = Streams.readAsciiLine(in);
+            String blank = Streams.readAsciiLine(in);
+            if (!MAGIC.equals(magic)
+                    || !VERSION_1.equals(version)
+                    || !Integer.toString(appVersion).equals(appVersionString)
+                    || !Integer.toString(valueCount).equals(valueCountString)
+                    || !"".equals(blank)) {
+                throw new IOException("unexpected journal header: ["
+                        + magic + ", " + version + ", " + valueCountString + ", " + blank + "]");
+            }
+
+            while (true) {
+                try {
+                    readJournalLine(Streams.readAsciiLine(in));
+                } catch (EOFException endOfJournal) {
+                    break;
+                }
+            }
+        } finally {
+            IoUtils.closeQuietly(in);
+        }
+    }
+
+    private void readJournalLine(String line) throws IOException {
+        String[] parts = line.split(" ");
+        if (parts.length < 2) {
+            throw new IOException("unexpected journal line: " + line);
+        }
+
+        String key = parts[1];
+        if (parts[0].equals(REMOVE) && parts.length == 2) {
+            lruEntries.remove(key);
+            return;
+        }
+
+        Entry entry = lruEntries.get(key);
+        if (entry == null) {
+            entry = new Entry(key);
+            lruEntries.put(key, entry);
+        }
+
+        if (parts[0].equals(CLEAN) && parts.length == 2 + valueCount) {
+            entry.readable = true;
+            entry.currentEditor = null;
+            entry.setLengths(Arrays.copyOfRange(parts, 2, parts.length));
+        } else if (parts[0].equals(DIRTY) && parts.length == 2) {
+            entry.currentEditor = new Editor(entry);
+        } else if (parts[0].equals(READ) && parts.length == 2) {
+            // this work was already done by calling lruEntries.get()
+        } else {
+            throw new IOException("unexpected journal line: " + line);
+        }
+    }
+
+    /**
+     * Computes the initial size and collects garbage as a part of opening the
+     * cache. Dirty entries are assumed to be inconsistent and will be deleted.
+     */
+    private void processJournal() throws IOException {
+        deleteIfExists(journalFileTmp);
+        for (Iterator<Entry> i = lruEntries.values().iterator(); i.hasNext();) {
+            Entry entry = i.next();
+            if (entry.currentEditor == null) {
+                for (int t = 0; t < valueCount; t++) {
+                    size += entry.lengths[t];
+                }
+            } else {
+                entry.currentEditor = null;
+                for (int t = 0; t < valueCount; t++) {
+                    deleteIfExists(entry.getCleanFile(t));
+                    deleteIfExists(entry.getDirtyFile(t));
+                }
+                i.remove();
+            }
+        }
+    }
+
+    /**
+     * Creates a new journal that omits redundant information. This replaces the
+     * current journal if it exists.
+     */
+    private synchronized void rebuildJournal() throws IOException {
+        if (journalWriter != null) {
+            journalWriter.close();
+        }
+
+        Writer writer = new BufferedWriter(new FileWriter(journalFileTmp));
+        writer.write(MAGIC);
+        writer.write("\n");
+        writer.write(VERSION_1);
+        writer.write("\n");
+        writer.write(Integer.toString(appVersion));
+        writer.write("\n");
+        writer.write(Integer.toString(valueCount));
+        writer.write("\n");
+        writer.write("\n");
+
+        for (Entry entry : lruEntries.values()) {
+            if (entry.currentEditor != null) {
+                writer.write(DIRTY + ' ' + entry.key + '\n');
+            } else {
+                writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
+            }
+        }
+
+        writer.close();
+        journalFileTmp.renameTo(journalFile);
+        journalWriter = new BufferedWriter(new FileWriter(journalFile, true));
+    }
+
+    private static void deleteIfExists(File file) throws IOException {
+        Libcore.deleteIfExists(file);
+    }
+
+    /**
+     * Returns a snapshot of the entry named {@code key}, or null if it doesn't
+     * exist is not currently readable. If a value is returned, it is moved to
+     * the head of the LRU queue.
+     */
+    public synchronized Snapshot get(String key) throws IOException {
+        checkNotClosed();
+        validateKey(key);
+        Entry entry = lruEntries.get(key);
+        if (entry == null) {
+            return null;
+        }
+
+        if (!entry.readable) {
+            return null;
+        }
+
+        /*
+         * Open all streams eagerly to guarantee that we see a single published
+         * snapshot. If we opened streams lazily then the streams could come
+         * from different edits.
+         */
+        InputStream[] ins = new InputStream[valueCount];
+        try {
+            for (int i = 0; i < valueCount; i++) {
+                ins[i] = new FileInputStream(entry.getCleanFile(i));
+            }
+        } catch (FileNotFoundException e) {
+            // a file must have been deleted manually!
+            return null;
+        }
+
+        redundantOpCount++;
+        journalWriter.append(READ + ' ' + key + '\n');
+        if (journalRebuildRequired()) {
+            executorService.submit(cleanupCallable);
+        }
+
+        return new Snapshot(key, entry.sequenceNumber, ins);
+    }
+
+    /**
+     * Returns an editor for the entry named {@code key}, or null if another
+     * edit is in progress.
+     */
+    public Editor edit(String key) throws IOException {
+        return edit(key, ANY_SEQUENCE_NUMBER);
+    }
+
+    private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException {
+        checkNotClosed();
+        validateKey(key);
+        Entry entry = lruEntries.get(key);
+        if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER
+                && (entry == null || entry.sequenceNumber != expectedSequenceNumber)) {
+            return null; // snapshot is stale
+        }
+        if (entry == null) {
+            entry = new Entry(key);
+            lruEntries.put(key, entry);
+        } else if (entry.currentEditor != null) {
+            return null; // another edit is in progress
+        }
+
+        Editor editor = new Editor(entry);
+        entry.currentEditor = editor;
+
+        // flush the journal before creating files to prevent file leaks
+        journalWriter.write(DIRTY + ' ' + key + '\n');
+        journalWriter.flush();
+        return editor;
+    }
+
+    /**
+     * Returns the directory where this cache stores its data.
+     */
+    public File getDirectory() {
+        return directory;
+    }
+
+    /**
+     * Returns the maximum number of bytes that this cache should use to store
+     * its data.
+     */
+    public long maxSize() {
+        return maxSize;
+    }
+
+    /**
+     * Returns the number of bytes currently being used to store the values in
+     * this cache. This may be greater than the max size if a background
+     * deletion is pending.
+     */
+    public synchronized long size() {
+        return size;
+    }
+
+    private synchronized void completeEdit(Editor editor, boolean success) throws IOException {
+        Entry entry = editor.entry;
+        if (entry.currentEditor != editor) {
+            throw new IllegalStateException();
+        }
+
+        // if this edit is creating the entry for the first time, every index must have a value
+        if (success && !entry.readable) {
+            for (int i = 0; i < valueCount; i++) {
+                if (!entry.getDirtyFile(i).exists()) {
+                    editor.abort();
+                    throw new IllegalStateException("edit didn't create file " + i);
+                }
+            }
+        }
+
+        for (int i = 0; i < valueCount; i++) {
+            File dirty = entry.getDirtyFile(i);
+            if (success) {
+                if (dirty.exists()) {
+                    File clean = entry.getCleanFile(i);
+                    dirty.renameTo(clean);
+                    long oldLength = entry.lengths[i];
+                    long newLength = clean.length();
+                    entry.lengths[i] = newLength;
+                    size = size - oldLength + newLength;
+                }
+            } else {
+                deleteIfExists(dirty);
+            }
+        }
+
+        redundantOpCount++;
+        entry.currentEditor = null;
+        if (entry.readable | success) {
+            entry.readable = true;
+            journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n');
+            if (success) {
+                entry.sequenceNumber = nextSequenceNumber++;
+            }
+        } else {
+            lruEntries.remove(entry.key);
+            journalWriter.write(REMOVE + ' ' + entry.key + '\n');
+        }
+
+        if (size > maxSize || journalRebuildRequired()) {
+            executorService.submit(cleanupCallable);
+        }
+    }
+
+    /**
+     * We only rebuild the journal when it will halve the size of the journal
+     * and eliminate at least 2000 ops.
+     */
+    private boolean journalRebuildRequired() {
+        final int redundantOpCompactThreshold = 2000;
+        return redundantOpCount >= redundantOpCompactThreshold
+                && redundantOpCount >= lruEntries.size();
+    }
+
+    /**
+     * Drops the entry for {@code key} if it exists and can be removed. Entries
+     * actively being edited cannot be removed.
+     *
+     * @return true if an entry was removed.
+     */
+    public synchronized boolean remove(String key) throws IOException {
+        checkNotClosed();
+        validateKey(key);
+        Entry entry = lruEntries.get(key);
+        if (entry == null || entry.currentEditor != null) {
+            return false;
+        }
+
+        for (int i = 0; i < valueCount; i++) {
+            File file = entry.getCleanFile(i);
+            if (!file.delete()) {
+                throw new IOException("failed to delete " + file);
+            }
+            size -= entry.lengths[i];
+            entry.lengths[i] = 0;
+        }
+
+        redundantOpCount++;
+        journalWriter.append(REMOVE + ' ' + key + '\n');
+        lruEntries.remove(key);
+
+        if (journalRebuildRequired()) {
+            executorService.submit(cleanupCallable);
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if this cache has been closed.
+     */
+    public boolean isClosed() {
+        return journalWriter == null;
+    }
+
+    private void checkNotClosed() {
+        if (journalWriter == null) {
+            throw new IllegalStateException("cache is closed");
+        }
+    }
+
+    /**
+     * Force buffered operations to the filesystem.
+     */
+    public synchronized void flush() throws IOException {
+        checkNotClosed();
+        trimToSize();
+        journalWriter.flush();
+    }
+
+    /**
+     * Closes this cache. Stored values will remain on the filesystem.
+     */
+    public synchronized void close() throws IOException {
+        if (journalWriter == null) {
+            return; // already closed
+        }
+        for (Entry entry : new ArrayList<Entry>(lruEntries.values())) {
+            if (entry.currentEditor != null) {
+                entry.currentEditor.abort();
+            }
+        }
+        trimToSize();
+        journalWriter.close();
+        journalWriter = null;
+    }
+
+    private void trimToSize() throws IOException {
+        while (size > maxSize) {
+            Map.Entry<String, Entry> toEvict = lruEntries.entrySet().iterator().next();
+            remove(toEvict.getKey());
+        }
+    }
+
+    /**
+     * Closes the cache and deletes all of its stored values. This will delete
+     * all files in the cache directory including files that weren't created by
+     * the cache.
+     */
+    public void delete() throws IOException {
+        close();
+        IoUtils.deleteContents(directory);
+    }
+
+    private void validateKey(String key) {
+        if (key.contains(" ") || key.contains("\n") || key.contains("\r")) {
+            throw new IllegalArgumentException(
+                    "keys must not contain spaces or newlines: \"" + key + "\"");
+        }
+    }
+
+    private static String inputStreamToString(InputStream in) throws IOException {
+        return Streams.readFully(new InputStreamReader(in, Charsets.UTF_8));
+    }
+
+    /**
+     * A snapshot of the values for an entry.
+     */
+    public final class Snapshot implements Closeable {
+        private final String key;
+        private final long sequenceNumber;
+        private final InputStream[] ins;
+
+        private Snapshot(String key, long sequenceNumber, InputStream[] ins) {
+            this.key = key;
+            this.sequenceNumber = sequenceNumber;
+            this.ins = ins;
+        }
+
+        /**
+         * Returns an editor for this snapshot's entry, or null if either the
+         * entry has changed since this snapshot was created or if another edit
+         * is in progress.
+         */
+        public Editor edit() throws IOException {
+            return DiskLruCache.this.edit(key, sequenceNumber);
+        }
+
+        /**
+         * Returns the unbuffered stream with the value for {@code index}.
+         */
+        public InputStream getInputStream(int index) {
+            return ins[index];
+        }
+
+        /**
+         * Returns the string value for {@code index}.
+         */
+        public String getString(int index) throws IOException {
+            return inputStreamToString(getInputStream(index));
+        }
+
+        @Override public void close() {
+            for (InputStream in : ins) {
+                IoUtils.closeQuietly(in);
+            }
+        }
+    }
+
+    /**
+     * Edits the values for an entry.
+     */
+    public final class Editor {
+        private final Entry entry;
+        private boolean hasErrors;
+
+        private Editor(Entry entry) {
+            this.entry = entry;
+        }
+
+        /**
+         * Returns an unbuffered input stream to read the last committed value,
+         * or null if no value has been committed.
+         */
+        public InputStream newInputStream(int index) throws IOException {
+            synchronized (DiskLruCache.this) {
+                if (entry.currentEditor != this) {
+                    throw new IllegalStateException();
+                }
+                if (!entry.readable) {
+                    return null;
+                }
+                return new FileInputStream(entry.getCleanFile(index));
+            }
+        }
+
+        /**
+         * Returns the last committed value as a string, or null if no value
+         * has been committed.
+         */
+        public String getString(int index) throws IOException {
+            InputStream in = newInputStream(index);
+            return in != null ? inputStreamToString(in) : null;
+        }
+
+        /**
+         * Returns a new unbuffered output stream to write the value at
+         * {@code index}. If the underlying output stream encounters errors
+         * when writing to the filesystem, this edit will be aborted when
+         * {@link #commit} is called. The returned output stream does not throw
+         * IOExceptions.
+         */
+        public OutputStream newOutputStream(int index) throws IOException {
+            synchronized (DiskLruCache.this) {
+                if (entry.currentEditor != this) {
+                    throw new IllegalStateException();
+                }
+                return new FaultHidingOutputStream(new FileOutputStream(entry.getDirtyFile(index)));
+            }
+        }
+
+        /**
+         * Sets the value at {@code index} to {@code value}.
+         */
+        public void set(int index, String value) throws IOException {
+            Writer writer = null;
+            try {
+                writer = new OutputStreamWriter(newOutputStream(index), Charsets.UTF_8);
+                writer.write(value);
+            } finally {
+                IoUtils.closeQuietly(writer);
+            }
+        }
+
+        /**
+         * Commits this edit so it is visible to readers.  This releases the
+         * edit lock so another edit may be started on the same key.
+         */
+        public void commit() throws IOException {
+            if (hasErrors) {
+                completeEdit(this, false);
+                remove(entry.key); // the previous entry is stale
+            } else {
+                completeEdit(this, true);
+            }
+        }
+
+        /**
+         * Aborts this edit. This releases the edit lock so another edit may be
+         * started on the same key.
+         */
+        public void abort() throws IOException {
+            completeEdit(this, false);
+        }
+
+        private final class FaultHidingOutputStream extends FilterOutputStream {
+            private FaultHidingOutputStream(OutputStream out) {
+                super(out);
+            }
+
+            @Override public void write(int oneByte) {
+                try {
+                    out.write(oneByte);
+                } catch (IOException e) {
+                    hasErrors = true;
+                }
+            }
+
+            @Override public void write(byte[] buffer, int offset, int length) {
+                try {
+                    out.write(buffer, offset, length);
+                } catch (IOException e) {
+                    hasErrors = true;
+                }
+            }
+
+            @Override public void close() {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    hasErrors = true;
+                }
+            }
+
+            @Override public void flush() {
+                try {
+                    out.flush();
+                } catch (IOException e) {
+                    hasErrors = true;
+                }
+            }
+        }
+    }
+
+    private final class Entry {
+        private final String key;
+
+        /** Lengths of this entry's files. */
+        private final long[] lengths;
+
+        /** True if this entry has ever been published. */
+        private boolean readable;
+
+        /** The ongoing edit or null if this entry is not being edited. */
+        private Editor currentEditor;
+
+        /** The sequence number of the most recently committed edit to this entry. */
+        private long sequenceNumber;
+
+        private Entry(String key) {
+            this.key = key;
+            this.lengths = new long[valueCount];
+        }
+
+        public String getLengths() throws IOException {
+            StringBuilder result = new StringBuilder();
+            for (long size : lengths) {
+                result.append(' ').append(size);
+            }
+            return result.toString();
+        }
+
+        /**
+         * Set lengths using decimal numbers like "10123".
+         */
+        private void setLengths(String[] strings) throws IOException {
+            if (strings.length != valueCount) {
+                throw invalidLengths(strings);
+            }
+
+            try {
+                for (int i = 0; i < strings.length; i++) {
+                    lengths[i] = Long.parseLong(strings[i]);
+                }
+            } catch (NumberFormatException e) {
+                throw invalidLengths(strings);
+            }
+        }
+
+        private IOException invalidLengths(String[] strings) throws IOException {
+            throw new IOException("unexpected journal line: " + Arrays.toString(strings));
+        }
+
+        public File getCleanFile(int i) {
+            return new File(directory, key + "." + i);
+        }
+
+        public File getDirtyFile(int i) {
+            return new File(directory, key + "." + i + ".tmp");
+        }
+    }
+}
diff --git a/src/main/java/libcore/io/IoUtils.java b/src/main/java/libcore/io/IoUtils.java
new file mode 100644
index 0000000..307737d
--- /dev/null
+++ b/src/main/java/libcore/io/IoUtils.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import java.io.Closeable;
+import java.io.File;
+import java.io.IOException;
+import java.net.Socket;
+
+public final class IoUtils {
+    private IoUtils() {
+    }
+
+    /**
+     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
+     */
+    public static void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    /**
+     * Closes 'socket', ignoring any exceptions. Does nothing if 'socket' is null.
+     */
+    public static void closeQuietly(Socket socket) {
+        if (socket != null) {
+            try {
+                socket.close();
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    /**
+     * Recursively delete everything in {@code dir}.
+     */
+    // TODO: this should specify paths as Strings rather than as Files
+    public static void deleteContents(File dir) throws IOException {
+        File[] files = dir.listFiles();
+        if (files == null) {
+            throw new IllegalArgumentException("not a directory: " + dir);
+        }
+        for (File file : files) {
+            if (file.isDirectory()) {
+                deleteContents(file);
+            }
+            if (!file.delete()) {
+                throw new IOException("failed to delete file: " + file);
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/io/OsConstants.java b/src/main/java/libcore/io/OsConstants.java
new file mode 100644
index 0000000..68a165c
--- /dev/null
+++ b/src/main/java/libcore/io/OsConstants.java
@@ -0,0 +1,724 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+public final class OsConstants {
+    private OsConstants() { }
+
+    public static boolean S_ISBLK(int mode) { return (mode & S_IFMT) == S_IFBLK; }
+    public static boolean S_ISCHR(int mode) { return (mode & S_IFMT) == S_IFCHR; }
+    public static boolean S_ISDIR(int mode) { return (mode & S_IFMT) == S_IFDIR; }
+    public static boolean S_ISFIFO(int mode) { return (mode & S_IFMT) == S_IFIFO; }
+    public static boolean S_ISREG(int mode) { return (mode & S_IFMT) == S_IFREG; }
+    public static boolean S_ISLNK(int mode) { return (mode & S_IFMT) == S_IFLNK; }
+    public static boolean S_ISSOCK(int mode) { return (mode & S_IFMT) == S_IFSOCK; }
+
+    public static int WEXITSTATUS(int status) { return (status & 0xff00) >> 8; }
+    public static boolean WCOREDUMP(int status) { return (status & 0x80) != 0; }
+    public static int WTERMSIG(int status) { return status & 0x7f; }
+    public static int WSTOPSIG(int status) { return WEXITSTATUS(status); }
+    public static boolean WIFEXITED(int status) { return (WTERMSIG(status) == 0); }
+    public static boolean WIFSTOPPED(int status) { return (WTERMSIG(status) == 0x7f); }
+    public static boolean WIFSIGNALED(int status) { return (WTERMSIG(status + 1) >= 2); }
+
+    public static final int AF_INET = placeholder();
+    public static final int AF_INET6 = placeholder();
+    public static final int AF_UNIX = placeholder();
+    public static final int AF_UNSPEC = placeholder();
+    public static final int AI_ADDRCONFIG = placeholder();
+    public static final int AI_ALL = placeholder();
+    public static final int AI_CANONNAME = placeholder();
+    public static final int AI_NUMERICHOST = placeholder();
+    public static final int AI_NUMERICSERV = placeholder();
+    public static final int AI_PASSIVE = placeholder();
+    public static final int AI_V4MAPPED = placeholder();
+    public static final int E2BIG = placeholder();
+    public static final int EACCES = placeholder();
+    public static final int EADDRINUSE = placeholder();
+    public static final int EADDRNOTAVAIL = placeholder();
+    public static final int EAFNOSUPPORT = placeholder();
+    public static final int EAGAIN = placeholder();
+    public static final int EAI_AGAIN = placeholder();
+    public static final int EAI_BADFLAGS = placeholder();
+    public static final int EAI_FAIL = placeholder();
+    public static final int EAI_FAMILY = placeholder();
+    public static final int EAI_MEMORY = placeholder();
+    public static final int EAI_NODATA = placeholder();
+    public static final int EAI_NONAME = placeholder();
+    public static final int EAI_OVERFLOW = placeholder();
+    public static final int EAI_SERVICE = placeholder();
+    public static final int EAI_SOCKTYPE = placeholder();
+    public static final int EAI_SYSTEM = placeholder();
+    public static final int EALREADY = placeholder();
+    public static final int EBADF = placeholder();
+    public static final int EBADMSG = placeholder();
+    public static final int EBUSY = placeholder();
+    public static final int ECANCELED = placeholder();
+    public static final int ECHILD = placeholder();
+    public static final int ECONNABORTED = placeholder();
+    public static final int ECONNREFUSED = placeholder();
+    public static final int ECONNRESET = placeholder();
+    public static final int EDEADLK = placeholder();
+    public static final int EDESTADDRREQ = placeholder();
+    public static final int EDOM = placeholder();
+    public static final int EDQUOT = placeholder();
+    public static final int EEXIST = placeholder();
+    public static final int EFAULT = placeholder();
+    public static final int EFBIG = placeholder();
+    public static final int EHOSTUNREACH = placeholder();
+    public static final int EIDRM = placeholder();
+    public static final int EILSEQ = placeholder();
+    public static final int EINPROGRESS = placeholder();
+    public static final int EINTR = placeholder();
+    public static final int EINVAL = placeholder();
+    public static final int EIO = placeholder();
+    public static final int EISCONN = placeholder();
+    public static final int EISDIR = placeholder();
+    public static final int ELOOP = placeholder();
+    public static final int EMFILE = placeholder();
+    public static final int EMLINK = placeholder();
+    public static final int EMSGSIZE = placeholder();
+    public static final int EMULTIHOP = placeholder();
+    public static final int ENAMETOOLONG = placeholder();
+    public static final int ENETDOWN = placeholder();
+    public static final int ENETRESET = placeholder();
+    public static final int ENETUNREACH = placeholder();
+    public static final int ENFILE = placeholder();
+    public static final int ENOBUFS = placeholder();
+    public static final int ENODATA = placeholder();
+    public static final int ENODEV = placeholder();
+    public static final int ENOENT = placeholder();
+    public static final int ENOEXEC = placeholder();
+    public static final int ENOLCK = placeholder();
+    public static final int ENOLINK = placeholder();
+    public static final int ENOMEM = placeholder();
+    public static final int ENOMSG = placeholder();
+    public static final int ENOPROTOOPT = placeholder();
+    public static final int ENOSPC = placeholder();
+    public static final int ENOSR = placeholder();
+    public static final int ENOSTR = placeholder();
+    public static final int ENOSYS = placeholder();
+    public static final int ENOTCONN = placeholder();
+    public static final int ENOTDIR = placeholder();
+    public static final int ENOTEMPTY = placeholder();
+    public static final int ENOTSOCK = placeholder();
+    public static final int ENOTSUP = placeholder();
+    public static final int ENOTTY = placeholder();
+    public static final int ENXIO = placeholder();
+    public static final int EOPNOTSUPP = placeholder();
+    public static final int EOVERFLOW = placeholder();
+    public static final int EPERM = placeholder();
+    public static final int EPIPE = placeholder();
+    public static final int EPROTO = placeholder();
+    public static final int EPROTONOSUPPORT = placeholder();
+    public static final int EPROTOTYPE = placeholder();
+    public static final int ERANGE = placeholder();
+    public static final int EROFS = placeholder();
+    public static final int ESPIPE = placeholder();
+    public static final int ESRCH = placeholder();
+    public static final int ESTALE = placeholder();
+    public static final int ETIME = placeholder();
+    public static final int ETIMEDOUT = placeholder();
+    public static final int ETXTBSY = placeholder();
+    public static final int EWOULDBLOCK = placeholder();
+    public static final int EXDEV = placeholder();
+    public static final int EXIT_FAILURE = placeholder();
+    public static final int EXIT_SUCCESS = placeholder();
+    public static final int FD_CLOEXEC = placeholder();
+    public static final int FIONREAD = placeholder();
+    public static final int F_DUPFD = placeholder();
+    public static final int F_GETFD = placeholder();
+    public static final int F_GETFL = placeholder();
+    public static final int F_GETLK = placeholder();
+    public static final int F_GETLK64 = placeholder();
+    public static final int F_GETOWN = placeholder();
+    public static final int F_OK = placeholder();
+    public static final int F_RDLCK = placeholder();
+    public static final int F_SETFD = placeholder();
+    public static final int F_SETFL = placeholder();
+    public static final int F_SETLK = placeholder();
+    public static final int F_SETLK64 = placeholder();
+    public static final int F_SETLKW = placeholder();
+    public static final int F_SETLKW64 = placeholder();
+    public static final int F_SETOWN = placeholder();
+    public static final int F_UNLCK = placeholder();
+    public static final int F_WRLCK = placeholder();
+    public static final int IFF_ALLMULTI = placeholder();
+    public static final int IFF_AUTOMEDIA = placeholder();
+    public static final int IFF_BROADCAST = placeholder();
+    public static final int IFF_DEBUG = placeholder();
+    public static final int IFF_DYNAMIC = placeholder();
+    public static final int IFF_LOOPBACK = placeholder();
+    public static final int IFF_MASTER = placeholder();
+    public static final int IFF_MULTICAST = placeholder();
+    public static final int IFF_NOARP = placeholder();
+    public static final int IFF_NOTRAILERS = placeholder();
+    public static final int IFF_POINTOPOINT = placeholder();
+    public static final int IFF_PORTSEL = placeholder();
+    public static final int IFF_PROMISC = placeholder();
+    public static final int IFF_RUNNING = placeholder();
+    public static final int IFF_SLAVE = placeholder();
+    public static final int IFF_UP = placeholder();
+    public static final int IPPROTO_ICMP = placeholder();
+    public static final int IPPROTO_IP = placeholder();
+    public static final int IPPROTO_IPV6 = placeholder();
+    public static final int IPPROTO_RAW = placeholder();
+    public static final int IPPROTO_TCP = placeholder();
+    public static final int IPPROTO_UDP = placeholder();
+    public static final int IPV6_CHECKSUM = placeholder();
+    public static final int IPV6_MULTICAST_HOPS = placeholder();
+    public static final int IPV6_MULTICAST_IF = placeholder();
+    public static final int IPV6_MULTICAST_LOOP = placeholder();
+    public static final int IPV6_RECVDSTOPTS = placeholder();
+    public static final int IPV6_RECVHOPLIMIT = placeholder();
+    public static final int IPV6_RECVHOPOPTS = placeholder();
+    public static final int IPV6_RECVPKTINFO = placeholder();
+    public static final int IPV6_RECVRTHDR = placeholder();
+    public static final int IPV6_RECVTCLASS = placeholder();
+    public static final int IPV6_TCLASS = placeholder();
+    public static final int IPV6_UNICAST_HOPS = placeholder();
+    public static final int IPV6_V6ONLY = placeholder();
+    public static final int IP_MULTICAST_IF = placeholder();
+    public static final int IP_MULTICAST_LOOP = placeholder();
+    public static final int IP_MULTICAST_TTL = placeholder();
+    public static final int IP_TOS = placeholder();
+    public static final int IP_TTL = placeholder();
+    public static final int MAP_FIXED = placeholder();
+    public static final int MAP_PRIVATE = placeholder();
+    public static final int MAP_SHARED = placeholder();
+    public static final int MCAST_JOIN_GROUP = placeholder();
+    public static final int MCAST_LEAVE_GROUP = placeholder();
+    public static final int MCL_CURRENT = placeholder();
+    public static final int MCL_FUTURE = placeholder();
+    public static final int MSG_CTRUNC = placeholder();
+    public static final int MSG_DONTROUTE = placeholder();
+    public static final int MSG_EOR = placeholder();
+    public static final int MSG_OOB = placeholder();
+    public static final int MSG_PEEK = placeholder();
+    public static final int MSG_TRUNC = placeholder();
+    public static final int MSG_WAITALL = placeholder();
+    public static final int MS_ASYNC = placeholder();
+    public static final int MS_INVALIDATE = placeholder();
+    public static final int MS_SYNC = placeholder();
+    public static final int NI_DGRAM = placeholder();
+    public static final int NI_NAMEREQD = placeholder();
+    public static final int NI_NOFQDN = placeholder();
+    public static final int NI_NUMERICHOST = placeholder();
+    public static final int NI_NUMERICSERV = placeholder();
+    public static final int O_ACCMODE = placeholder();
+    public static final int O_APPEND = placeholder();
+    public static final int O_CREAT = placeholder();
+    public static final int O_EXCL = placeholder();
+    public static final int O_NOCTTY = placeholder();
+    public static final int O_NONBLOCK = placeholder();
+    public static final int O_RDONLY = placeholder();
+    public static final int O_RDWR = placeholder();
+    public static final int O_SYNC = placeholder();
+    public static final int O_TRUNC = placeholder();
+    public static final int O_WRONLY = placeholder();
+    public static final int POLLERR = placeholder();
+    public static final int POLLHUP = placeholder();
+    public static final int POLLIN = placeholder();
+    public static final int POLLNVAL = placeholder();
+    public static final int POLLOUT = placeholder();
+    public static final int POLLPRI = placeholder();
+    public static final int POLLRDBAND = placeholder();
+    public static final int POLLRDNORM = placeholder();
+    public static final int POLLWRBAND = placeholder();
+    public static final int POLLWRNORM = placeholder();
+    public static final int PROT_EXEC = placeholder();
+    public static final int PROT_NONE = placeholder();
+    public static final int PROT_READ = placeholder();
+    public static final int PROT_WRITE = placeholder();
+    public static final int R_OK = placeholder();
+    public static final int SEEK_CUR = placeholder();
+    public static final int SEEK_END = placeholder();
+    public static final int SEEK_SET = placeholder();
+    public static final int SHUT_RD = placeholder();
+    public static final int SHUT_RDWR = placeholder();
+    public static final int SHUT_WR = placeholder();
+    public static final int SIGABRT = placeholder();
+    public static final int SIGALRM = placeholder();
+    public static final int SIGBUS = placeholder();
+    public static final int SIGCHLD = placeholder();
+    public static final int SIGCONT = placeholder();
+    public static final int SIGFPE = placeholder();
+    public static final int SIGHUP = placeholder();
+    public static final int SIGILL = placeholder();
+    public static final int SIGINT = placeholder();
+    public static final int SIGIO = placeholder();
+    public static final int SIGKILL = placeholder();
+    public static final int SIGPIPE = placeholder();
+    public static final int SIGPROF = placeholder();
+    public static final int SIGPWR = placeholder();
+    public static final int SIGQUIT = placeholder();
+    public static final int SIGRTMAX = placeholder();
+    public static final int SIGRTMIN = placeholder();
+    public static final int SIGSEGV = placeholder();
+    public static final int SIGSTKFLT = placeholder();
+    public static final int SIGSTOP = placeholder();
+    public static final int SIGSYS = placeholder();
+    public static final int SIGTERM = placeholder();
+    public static final int SIGTRAP = placeholder();
+    public static final int SIGTSTP = placeholder();
+    public static final int SIGTTIN = placeholder();
+    public static final int SIGTTOU = placeholder();
+    public static final int SIGURG = placeholder();
+    public static final int SIGUSR1 = placeholder();
+    public static final int SIGUSR2 = placeholder();
+    public static final int SIGVTALRM = placeholder();
+    public static final int SIGWINCH = placeholder();
+    public static final int SIGXCPU = placeholder();
+    public static final int SIGXFSZ = placeholder();
+    public static final int SIOCGIFADDR = placeholder();
+    public static final int SIOCGIFBRDADDR = placeholder();
+    public static final int SIOCGIFDSTADDR = placeholder();
+    public static final int SIOCGIFNETMASK = placeholder();
+    public static final int SOCK_DGRAM = placeholder();
+    public static final int SOCK_RAW = placeholder();
+    public static final int SOCK_SEQPACKET = placeholder();
+    public static final int SOCK_STREAM = placeholder();
+    public static final int SOL_SOCKET = placeholder();
+    public static final int SO_BINDTODEVICE = placeholder();
+    public static final int SO_BROADCAST = placeholder();
+    public static final int SO_DEBUG = placeholder();
+    public static final int SO_DONTROUTE = placeholder();
+    public static final int SO_ERROR = placeholder();
+    public static final int SO_KEEPALIVE = placeholder();
+    public static final int SO_LINGER = placeholder();
+    public static final int SO_OOBINLINE = placeholder();
+    public static final int SO_RCVBUF = placeholder();
+    public static final int SO_RCVLOWAT = placeholder();
+    public static final int SO_RCVTIMEO = placeholder();
+    public static final int SO_REUSEADDR = placeholder();
+    public static final int SO_SNDBUF = placeholder();
+    public static final int SO_SNDLOWAT = placeholder();
+    public static final int SO_SNDTIMEO = placeholder();
+    public static final int SO_TYPE = placeholder();
+    public static final int STDERR_FILENO = placeholder();
+    public static final int STDIN_FILENO = placeholder();
+    public static final int STDOUT_FILENO = placeholder();
+    public static final int S_IFBLK = placeholder();
+    public static final int S_IFCHR = placeholder();
+    public static final int S_IFDIR = placeholder();
+    public static final int S_IFIFO = placeholder();
+    public static final int S_IFLNK = placeholder();
+    public static final int S_IFMT = placeholder();
+    public static final int S_IFREG = placeholder();
+    public static final int S_IFSOCK = placeholder();
+    public static final int S_IRGRP = placeholder();
+    public static final int S_IROTH = placeholder();
+    public static final int S_IRUSR = placeholder();
+    public static final int S_IRWXG = placeholder();
+    public static final int S_IRWXO = placeholder();
+    public static final int S_IRWXU = placeholder();
+    public static final int S_ISGID = placeholder();
+    public static final int S_ISUID = placeholder();
+    public static final int S_ISVTX = placeholder();
+    public static final int S_IWGRP = placeholder();
+    public static final int S_IWOTH = placeholder();
+    public static final int S_IWUSR = placeholder();
+    public static final int S_IXGRP = placeholder();
+    public static final int S_IXOTH = placeholder();
+    public static final int S_IXUSR = placeholder();
+    public static final int TCP_NODELAY = placeholder();
+    public static final int WCONTINUED = placeholder();
+    public static final int WEXITED = placeholder();
+    public static final int WNOHANG = placeholder();
+    public static final int WNOWAIT = placeholder();
+    public static final int WSTOPPED = placeholder();
+    public static final int WUNTRACED = placeholder();
+    public static final int W_OK = placeholder();
+    public static final int X_OK = placeholder();
+    public static final int _SC_2_CHAR_TERM = placeholder();
+    public static final int _SC_2_C_BIND = placeholder();
+    public static final int _SC_2_C_DEV = placeholder();
+    public static final int _SC_2_C_VERSION = placeholder();
+    public static final int _SC_2_FORT_DEV = placeholder();
+    public static final int _SC_2_FORT_RUN = placeholder();
+    public static final int _SC_2_LOCALEDEF = placeholder();
+    public static final int _SC_2_SW_DEV = placeholder();
+    public static final int _SC_2_UPE = placeholder();
+    public static final int _SC_2_VERSION = placeholder();
+    public static final int _SC_AIO_LISTIO_MAX = placeholder();
+    public static final int _SC_AIO_MAX = placeholder();
+    public static final int _SC_AIO_PRIO_DELTA_MAX = placeholder();
+    public static final int _SC_ARG_MAX = placeholder();
+    public static final int _SC_ASYNCHRONOUS_IO = placeholder();
+    public static final int _SC_ATEXIT_MAX = placeholder();
+    public static final int _SC_AVPHYS_PAGES = placeholder();
+    public static final int _SC_BC_BASE_MAX = placeholder();
+    public static final int _SC_BC_DIM_MAX = placeholder();
+    public static final int _SC_BC_SCALE_MAX = placeholder();
+    public static final int _SC_BC_STRING_MAX = placeholder();
+    public static final int _SC_CHILD_MAX = placeholder();
+    public static final int _SC_CLK_TCK = placeholder();
+    public static final int _SC_COLL_WEIGHTS_MAX = placeholder();
+    public static final int _SC_DELAYTIMER_MAX = placeholder();
+    public static final int _SC_EXPR_NEST_MAX = placeholder();
+    public static final int _SC_FSYNC = placeholder();
+    public static final int _SC_GETGR_R_SIZE_MAX = placeholder();
+    public static final int _SC_GETPW_R_SIZE_MAX = placeholder();
+    public static final int _SC_IOV_MAX = placeholder();
+    public static final int _SC_JOB_CONTROL = placeholder();
+    public static final int _SC_LINE_MAX = placeholder();
+    public static final int _SC_LOGIN_NAME_MAX = placeholder();
+    public static final int _SC_MAPPED_FILES = placeholder();
+    public static final int _SC_MEMLOCK = placeholder();
+    public static final int _SC_MEMLOCK_RANGE = placeholder();
+    public static final int _SC_MEMORY_PROTECTION = placeholder();
+    public static final int _SC_MESSAGE_PASSING = placeholder();
+    public static final int _SC_MQ_OPEN_MAX = placeholder();
+    public static final int _SC_MQ_PRIO_MAX = placeholder();
+    public static final int _SC_NGROUPS_MAX = placeholder();
+    public static final int _SC_NPROCESSORS_CONF = placeholder();
+    public static final int _SC_NPROCESSORS_ONLN = placeholder();
+    public static final int _SC_OPEN_MAX = placeholder();
+    public static final int _SC_PAGESIZE = placeholder();
+    public static final int _SC_PAGE_SIZE = placeholder();
+    public static final int _SC_PASS_MAX = placeholder();
+    public static final int _SC_PHYS_PAGES = placeholder();
+    public static final int _SC_PRIORITIZED_IO = placeholder();
+    public static final int _SC_PRIORITY_SCHEDULING = placeholder();
+    public static final int _SC_REALTIME_SIGNALS = placeholder();
+    public static final int _SC_RE_DUP_MAX = placeholder();
+    public static final int _SC_RTSIG_MAX = placeholder();
+    public static final int _SC_SAVED_IDS = placeholder();
+    public static final int _SC_SEMAPHORES = placeholder();
+    public static final int _SC_SEM_NSEMS_MAX = placeholder();
+    public static final int _SC_SEM_VALUE_MAX = placeholder();
+    public static final int _SC_SHARED_MEMORY_OBJECTS = placeholder();
+    public static final int _SC_SIGQUEUE_MAX = placeholder();
+    public static final int _SC_STREAM_MAX = placeholder();
+    public static final int _SC_SYNCHRONIZED_IO = placeholder();
+    public static final int _SC_THREADS = placeholder();
+    public static final int _SC_THREAD_ATTR_STACKADDR = placeholder();
+    public static final int _SC_THREAD_ATTR_STACKSIZE = placeholder();
+    public static final int _SC_THREAD_DESTRUCTOR_ITERATIONS = placeholder();
+    public static final int _SC_THREAD_KEYS_MAX = placeholder();
+    public static final int _SC_THREAD_PRIORITY_SCHEDULING = placeholder();
+    public static final int _SC_THREAD_PRIO_INHERIT = placeholder();
+    public static final int _SC_THREAD_PRIO_PROTECT = placeholder();
+    public static final int _SC_THREAD_SAFE_FUNCTIONS = placeholder();
+    public static final int _SC_THREAD_STACK_MIN = placeholder();
+    public static final int _SC_THREAD_THREADS_MAX = placeholder();
+    public static final int _SC_TIMERS = placeholder();
+    public static final int _SC_TIMER_MAX = placeholder();
+    public static final int _SC_TTY_NAME_MAX = placeholder();
+    public static final int _SC_TZNAME_MAX = placeholder();
+    public static final int _SC_VERSION = placeholder();
+    public static final int _SC_XBS5_ILP32_OFF32 = placeholder();
+    public static final int _SC_XBS5_ILP32_OFFBIG = placeholder();
+    public static final int _SC_XBS5_LP64_OFF64 = placeholder();
+    public static final int _SC_XBS5_LPBIG_OFFBIG = placeholder();
+    public static final int _SC_XOPEN_CRYPT = placeholder();
+    public static final int _SC_XOPEN_ENH_I18N = placeholder();
+    public static final int _SC_XOPEN_LEGACY = placeholder();
+    public static final int _SC_XOPEN_REALTIME = placeholder();
+    public static final int _SC_XOPEN_REALTIME_THREADS = placeholder();
+    public static final int _SC_XOPEN_SHM = placeholder();
+    public static final int _SC_XOPEN_UNIX = placeholder();
+    public static final int _SC_XOPEN_VERSION = placeholder();
+    public static final int _SC_XOPEN_XCU_VERSION = placeholder();
+
+    public static String gaiName(int error) {
+        if (error == EAI_AGAIN) {
+            return "EAI_AGAIN";
+        }
+        if (error == EAI_BADFLAGS) {
+            return "EAI_BADFLAGS";
+        }
+        if (error == EAI_FAIL) {
+            return "EAI_FAIL";
+        }
+        if (error == EAI_FAMILY) {
+            return "EAI_FAMILY";
+        }
+        if (error == EAI_MEMORY) {
+            return "EAI_MEMORY";
+        }
+        if (error == EAI_NODATA) {
+            return "EAI_NODATA";
+        }
+        if (error == EAI_NONAME) {
+            return "EAI_NONAME";
+        }
+        if (error == EAI_OVERFLOW) {
+            return "EAI_OVERFLOW";
+        }
+        if (error == EAI_SERVICE) {
+            return "EAI_SERVICE";
+        }
+        if (error == EAI_SOCKTYPE) {
+            return "EAI_SOCKTYPE";
+        }
+        if (error == EAI_SYSTEM) {
+            return "EAI_SYSTEM";
+        }
+        return null;
+    }
+
+    public static String errnoName(int errno) {
+        if (errno == E2BIG) {
+            return "E2BIG";
+        }
+        if (errno == EACCES) {
+            return "EACCES";
+        }
+        if (errno == EADDRINUSE) {
+            return "EADDRINUSE";
+        }
+        if (errno == EADDRNOTAVAIL) {
+            return "EADDRNOTAVAIL";
+        }
+        if (errno == EAFNOSUPPORT) {
+            return "EAFNOSUPPORT";
+        }
+        if (errno == EAGAIN) {
+            return "EAGAIN";
+        }
+        if (errno == EALREADY) {
+            return "EALREADY";
+        }
+        if (errno == EBADF) {
+            return "EBADF";
+        }
+        if (errno == EBADMSG) {
+            return "EBADMSG";
+        }
+        if (errno == EBUSY) {
+            return "EBUSY";
+        }
+        if (errno == ECANCELED) {
+            return "ECANCELED";
+        }
+        if (errno == ECHILD) {
+            return "ECHILD";
+        }
+        if (errno == ECONNABORTED) {
+            return "ECONNABORTED";
+        }
+        if (errno == ECONNREFUSED) {
+            return "ECONNREFUSED";
+        }
+        if (errno == ECONNRESET) {
+            return "ECONNRESET";
+        }
+        if (errno == EDEADLK) {
+            return "EDEADLK";
+        }
+        if (errno == EDESTADDRREQ) {
+            return "EDESTADDRREQ";
+        }
+        if (errno == EDOM) {
+            return "EDOM";
+        }
+        if (errno == EDQUOT) {
+            return "EDQUOT";
+        }
+        if (errno == EEXIST) {
+            return "EEXIST";
+        }
+        if (errno == EFAULT) {
+            return "EFAULT";
+        }
+        if (errno == EFBIG) {
+            return "EFBIG";
+        }
+        if (errno == EHOSTUNREACH) {
+            return "EHOSTUNREACH";
+        }
+        if (errno == EIDRM) {
+            return "EIDRM";
+        }
+        if (errno == EILSEQ) {
+            return "EILSEQ";
+        }
+        if (errno == EINPROGRESS) {
+            return "EINPROGRESS";
+        }
+        if (errno == EINTR) {
+            return "EINTR";
+        }
+        if (errno == EINVAL) {
+            return "EINVAL";
+        }
+        if (errno == EIO) {
+            return "EIO";
+        }
+        if (errno == EISCONN) {
+            return "EISCONN";
+        }
+        if (errno == EISDIR) {
+            return "EISDIR";
+        }
+        if (errno == ELOOP) {
+            return "ELOOP";
+        }
+        if (errno == EMFILE) {
+            return "EMFILE";
+        }
+        if (errno == EMLINK) {
+            return "EMLINK";
+        }
+        if (errno == EMSGSIZE) {
+            return "EMSGSIZE";
+        }
+        if (errno == EMULTIHOP) {
+            return "EMULTIHOP";
+        }
+        if (errno == ENAMETOOLONG) {
+            return "ENAMETOOLONG";
+        }
+        if (errno == ENETDOWN) {
+            return "ENETDOWN";
+        }
+        if (errno == ENETRESET) {
+            return "ENETRESET";
+        }
+        if (errno == ENETUNREACH) {
+            return "ENETUNREACH";
+        }
+        if (errno == ENFILE) {
+            return "ENFILE";
+        }
+        if (errno == ENOBUFS) {
+            return "ENOBUFS";
+        }
+        if (errno == ENODATA) {
+            return "ENODATA";
+        }
+        if (errno == ENODEV) {
+            return "ENODEV";
+        }
+        if (errno == ENOENT) {
+            return "ENOENT";
+        }
+        if (errno == ENOEXEC) {
+            return "ENOEXEC";
+        }
+        if (errno == ENOLCK) {
+            return "ENOLCK";
+        }
+        if (errno == ENOLINK) {
+            return "ENOLINK";
+        }
+        if (errno == ENOMEM) {
+            return "ENOMEM";
+        }
+        if (errno == ENOMSG) {
+            return "ENOMSG";
+        }
+        if (errno == ENOPROTOOPT) {
+            return "ENOPROTOOPT";
+        }
+        if (errno == ENOSPC) {
+            return "ENOSPC";
+        }
+        if (errno == ENOSR) {
+            return "ENOSR";
+        }
+        if (errno == ENOSTR) {
+            return "ENOSTR";
+        }
+        if (errno == ENOSYS) {
+            return "ENOSYS";
+        }
+        if (errno == ENOTCONN) {
+            return "ENOTCONN";
+        }
+        if (errno == ENOTDIR) {
+            return "ENOTDIR";
+        }
+        if (errno == ENOTEMPTY) {
+            return "ENOTEMPTY";
+        }
+        if (errno == ENOTSOCK) {
+            return "ENOTSOCK";
+        }
+        if (errno == ENOTSUP) {
+            return "ENOTSUP";
+        }
+        if (errno == ENOTTY) {
+            return "ENOTTY";
+        }
+        if (errno == ENXIO) {
+            return "ENXIO";
+        }
+        if (errno == EOPNOTSUPP) {
+            return "EOPNOTSUPP";
+        }
+        if (errno == EOVERFLOW) {
+            return "EOVERFLOW";
+        }
+        if (errno == EPERM) {
+            return "EPERM";
+        }
+        if (errno == EPIPE) {
+            return "EPIPE";
+        }
+        if (errno == EPROTO) {
+            return "EPROTO";
+        }
+        if (errno == EPROTONOSUPPORT) {
+            return "EPROTONOSUPPORT";
+        }
+        if (errno == EPROTOTYPE) {
+            return "EPROTOTYPE";
+        }
+        if (errno == ERANGE) {
+            return "ERANGE";
+        }
+        if (errno == EROFS) {
+            return "EROFS";
+        }
+        if (errno == ESPIPE) {
+            return "ESPIPE";
+        }
+        if (errno == ESRCH) {
+            return "ESRCH";
+        }
+        if (errno == ESTALE) {
+            return "ESTALE";
+        }
+        if (errno == ETIME) {
+            return "ETIME";
+        }
+        if (errno == ETIMEDOUT) {
+            return "ETIMEDOUT";
+        }
+        if (errno == ETXTBSY) {
+            return "ETXTBSY";
+        }
+        if (errno == EWOULDBLOCK) {
+            return "EWOULDBLOCK";
+        }
+        if (errno == EXDEV) {
+            return "EXDEV";
+        }
+        return null;
+    }
+
+    private static native void initConstants();
+
+    // A hack to avoid these constants being inlined by javac...
+    private static int placeholder() { return 0; }
+    // ...because we want to initialize them at runtime.
+    static {
+        initConstants();
+    }
+}
diff --git a/src/main/java/libcore/io/SizeOf.java b/src/main/java/libcore/io/SizeOf.java
new file mode 100644
index 0000000..728fbfc
--- /dev/null
+++ b/src/main/java/libcore/io/SizeOf.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+public final class SizeOf {
+    public static final int CHAR = 2;
+    public static final int DOUBLE = 8;
+    public static final int FLOAT = 4;
+    public static final int INT = 4;
+    public static final int LONG = 8;
+    public static final int SHORT = 2;
+
+    private SizeOf() {
+    }
+}
diff --git a/src/main/java/libcore/io/Streams.java b/src/main/java/libcore/io/Streams.java
new file mode 100644
index 0000000..1ad2356
--- /dev/null
+++ b/src/main/java/libcore/io/Streams.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.io;
+
+import java.io.ByteArrayOutputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.util.concurrent.atomic.AtomicReference;
+import libcore.util.Libcore;
+
+public final class Streams {
+    private static AtomicReference<byte[]> skipBuffer = new AtomicReference<byte[]>();
+
+    private Streams() {
+    }
+
+    /**
+     * Implements InputStream.read(int) in terms of InputStream.read(byte[], int, int).
+     * InputStream assumes that you implement InputStream.read(int) and provides default
+     * implementations of the others, but often the opposite is more efficient.
+     */
+    public static int readSingleByte(InputStream in) throws IOException {
+        byte[] buffer = new byte[1];
+        int result = in.read(buffer, 0, 1);
+        return (result != -1) ? buffer[0] & 0xff : -1;
+    }
+
+    /**
+     * Implements OutputStream.write(int) in terms of OutputStream.write(byte[], int, int).
+     * OutputStream assumes that you implement OutputStream.write(int) and provides default
+     * implementations of the others, but often the opposite is more efficient.
+     */
+    public static void writeSingleByte(OutputStream out, int b) throws IOException {
+        byte[] buffer = new byte[1];
+        buffer[0] = (byte) (b & 0xff);
+        out.write(buffer);
+    }
+
+    /**
+     * Fills 'dst' with bytes from 'in', throwing EOFException if insufficient bytes are available.
+     */
+    public static void readFully(InputStream in, byte[] dst) throws IOException {
+        readFully(in, dst, 0, dst.length);
+    }
+
+    /**
+     * Reads exactly 'byteCount' bytes from 'in' (into 'dst' at offset 'offset'), and throws
+     * EOFException if insufficient bytes are available.
+     *
+     * Used to implement {@link java.io.DataInputStream#readFully(byte[], int, int)}.
+     */
+    public static void readFully(InputStream in, byte[] dst, int offset, int byteCount) throws IOException {
+        if (byteCount == 0) {
+            return;
+        }
+        if (in == null) {
+            throw new NullPointerException("in == null");
+        }
+        if (dst == null) {
+            throw new NullPointerException("dst == null");
+        }
+        Libcore.checkOffsetAndCount(dst.length, offset, byteCount);
+        while (byteCount > 0) {
+            int bytesRead = in.read(dst, offset, byteCount);
+            if (bytesRead < 0) {
+                throw new EOFException();
+            }
+            offset += bytesRead;
+            byteCount -= bytesRead;
+        }
+    }
+
+    /**
+     * Returns a byte[] containing the remainder of 'in', closing it when done.
+     */
+    public static byte[] readFully(InputStream in) throws IOException {
+        try {
+            return readFullyNoClose(in);
+        } finally {
+            in.close();
+        }
+    }
+
+    /**
+     * Returns a byte[] containing the remainder of 'in'.
+     */
+    public static byte[] readFullyNoClose(InputStream in) throws IOException {
+        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+        byte[] buffer = new byte[1024];
+        int count;
+        while ((count = in.read(buffer)) != -1) {
+            bytes.write(buffer, 0, count);
+        }
+        return bytes.toByteArray();
+    }
+
+    /**
+     * Returns the remainder of 'reader' as a string, closing it when done.
+     */
+    public static String readFully(Reader reader) throws IOException {
+        try {
+            StringWriter writer = new StringWriter();
+            char[] buffer = new char[1024];
+            int count;
+            while ((count = reader.read(buffer)) != -1) {
+                writer.write(buffer, 0, count);
+            }
+            return writer.toString();
+        } finally {
+            reader.close();
+        }
+    }
+
+    public static void skipAll(InputStream in) throws IOException {
+        do {
+            in.skip(Long.MAX_VALUE);
+        } while (in.read() != -1);
+    }
+
+    /**
+     * Call {@code in.read()} repeatedly until either the stream is exhausted or
+     * {@code byteCount} bytes have been read.
+     *
+     * <p>This method reuses the skip buffer but is careful to never use it at
+     * the same time that another stream is using it. Otherwise streams that use
+     * the caller's buffer for consistency checks like CRC could be clobbered by
+     * other threads. A thread-local buffer is also insufficient because some
+     * streams may call other streams in their skip() method, also clobbering the
+     * buffer.
+     */
+    public static long skipByReading(InputStream in, long byteCount) throws IOException {
+        // acquire the shared skip buffer.
+        byte[] buffer = skipBuffer.getAndSet(null);
+        if (buffer == null) {
+            buffer = new byte[4096];
+        }
+
+        long skipped = 0;
+        while (skipped < byteCount) {
+            int toRead = (int) Math.min(byteCount - skipped, buffer.length);
+            int read = in.read(buffer, 0, toRead);
+            if (read == -1) {
+                break;
+            }
+            skipped += read;
+            if (read < toRead) {
+                break;
+            }
+        }
+
+        // release the shared skip buffer.
+        skipBuffer.set(buffer);
+
+        return skipped;
+    }
+
+    /**
+     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
+     * Returns the total number of bytes transferred.
+     */
+    public static int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
+
+    /**
+     * Returns the ASCII characters up to but not including the next "\r\n", or
+     * "\n".
+     *
+     * @throws java.io.EOFException if the stream is exhausted before the next newline
+     *     character.
+     */
+    public static String readAsciiLine(InputStream in) throws IOException {
+        // TODO: support UTF-8 here instead
+
+        StringBuilder result = new StringBuilder(80);
+        while (true) {
+            int c = in.read();
+            if (c == -1) {
+                throw new EOFException();
+            } else if (c == '\n') {
+                break;
+            }
+
+            result.append((char) c);
+        }
+        int length = result.length();
+        if (length > 0 && result.charAt(length - 1) == '\r') {
+            result.setLength(length - 1);
+        }
+        return result.toString();
+    }
+}
diff --git a/src/main/java/libcore/net/MimeUtils.java b/src/main/java/libcore/net/MimeUtils.java
new file mode 100644
index 0000000..76193ff
--- /dev/null
+++ b/src/main/java/libcore/net/MimeUtils.java
@@ -0,0 +1,480 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * Utilities for dealing with MIME types.
+ * Used to implement java.net.URLConnection and android.webkit.MimeTypeMap.
+ */
+public final class MimeUtils {
+    private static final Map<String, String> MIME_TYPE_TO_EXTENSION_MAP = new HashMap<String, String>();
+
+    private static final Map<String, String> EXTENSION_TO_MIME_TYPE_MAP = new HashMap<String, String>();
+
+    static {
+        // The following table is based on /etc/mime.types data minus
+        // chemical/* MIME types and MIME types that don't map to any
+        // file extensions. We also exclude top-level domain names to
+        // deal with cases like:
+        //
+        // mail.google.com/a/google.com
+        //
+        // and "active" MIME types (due to potential security issues).
+
+        add("application/andrew-inset", "ez");
+        add("application/dsptype", "tsp");
+        add("application/futuresplash", "spl");
+        add("application/hta", "hta");
+        add("application/mac-binhex40", "hqx");
+        add("application/mac-compactpro", "cpt");
+        add("application/mathematica", "nb");
+        add("application/msaccess", "mdb");
+        add("application/oda", "oda");
+        add("application/ogg", "ogg");
+        add("application/pdf", "pdf");
+        add("application/pgp-keys", "key");
+        add("application/pgp-signature", "pgp");
+        add("application/pics-rules", "prf");
+        add("application/rar", "rar");
+        add("application/rdf+xml", "rdf");
+        add("application/rss+xml", "rss");
+        add("application/zip", "zip");
+        add("application/vnd.android.package-archive", "apk");
+        add("application/vnd.cinderella", "cdy");
+        add("application/vnd.ms-pki.stl", "stl");
+        add("application/vnd.oasis.opendocument.database", "odb");
+        add("application/vnd.oasis.opendocument.formula", "odf");
+        add("application/vnd.oasis.opendocument.graphics", "odg");
+        add("application/vnd.oasis.opendocument.graphics-template", "otg");
+        add("application/vnd.oasis.opendocument.image", "odi");
+        add("application/vnd.oasis.opendocument.spreadsheet", "ods");
+        add("application/vnd.oasis.opendocument.spreadsheet-template", "ots");
+        add("application/vnd.oasis.opendocument.text", "odt");
+        add("application/vnd.oasis.opendocument.text-master", "odm");
+        add("application/vnd.oasis.opendocument.text-template", "ott");
+        add("application/vnd.oasis.opendocument.text-web", "oth");
+        add("application/vnd.google-earth.kml+xml", "kml");
+        add("application/vnd.google-earth.kmz", "kmz");
+        add("application/msword", "doc");
+        add("application/msword", "dot");
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.document", "docx");
+        add("application/vnd.openxmlformats-officedocument.wordprocessingml.template", "dotx");
+        add("application/vnd.ms-excel", "xls");
+        add("application/vnd.ms-excel", "xlt");
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", "xlsx");
+        add("application/vnd.openxmlformats-officedocument.spreadsheetml.template", "xltx");
+        add("application/vnd.ms-powerpoint", "ppt");
+        add("application/vnd.ms-powerpoint", "pot");
+        add("application/vnd.ms-powerpoint", "pps");
+        add("application/vnd.openxmlformats-officedocument.presentationml.presentation", "pptx");
+        add("application/vnd.openxmlformats-officedocument.presentationml.template", "potx");
+        add("application/vnd.openxmlformats-officedocument.presentationml.slideshow", "ppsx");
+        add("application/vnd.rim.cod", "cod");
+        add("application/vnd.smaf", "mmf");
+        add("application/vnd.stardivision.calc", "sdc");
+        add("application/vnd.stardivision.draw", "sda");
+        add("application/vnd.stardivision.impress", "sdd");
+        add("application/vnd.stardivision.impress", "sdp");
+        add("application/vnd.stardivision.math", "smf");
+        add("application/vnd.stardivision.writer", "sdw");
+        add("application/vnd.stardivision.writer", "vor");
+        add("application/vnd.stardivision.writer-global", "sgl");
+        add("application/vnd.sun.xml.calc", "sxc");
+        add("application/vnd.sun.xml.calc.template", "stc");
+        add("application/vnd.sun.xml.draw", "sxd");
+        add("application/vnd.sun.xml.draw.template", "std");
+        add("application/vnd.sun.xml.impress", "sxi");
+        add("application/vnd.sun.xml.impress.template", "sti");
+        add("application/vnd.sun.xml.math", "sxm");
+        add("application/vnd.sun.xml.writer", "sxw");
+        add("application/vnd.sun.xml.writer.global", "sxg");
+        add("application/vnd.sun.xml.writer.template", "stw");
+        add("application/vnd.visio", "vsd");
+        add("application/x-abiword", "abw");
+        add("application/x-apple-diskimage", "dmg");
+        add("application/x-bcpio", "bcpio");
+        add("application/x-bittorrent", "torrent");
+        add("application/x-cdf", "cdf");
+        add("application/x-cdlink", "vcd");
+        add("application/x-chess-pgn", "pgn");
+        add("application/x-cpio", "cpio");
+        add("application/x-debian-package", "deb");
+        add("application/x-debian-package", "udeb");
+        add("application/x-director", "dcr");
+        add("application/x-director", "dir");
+        add("application/x-director", "dxr");
+        add("application/x-dms", "dms");
+        add("application/x-doom", "wad");
+        add("application/x-dvi", "dvi");
+        add("application/x-flac", "flac");
+        add("application/x-font", "pfa");
+        add("application/x-font", "pfb");
+        add("application/x-font", "gsf");
+        add("application/x-font", "pcf");
+        add("application/x-font", "pcf.Z");
+        add("application/x-freemind", "mm");
+        add("application/x-futuresplash", "spl");
+        add("application/x-gnumeric", "gnumeric");
+        add("application/x-go-sgf", "sgf");
+        add("application/x-graphing-calculator", "gcf");
+        add("application/x-gtar", "gtar");
+        add("application/x-gtar", "tgz");
+        add("application/x-gtar", "taz");
+        add("application/x-hdf", "hdf");
+        add("application/x-ica", "ica");
+        add("application/x-internet-signup", "ins");
+        add("application/x-internet-signup", "isp");
+        add("application/x-iphone", "iii");
+        add("application/x-iso9660-image", "iso");
+        add("application/x-jmol", "jmz");
+        add("application/x-kchart", "chrt");
+        add("application/x-killustrator", "kil");
+        add("application/x-koan", "skp");
+        add("application/x-koan", "skd");
+        add("application/x-koan", "skt");
+        add("application/x-koan", "skm");
+        add("application/x-kpresenter", "kpr");
+        add("application/x-kpresenter", "kpt");
+        add("application/x-kspread", "ksp");
+        add("application/x-kword", "kwd");
+        add("application/x-kword", "kwt");
+        add("application/x-latex", "latex");
+        add("application/x-lha", "lha");
+        add("application/x-lzh", "lzh");
+        add("application/x-lzx", "lzx");
+        add("application/x-maker", "frm");
+        add("application/x-maker", "maker");
+        add("application/x-maker", "frame");
+        add("application/x-maker", "fb");
+        add("application/x-maker", "book");
+        add("application/x-maker", "fbdoc");
+        add("application/x-mif", "mif");
+        add("application/x-ms-wmd", "wmd");
+        add("application/x-ms-wmz", "wmz");
+        add("application/x-msi", "msi");
+        add("application/x-ns-proxy-autoconfig", "pac");
+        add("application/x-nwc", "nwc");
+        add("application/x-object", "o");
+        add("application/x-oz-application", "oza");
+        add("application/x-pkcs12", "p12");
+        add("application/x-pkcs12", "pfx");
+        add("application/x-pkcs7-certreqresp", "p7r");
+        add("application/x-pkcs7-crl", "crl");
+        add("application/x-quicktimeplayer", "qtl");
+        add("application/x-shar", "shar");
+        add("application/x-shockwave-flash", "swf");
+        add("application/x-stuffit", "sit");
+        add("application/x-sv4cpio", "sv4cpio");
+        add("application/x-sv4crc", "sv4crc");
+        add("application/x-tar", "tar");
+        add("application/x-texinfo", "texinfo");
+        add("application/x-texinfo", "texi");
+        add("application/x-troff", "t");
+        add("application/x-troff", "roff");
+        add("application/x-troff-man", "man");
+        add("application/x-ustar", "ustar");
+        add("application/x-wais-source", "src");
+        add("application/x-wingz", "wz");
+        add("application/x-webarchive", "webarchive");
+        add("application/x-webarchive-xml", "webarchivexml");
+        add("application/x-x509-ca-cert", "crt");
+        add("application/x-x509-user-cert", "crt");
+        add("application/x-xcf", "xcf");
+        add("application/x-xfig", "fig");
+        add("application/xhtml+xml", "xhtml");
+        add("audio/3gpp", "3gpp");
+        add("audio/amr", "amr");
+        add("audio/basic", "snd");
+        add("audio/midi", "mid");
+        add("audio/midi", "midi");
+        add("audio/midi", "kar");
+        add("audio/midi", "xmf");
+        add("audio/mobile-xmf", "mxmf");
+        add("audio/mpeg", "mpga");
+        add("audio/mpeg", "mpega");
+        add("audio/mpeg", "mp2");
+        add("audio/mpeg", "mp3");
+        add("audio/mpeg", "m4a");
+        add("audio/mpegurl", "m3u");
+        add("audio/prs.sid", "sid");
+        add("audio/x-aiff", "aif");
+        add("audio/x-aiff", "aiff");
+        add("audio/x-aiff", "aifc");
+        add("audio/x-gsm", "gsm");
+        add("audio/x-mpegurl", "m3u");
+        add("audio/x-ms-wma", "wma");
+        add("audio/x-ms-wax", "wax");
+        add("audio/x-pn-realaudio", "ra");
+        add("audio/x-pn-realaudio", "rm");
+        add("audio/x-pn-realaudio", "ram");
+        add("audio/x-realaudio", "ra");
+        add("audio/x-scpls", "pls");
+        add("audio/x-sd2", "sd2");
+        add("audio/x-wav", "wav");
+        add("image/bmp", "bmp");
+        add("image/gif", "gif");
+        add("image/ico", "cur");
+        add("image/ico", "ico");
+        add("image/ief", "ief");
+        add("image/jpeg", "jpeg");
+        add("image/jpeg", "jpg");
+        add("image/jpeg", "jpe");
+        add("image/pcx", "pcx");
+        add("image/png", "png");
+        add("image/svg+xml", "svg");
+        add("image/svg+xml", "svgz");
+        add("image/tiff", "tiff");
+        add("image/tiff", "tif");
+        add("image/vnd.djvu", "djvu");
+        add("image/vnd.djvu", "djv");
+        add("image/vnd.wap.wbmp", "wbmp");
+        add("image/x-cmu-raster", "ras");
+        add("image/x-coreldraw", "cdr");
+        add("image/x-coreldrawpattern", "pat");
+        add("image/x-coreldrawtemplate", "cdt");
+        add("image/x-corelphotopaint", "cpt");
+        add("image/x-icon", "ico");
+        add("image/x-jg", "art");
+        add("image/x-jng", "jng");
+        add("image/x-ms-bmp", "bmp");
+        add("image/x-photoshop", "psd");
+        add("image/x-portable-anymap", "pnm");
+        add("image/x-portable-bitmap", "pbm");
+        add("image/x-portable-graymap", "pgm");
+        add("image/x-portable-pixmap", "ppm");
+        add("image/x-rgb", "rgb");
+        add("image/x-xbitmap", "xbm");
+        add("image/x-xpixmap", "xpm");
+        add("image/x-xwindowdump", "xwd");
+        add("model/iges", "igs");
+        add("model/iges", "iges");
+        add("model/mesh", "msh");
+        add("model/mesh", "mesh");
+        add("model/mesh", "silo");
+        add("text/calendar", "ics");
+        add("text/calendar", "icz");
+        add("text/comma-separated-values", "csv");
+        add("text/css", "css");
+        add("text/html", "htm");
+        add("text/html", "html");
+        add("text/h323", "323");
+        add("text/iuls", "uls");
+        add("text/mathml", "mml");
+        // add ".txt" first so it will be the default for ExtensionFromMimeType
+        add("text/plain", "txt");
+        add("text/plain", "asc");
+        add("text/plain", "text");
+        add("text/plain", "diff");
+        add("text/plain", "po");     // reserve "pot" for vnd.ms-powerpoint
+        add("text/richtext", "rtx");
+        add("text/rtf", "rtf");
+        add("text/texmacs", "ts");
+        add("text/text", "phps");
+        add("text/tab-separated-values", "tsv");
+        add("text/xml", "xml");
+        add("text/x-bibtex", "bib");
+        add("text/x-boo", "boo");
+        add("text/x-c++hdr", "h++");
+        add("text/x-c++hdr", "hpp");
+        add("text/x-c++hdr", "hxx");
+        add("text/x-c++hdr", "hh");
+        add("text/x-c++src", "c++");
+        add("text/x-c++src", "cpp");
+        add("text/x-c++src", "cxx");
+        add("text/x-chdr", "h");
+        add("text/x-component", "htc");
+        add("text/x-csh", "csh");
+        add("text/x-csrc", "c");
+        add("text/x-dsrc", "d");
+        add("text/x-haskell", "hs");
+        add("text/x-java", "java");
+        add("text/x-literate-haskell", "lhs");
+        add("text/x-moc", "moc");
+        add("text/x-pascal", "p");
+        add("text/x-pascal", "pas");
+        add("text/x-pcs-gcd", "gcd");
+        add("text/x-setext", "etx");
+        add("text/x-tcl", "tcl");
+        add("text/x-tex", "tex");
+        add("text/x-tex", "ltx");
+        add("text/x-tex", "sty");
+        add("text/x-tex", "cls");
+        add("text/x-vcalendar", "vcs");
+        add("text/x-vcard", "vcf");
+        add("video/3gpp", "3gpp");
+        add("video/3gpp", "3gp");
+        add("video/3gpp", "3g2");
+        add("video/dl", "dl");
+        add("video/dv", "dif");
+        add("video/dv", "dv");
+        add("video/fli", "fli");
+        add("video/m4v", "m4v");
+        add("video/mpeg", "mpeg");
+        add("video/mpeg", "mpg");
+        add("video/mpeg", "mpe");
+        add("video/mp4", "mp4");
+        add("video/mpeg", "VOB");
+        add("video/quicktime", "qt");
+        add("video/quicktime", "mov");
+        add("video/vnd.mpegurl", "mxu");
+        add("video/x-la-asf", "lsf");
+        add("video/x-la-asf", "lsx");
+        add("video/x-mng", "mng");
+        add("video/x-ms-asf", "asf");
+        add("video/x-ms-asf", "asx");
+        add("video/x-ms-wm", "wm");
+        add("video/x-ms-wmv", "wmv");
+        add("video/x-ms-wmx", "wmx");
+        add("video/x-ms-wvx", "wvx");
+        add("video/x-msvideo", "avi");
+        add("video/x-sgi-movie", "movie");
+        add("x-conference/x-cooltalk", "ice");
+        add("x-epoc/x-sisx-app", "sisx");
+        applyOverrides();
+    }
+
+    private static void add(String mimeType, String extension) {
+        //
+        // if we have an existing x --> y mapping, we do not want to
+        // override it with another mapping x --> ?
+        // this is mostly because of the way the mime-type map below
+        // is constructed (if a mime type maps to several extensions
+        // the first extension is considered the most popular and is
+        // added first; we do not want to overwrite it later).
+        //
+        if (!MIME_TYPE_TO_EXTENSION_MAP.containsKey(mimeType)) {
+            MIME_TYPE_TO_EXTENSION_MAP.put(mimeType, extension);
+        }
+        EXTENSION_TO_MIME_TYPE_MAP.put(extension, mimeType);
+    }
+
+    private static InputStream getContentTypesPropertiesStream() {
+        // User override?
+        String userTable = System.getProperty("content.types.user.table");
+        if (userTable != null) {
+            File f = new File(userTable);
+            if (f.exists()) {
+                try {
+                    return new FileInputStream(f);
+                } catch (IOException ignored) {
+                }
+            }
+        }
+
+        // Standard location?
+        File f = new File(System.getProperty("java.home"), "lib" + File.separator + "content-types.properties");
+        if (f.exists()) {
+            try {
+                return new FileInputStream(f);
+            } catch (IOException ignored) {
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * This isn't what the RI does. The RI doesn't have hard-coded defaults, so supplying your
+     * own "content.types.user.table" means you don't get any of the built-ins, and the built-ins
+     * come from "$JAVA_HOME/lib/content-types.properties".
+     */
+    private static void applyOverrides() {
+        // Get the appropriate InputStream to read overrides from, if any.
+        InputStream stream = getContentTypesPropertiesStream();
+        if (stream == null) {
+            return;
+        }
+
+        try {
+            try {
+                // Read the properties file...
+                Properties overrides = new Properties();
+                overrides.load(stream);
+                // And translate its mapping to ours...
+                for (Map.Entry<Object, Object> entry : overrides.entrySet()) {
+                    String extension = (String) entry.getKey();
+                    String mimeType = (String) entry.getValue();
+                    add(mimeType, extension);
+                }
+            } finally {
+                stream.close();
+            }
+        } catch (IOException ignored) {
+        }
+    }
+
+    private MimeUtils() {
+    }
+
+    /**
+     * Returns true if the given MIME type has an entry in the map.
+     * @param mimeType A MIME type (i.e. text/plain)
+     * @return True iff there is a mimeType entry in the map.
+     */
+    public static boolean hasMimeType(String mimeType) {
+        if (mimeType == null || mimeType.length() == 0) {
+            return false;
+        }
+        return MIME_TYPE_TO_EXTENSION_MAP.containsKey(mimeType);
+    }
+
+    /**
+     * Returns the MIME type for the given extension.
+     * @param extension A file extension without the leading '.'
+     * @return The MIME type for the given extension or null iff there is none.
+     */
+    public static String guessMimeTypeFromExtension(String extension) {
+        if (extension == null || extension.length() == 0) {
+            return null;
+        }
+        return EXTENSION_TO_MIME_TYPE_MAP.get(extension);
+    }
+
+    /**
+     * Returns true if the given extension has a registered MIME type.
+     * @param extension A file extension without the leading '.'
+     * @return True iff there is an extension entry in the map.
+     */
+    public static boolean hasExtension(String extension) {
+        if (extension == null || extension.length() == 0) {
+            return false;
+        }
+        return EXTENSION_TO_MIME_TYPE_MAP.containsKey(extension);
+    }
+
+    /**
+     * Returns the registered extension for the given MIME type. Note that some
+     * MIME types map to multiple extensions. This call will return the most
+     * common extension for the given MIME type.
+     * @param mimeType A MIME type (i.e. text/plain)
+     * @return The extension for the given MIME type or null iff there is none.
+     */
+    public static String guessExtensionFromMimeType(String mimeType) {
+        if (mimeType == null || mimeType.length() == 0) {
+            return null;
+        }
+        return MIME_TYPE_TO_EXTENSION_MAP.get(mimeType);
+    }
+}
diff --git a/src/main/java/libcore/net/http/AbstractHttpInputStream.java b/src/main/java/libcore/net/http/AbstractHttpInputStream.java
new file mode 100644
index 0000000..70f76b7
--- /dev/null
+++ b/src/main/java/libcore/net/http/AbstractHttpInputStream.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheRequest;
+import libcore.io.Streams;
+
+/**
+ * An input stream for the body of an HTTP response.
+ *
+ * <p>Since a single socket's input stream may be used to read multiple HTTP
+ * responses from the same server, subclasses shouldn't close the socket stream.
+ *
+ * <p>A side effect of reading an HTTP response is that the response cache
+ * is populated. If the stream is closed early, that cache entry will be
+ * invalidated.
+ */
+abstract class AbstractHttpInputStream extends InputStream {
+    protected final InputStream in;
+    protected final HttpEngine httpEngine;
+    private final CacheRequest cacheRequest;
+    private final OutputStream cacheBody;
+    protected boolean closed;
+
+    AbstractHttpInputStream(InputStream in, HttpEngine httpEngine,
+            CacheRequest cacheRequest) throws IOException {
+        this.in = in;
+        this.httpEngine = httpEngine;
+
+        OutputStream cacheBody = cacheRequest != null ? cacheRequest.getBody() : null;
+
+        // some apps return a null body; for compatibility we treat that like a null cache request
+        if (cacheBody == null) {
+            cacheRequest = null;
+        }
+
+        this.cacheBody = cacheBody;
+        this.cacheRequest = cacheRequest;
+    }
+
+    /**
+     * read() is implemented using read(byte[], int, int) so subclasses only
+     * need to override the latter.
+     */
+    @Override public final int read() throws IOException {
+        return Streams.readSingleByte(this);
+    }
+
+    protected final void checkNotClosed() throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+    }
+
+    protected final void cacheWrite(byte[] buffer, int offset, int count) throws IOException {
+        if (cacheBody != null) {
+            cacheBody.write(buffer, offset, count);
+        }
+    }
+
+    /**
+     * Closes the cache entry and makes the socket available for reuse. This
+     * should be invoked when the end of the body has been reached.
+     */
+    protected final void endOfInput(boolean reuseSocket) throws IOException {
+        if (cacheRequest != null) {
+            cacheBody.close();
+        }
+        httpEngine.release(reuseSocket);
+    }
+
+    /**
+     * Calls abort on the cache entry and disconnects the socket. This
+     * should be invoked when the connection is closed unexpectedly to
+     * invalidate the cache entry and to prevent the HTTP connection from
+     * being reused. HTTP messages are sent in serial so whenever a message
+     * cannot be read to completion, subsequent messages cannot be read
+     * either and the connection must be discarded.
+     *
+     * <p>An earlier implementation skipped the remaining bytes, but this
+     * requires that the entire transfer be completed. If the intention was
+     * to cancel the transfer, closing the connection is the only solution.
+     */
+    protected final void unexpectedEndOfInput() {
+        if (cacheRequest != null) {
+            cacheRequest.abort();
+        }
+        httpEngine.release(false);
+    }
+}
diff --git a/src/main/java/libcore/net/http/AbstractHttpOutputStream.java b/src/main/java/libcore/net/http/AbstractHttpOutputStream.java
new file mode 100644
index 0000000..145bc50
--- /dev/null
+++ b/src/main/java/libcore/net/http/AbstractHttpOutputStream.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+/**
+ * An output stream for the body of an HTTP request.
+ *
+ * <p>Since a single socket's output stream may be used to write multiple HTTP
+ * requests to the same server, subclasses should not close the socket stream.
+ */
+abstract class AbstractHttpOutputStream extends OutputStream {
+    protected boolean closed;
+
+    @Override public final void write(int data) throws IOException {
+        write(new byte[] {(byte) data});
+    }
+
+    protected final void checkNotClosed() throws IOException {
+        if (closed) {
+            throw new IOException("stream closed");
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/Challenge.java b/src/main/java/libcore/net/http/Challenge.java
new file mode 100644
index 0000000..d373c0a
--- /dev/null
+++ b/src/main/java/libcore/net/http/Challenge.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+/**
+ * An RFC 2617 challenge.
+ */
+final class Challenge {
+    final String scheme;
+    final String realm;
+
+    Challenge(String scheme, String realm) {
+        this.scheme = scheme;
+        this.realm = realm;
+    }
+
+    @Override public boolean equals(Object o) {
+        return o instanceof Challenge
+                && ((Challenge) o).scheme.equals(scheme)
+                && ((Challenge) o).realm.equals(realm);
+    }
+
+    @Override public int hashCode() {
+        return scheme.hashCode() + 31 * realm.hashCode();
+    }
+}
diff --git a/src/main/java/libcore/net/http/HeaderParser.java b/src/main/java/libcore/net/http/HeaderParser.java
new file mode 100644
index 0000000..4a4ac2a
--- /dev/null
+++ b/src/main/java/libcore/net/http/HeaderParser.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.util.ArrayList;
+import java.util.List;
+
+final class HeaderParser {
+
+    public interface CacheControlHandler {
+        void handle(String directive, String parameter);
+    }
+
+    /**
+     * Parse a comma-separated list of cache control header values.
+     */
+    public static void parseCacheControl(String value, CacheControlHandler handler) {
+        int pos = 0;
+        while (pos < value.length()) {
+            int tokenStart = pos;
+            pos = skipUntil(value, pos, "=,");
+            String directive = value.substring(tokenStart, pos).trim();
+
+            if (pos == value.length() || value.charAt(pos) == ',') {
+                pos++; // consume ',' (if necessary)
+                handler.handle(directive, null);
+                continue;
+            }
+
+            pos++; // consume '='
+            pos = skipWhitespace(value, pos);
+
+            String parameter;
+
+            // quoted string
+            if (pos < value.length() && value.charAt(pos) == '\"') {
+                pos++; // consume '"' open quote
+                int parameterStart = pos;
+                pos = skipUntil(value, pos, "\"");
+                parameter = value.substring(parameterStart, pos);
+                pos++; // consume '"' close quote (if necessary)
+
+            // unquoted string
+            } else {
+                int parameterStart = pos;
+                pos = skipUntil(value, pos, ",");
+                parameter = value.substring(parameterStart, pos).trim();
+            }
+
+            handler.handle(directive, parameter);
+        }
+    }
+
+    /**
+     * Parse RFC 2617 challenges. This API is only interested in the scheme
+     * name and realm.
+     */
+    public static List<Challenge> parseChallenges(
+            RawHeaders responseHeaders, String challengeHeader) {
+        /*
+         * auth-scheme = token
+         * auth-param  = token "=" ( token | quoted-string )
+         * challenge   = auth-scheme 1*SP 1#auth-param
+         * realm       = "realm" "=" realm-value
+         * realm-value = quoted-string
+         */
+        List<Challenge> result = new ArrayList<Challenge>();
+        for (int h = 0; h < responseHeaders.length(); h++) {
+            if (!challengeHeader.equalsIgnoreCase(responseHeaders.getFieldName(h))) {
+                continue;
+            }
+            String value = responseHeaders.getValue(h);
+            int pos = 0;
+            while (pos < value.length()) {
+                int tokenStart = pos;
+                pos = skipUntil(value, pos, " ");
+
+                String scheme = value.substring(tokenStart, pos).trim();
+                pos = skipWhitespace(value, pos);
+
+                // TODO: This currently only handles schemes with a 'realm' parameter;
+                //       It needs to be fixed to handle any scheme and any parameters
+                //       http://code.google.com/p/android/issues/detail?id=11140
+
+                if (!value.regionMatches(pos, "realm=\"", 0, "realm=\"".length())) {
+                    break; // unexpected challenge parameter; give up
+                }
+
+                pos += "realm=\"".length();
+                int realmStart = pos;
+                pos = skipUntil(value, pos, "\"");
+                String realm = value.substring(realmStart, pos);
+                pos++; // consume '"' close quote
+                pos = skipUntil(value, pos, ",");
+                pos++; // consume ',' comma
+                pos = skipWhitespace(value, pos);
+                result.add(new Challenge(scheme, realm));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the next index in {@code input} at or after {@code pos} that
+     * contains a character from {@code characters}. Returns the input length if
+     * none of the requested characters can be found.
+     */
+    private static int skipUntil(String input, int pos, String characters) {
+        for (; pos < input.length(); pos++) {
+            if (characters.indexOf(input.charAt(pos)) != -1) {
+                break;
+            }
+        }
+        return pos;
+    }
+
+    /**
+     * Returns the next non-whitespace character in {@code input} that is white
+     * space. Result is undefined if input contains newline characters.
+     */
+    private static int skipWhitespace(String input, int pos) {
+        for (; pos < input.length(); pos++) {
+            char c = input.charAt(pos);
+            if (c != ' ' && c != '\t') {
+                break;
+            }
+        }
+        return pos;
+    }
+
+    /**
+     * Returns {@code value} as a positive integer, or 0 if it is negative, or
+     * -1 if it cannot be parsed.
+     */
+    public static int parseSeconds(String value) {
+        try {
+            long seconds = Long.parseLong(value);
+            if (seconds > Integer.MAX_VALUE) {
+                return Integer.MAX_VALUE;
+            } else if (seconds < 0) {
+                return 0;
+            } else {
+                return (int) seconds;
+            }
+        } catch (NumberFormatException e) {
+            return -1;
+        }
+    }
+
+    private HeaderParser() {
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpConnection.java b/src/main/java/libcore/net/http/HttpConnection.java
new file mode 100644
index 0000000..6d5b7d8
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpConnection.java
@@ -0,0 +1,373 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.ProxySelector;
+import java.net.Socket;
+import java.net.SocketAddress;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.UnknownHostException;
+import java.util.Arrays;
+import java.util.List;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+import libcore.io.IoUtils;
+import libcore.net.spdy.SpdyConnection;
+import libcore.util.Libcore;
+import libcore.util.Objects;
+
+/**
+ * Holds the sockets and streams of an HTTP, HTTPS, or HTTPS+SPDY connection,
+ * which may be used for multiple HTTP request/response exchanges. Connections
+ * may be direct to the origin server or via a proxy. Create an instance using
+ * the {@link Address} inner class.
+ *
+ * <p>Do not confuse this class with the misnamed {@code HttpURLConnection},
+ * which isn't so much a connection as a single request/response pair.
+ */
+final class HttpConnection {
+    private static final byte[] NPN_PROTOCOLS = new byte[] {
+            6, 's', 'p', 'd', 'y', '/', '2',
+            8, 'h', 't', 't', 'p', '/', '1', '.', '1',
+    };
+    private static final byte[] SPDY2 = new byte[] {
+            's', 'p', 'd', 'y', '/', '2',
+    };
+    private static final byte[] HTTP_11 = new byte[] {
+            'h', 't', 't', 'p', '/', '1', '.', '1',
+    };
+
+    private final Address address;
+    private final Socket socket;
+    private InputStream inputStream;
+    private OutputStream outputStream;
+    private SSLSocket sslSocket;
+    private InputStream sslInputStream;
+    private OutputStream sslOutputStream;
+    private boolean recycled = false;
+    private SpdyConnection spdyConnection;
+
+    /**
+     * The version this client will use. Either 0 for HTTP/1.0, or 1 for
+     * HTTP/1.1. Upon receiving a non-HTTP/1.1 response, this client
+     * automatically sets its version to HTTP/1.0.
+     */
+    int httpMinorVersion = 1; // Assume HTTP/1.1
+
+    private HttpConnection(Address config, int connectTimeout) throws IOException {
+        this.address = config;
+
+        /*
+         * Try each of the host's addresses for best behavior in mixed IPv4/IPv6
+         * environments. See http://b/2876927
+         * TODO: add a hidden method so that Socket.tryAllAddresses can does this for us
+         */
+        Socket socketCandidate = null;
+        InetAddress[] addresses = InetAddress.getAllByName(config.socketHost);
+        for (int i = 0; i < addresses.length; i++) {
+            socketCandidate = (config.proxy != null && config.proxy.type() != Proxy.Type.HTTP)
+                    ? new Socket(config.proxy)
+                    : new Socket();
+            try {
+                socketCandidate.connect(
+                        new InetSocketAddress(addresses[i], config.socketPort), connectTimeout);
+                break;
+            } catch (IOException e) {
+                if (i == addresses.length - 1) {
+                    throw e;
+                }
+            }
+        }
+
+        if (socketCandidate == null) {
+            throw new IOException();
+        }
+
+        this.socket = socketCandidate;
+
+        /*
+         * Buffer the socket stream to permit efficient parsing of HTTP headers
+         * and chunk sizes. Benchmarks suggest 128 is sufficient. We cannot
+         * buffer when setting up a tunnel because we may consume bytes intended
+         * for the SSL socket.
+         */
+        int bufferSize = 128;
+        inputStream = address.requiresTunnel
+                ? socket.getInputStream()
+                : new BufferedInputStream(socket.getInputStream(), bufferSize);
+        outputStream = socket.getOutputStream();
+    }
+
+    public static HttpConnection connect(URI uri, SSLSocketFactory sslSocketFactory,
+            Proxy proxy, boolean requiresTunnel, int connectTimeout) throws IOException {
+        /*
+         * Try an explicitly-specified proxy.
+         */
+        if (proxy != null) {
+            Address address = (proxy.type() == Proxy.Type.DIRECT)
+                    ? new Address(uri, sslSocketFactory)
+                    : new Address(uri, sslSocketFactory, proxy, requiresTunnel);
+            return HttpConnectionPool.INSTANCE.get(address, connectTimeout);
+        }
+
+        /*
+         * Try connecting to each of the proxies provided by the ProxySelector
+         * until a connection succeeds.
+         */
+        ProxySelector selector = ProxySelector.getDefault();
+        List<Proxy> proxyList = selector.select(uri);
+        if (proxyList != null) {
+            for (Proxy selectedProxy : proxyList) {
+                if (selectedProxy.type() == Proxy.Type.DIRECT) {
+                    // the same as NO_PROXY
+                    // TODO: if the selector recommends a direct connection, attempt that?
+                    continue;
+                }
+                try {
+                    Address address = new Address(uri, sslSocketFactory,
+                            selectedProxy, requiresTunnel);
+                    return HttpConnectionPool.INSTANCE.get(address, connectTimeout);
+                } catch (IOException e) {
+                    // failed to connect, tell it to the selector
+                    selector.connectFailed(uri, selectedProxy.address(), e);
+                }
+            }
+        }
+
+        /*
+         * Try a direct connection. If this fails, this method will throw.
+         */
+        return HttpConnectionPool.INSTANCE.get(new Address(uri, sslSocketFactory), connectTimeout);
+    }
+
+    public void closeSocketAndStreams() {
+        IoUtils.closeQuietly(sslOutputStream);
+        IoUtils.closeQuietly(sslInputStream);
+        IoUtils.closeQuietly(sslSocket);
+        IoUtils.closeQuietly(outputStream);
+        IoUtils.closeQuietly(inputStream);
+        IoUtils.closeQuietly(socket);
+    }
+
+    public void setSoTimeout(int readTimeout) throws SocketException {
+        socket.setSoTimeout(readTimeout);
+    }
+
+    Socket getSocket() {
+        return sslSocket != null ? sslSocket : socket;
+    }
+
+    public Address getAddress() {
+        return address;
+    }
+
+    /**
+     * Create an {@code SSLSocket} and perform the SSL handshake
+     * (performing certificate validation.
+     *
+     * @param sslSocketFactory Source of new {@code SSLSocket} instances.
+     * @param tlsTolerant If true, assume server can handle common
+     */
+    public SSLSocket setupSecureSocket(SSLSocketFactory sslSocketFactory,
+            HostnameVerifier hostnameVerifier, boolean tlsTolerant) throws IOException {
+        if (spdyConnection != null || sslOutputStream != null || sslInputStream != null) {
+            throw new IllegalStateException();
+        }
+
+        // Create the wrapper over connected socket.
+        sslSocket = (SSLSocket) sslSocketFactory.createSocket(socket,
+                address.uriHost, address.uriPort, true /* autoClose */);
+        Libcore.makeTlsTolerant(sslSocket, address.socketHost, tlsTolerant);
+
+        if (tlsTolerant) {
+            Libcore.setNpnProtocols(sslSocket, NPN_PROTOCOLS);
+        }
+
+        // Force handshake. This can throw!
+        sslSocket.startHandshake();
+
+        // Verify that the socket's certificates are acceptable for the target host.
+        if (!hostnameVerifier.verify(address.uriHost, sslSocket.getSession())) {
+            throw new IOException("Hostname '" + address.uriHost + "' was not verified");
+        }
+
+        // SSL success. Prepare to hand out Transport instances.
+        sslOutputStream = sslSocket.getOutputStream();
+        sslInputStream = sslSocket.getInputStream();
+
+        byte[] selectedProtocol;
+        if (tlsTolerant
+                && (selectedProtocol = Libcore.getNpnSelectedProtocol(sslSocket)) != null) {
+            if (Arrays.equals(selectedProtocol, SPDY2)) {
+                spdyConnection = new SpdyConnection.Builder(
+                        true, sslInputStream, sslOutputStream).build();
+                HttpConnectionPool.INSTANCE.share(this);
+            } else if (!Arrays.equals(selectedProtocol, HTTP_11)) {
+                throw new IOException("Unexpected NPN transport "
+                        + new String(selectedProtocol, "ISO-8859-1"));
+            }
+        }
+
+        return sslSocket;
+    }
+
+    /**
+     * Return an {@code SSLSocket} if already connected, otherwise null.
+     */
+    public SSLSocket getSecureSocketIfConnected() {
+        return sslSocket;
+    }
+
+    /**
+     * Returns true if this connection has been used to satisfy an earlier
+     * HTTP request/response pair.
+     */
+    public boolean isRecycled() {
+        return recycled;
+    }
+
+    public void setRecycled() {
+        this.recycled = true;
+    }
+
+    /**
+     * Returns true if this connection is eligible to be reused for another
+     * request/response pair.
+     */
+    protected boolean isEligibleForRecycling() {
+        return !socket.isClosed()
+                && !socket.isInputShutdown()
+                && !socket.isOutputShutdown();
+    }
+
+    /**
+     * Returns the transport appropriate for this connection.
+     */
+    public Transport newTransport(HttpEngine httpEngine) throws IOException {
+        if (spdyConnection != null) {
+            return new SpdyTransport(httpEngine, spdyConnection);
+        } else if (sslSocket != null) {
+            return new HttpTransport(httpEngine, sslOutputStream, sslInputStream);
+        } else {
+            return new HttpTransport(httpEngine, outputStream, inputStream);
+        }
+    }
+
+    /**
+     * Returns true if this is a SPDY connection. Such connections can be used
+     * in multiple HTTP requests simultaneously.
+     */
+    public boolean isSpdy() {
+        return spdyConnection != null;
+    }
+
+    /**
+     * This address has two parts: the address we connect to directly and the
+     * origin address of the resource. These are the same unless a proxy is
+     * being used. It also includes the SSL socket factory so that a socket will
+     * not be reused if its SSL configuration is different.
+     */
+    public static final class Address {
+        private final Proxy proxy;
+        private final boolean requiresTunnel;
+        private final String uriHost;
+        private final int uriPort;
+        private final String socketHost;
+        private final int socketPort;
+        private final SSLSocketFactory sslSocketFactory;
+
+        public Address(URI uri, SSLSocketFactory sslSocketFactory) throws UnknownHostException {
+            this.proxy = null;
+            this.requiresTunnel = false;
+            this.uriHost = uri.getHost();
+            this.uriPort = Libcore.getEffectivePort(uri);
+            this.sslSocketFactory = sslSocketFactory;
+            this.socketHost = uriHost;
+            this.socketPort = uriPort;
+            if (uriHost == null) {
+                throw new UnknownHostException(uri.toString());
+            }
+        }
+
+        /**
+         * @param requiresTunnel true if the HTTP connection needs to tunnel one
+         *     protocol over another, such as when using HTTPS through an HTTP
+         *     proxy. When doing so, we must avoid buffering bytes intended for
+         *     the higher-level protocol.
+         */
+        public Address(URI uri, SSLSocketFactory sslSocketFactory,
+                Proxy proxy, boolean requiresTunnel) throws UnknownHostException {
+            this.proxy = proxy;
+            this.requiresTunnel = requiresTunnel;
+            this.uriHost = uri.getHost();
+            this.uriPort = Libcore.getEffectivePort(uri);
+            this.sslSocketFactory = sslSocketFactory;
+
+            SocketAddress proxyAddress = proxy.address();
+            if (!(proxyAddress instanceof InetSocketAddress)) {
+                throw new IllegalArgumentException("Proxy.address() is not an InetSocketAddress: "
+                        + proxyAddress.getClass());
+            }
+            InetSocketAddress proxySocketAddress = (InetSocketAddress) proxyAddress;
+            this.socketHost = proxySocketAddress.getHostName();
+            this.socketPort = proxySocketAddress.getPort();
+            if (uriHost == null) {
+                throw new UnknownHostException(uri.toString());
+            }
+        }
+
+        public Proxy getProxy() {
+            return proxy;
+        }
+
+        @Override public boolean equals(Object other) {
+            if (other instanceof Address) {
+                Address that = (Address) other;
+                return Objects.equal(this.proxy, that.proxy)
+                        && this.uriHost.equals(that.uriHost)
+                        && this.uriPort == that.uriPort
+                        && Objects.equal(this.sslSocketFactory, that.sslSocketFactory)
+                        && this.requiresTunnel == that.requiresTunnel;
+            }
+            return false;
+        }
+
+        @Override public int hashCode() {
+            int result = 17;
+            result = 31 * result + uriHost.hashCode();
+            result = 31 * result + uriPort;
+            result = 31 * result + (sslSocketFactory != null ? sslSocketFactory.hashCode() : 0);
+            result = 31 * result + (proxy != null ? proxy.hashCode() : 0);
+            result = 31 * result + (requiresTunnel ? 1 : 0);
+            return result;
+        }
+
+        public HttpConnection connect(int connectTimeout) throws IOException {
+            return new HttpConnection(this, connectTimeout);
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpConnectionPool.java b/src/main/java/libcore/net/http/HttpConnectionPool.java
new file mode 100644
index 0000000..490c98a
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpConnectionPool.java
@@ -0,0 +1,152 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.net.SocketException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import libcore.util.Libcore;
+
+/**
+ * A pool of HTTP and SPDY connections. This class exposes its tuning parameters
+ * as system properties:
+ * <ul>
+ *   <li>{@code http.keepAlive} true if HTTP and SPDY connections should be
+ *       pooled at all. Default is true.
+ *   <li>{@code http.maxConnections} maximum number of connections to each host.
+ *       Default is 5.
+ * </ul>
+ *
+ * <p>This class <i>doesn't</i> adjust its configuration as system properties
+ * are changed. This assumes that the applications that set these parameters do
+ * so before making HTTP connections, and that this class is initialized lazily.
+ */
+final class HttpConnectionPool {
+    public static final HttpConnectionPool INSTANCE = new HttpConnectionPool();
+
+    private final int maxConnections;
+    private final HashMap<HttpConnection.Address, List<HttpConnection>> connectionPool
+            = new HashMap<HttpConnection.Address, List<HttpConnection>>();
+
+    private HttpConnectionPool() {
+        String keepAlive = System.getProperty("http.keepAlive");
+        if (keepAlive != null && !Boolean.parseBoolean(keepAlive)) {
+            maxConnections = 0;
+            return;
+        }
+
+        String maxConnectionsString = System.getProperty("http.maxConnections");
+        this.maxConnections = maxConnectionsString != null
+                ? Integer.parseInt(maxConnectionsString)
+                : 5;
+    }
+
+    public HttpConnection get(HttpConnection.Address address, int connectTimeout)
+            throws IOException {
+        // First try to reuse an existing HTTP connection.
+        synchronized (connectionPool) {
+            List<HttpConnection> connections = connectionPool.get(address);
+            while (connections != null) {
+                HttpConnection connection = connections.get(connections.size() - 1);
+                if (!connection.isSpdy()) {
+                    connections.remove(connections.size() - 1);
+                }
+                if (connections.isEmpty()) {
+                    connectionPool.remove(address);
+                    connections = null;
+                }
+                if (connection.isEligibleForRecycling()) {
+                    // Since Socket is recycled, re-tag before using
+                    Socket socket = connection.getSocket();
+                    Libcore.tagSocket(socket);
+                    return connection;
+                }
+            }
+        }
+
+        /*
+         * We couldn't find a reusable connection, so we need to create a new
+         * connection. We're careful not to do so while holding a lock!
+         */
+        return address.connect(connectTimeout);
+    }
+
+    /**
+     * Gives the HTTP/HTTPS connection to the pool. It is an error to use {@code
+     * connection} after calling this method.
+     */
+    public void recycle(HttpConnection connection) {
+        if (connection.isSpdy()) {
+            throw new IllegalArgumentException();
+        }
+
+        Socket socket = connection.getSocket();
+        try {
+            Libcore.untagSocket(socket);
+        } catch (SocketException e) {
+            // When unable to remove tagging, skip recycling and close
+            Libcore.logW("Unable to untagSocket(): " + e);
+            connection.closeSocketAndStreams();
+            return;
+        }
+
+        if (maxConnections > 0 && connection.isEligibleForRecycling()) {
+            HttpConnection.Address address = connection.getAddress();
+            synchronized (connectionPool) {
+                List<HttpConnection> connections = connectionPool.get(address);
+                if (connections == null) {
+                    connections = new ArrayList<HttpConnection>();
+                    connectionPool.put(address, connections);
+                }
+                if (connections.size() < maxConnections) {
+                    connection.setRecycled();
+                    connections.add(connection);
+                    return; // keep the connection open
+                }
+            }
+        }
+
+        // don't close streams while holding a lock!
+        connection.closeSocketAndStreams();
+    }
+
+    /**
+     * Shares the SPDY connection with the pool. Callers to this method may
+     * continue to use {@code connection}.
+     */
+    public void share(HttpConnection connection) {
+        if (!connection.isSpdy()) {
+            throw new IllegalArgumentException();
+        }
+        if (maxConnections <= 0 || !connection.isEligibleForRecycling()) {
+            return;
+        }
+        HttpConnection.Address address = connection.getAddress();
+        synchronized (connectionPool) {
+            List<HttpConnection> connections = connectionPool.get(address);
+            if (connections == null) {
+                connections = new ArrayList<HttpConnection>(1);
+                connections.add(connection);
+                connectionPool.put(address, connections);
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpDate.java b/src/main/java/libcore/net/http/HttpDate.java
new file mode 100644
index 0000000..41ae5ef
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpDate.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.text.DateFormat;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Locale;
+import java.util.TimeZone;
+
+/**
+ * Best-effort parser for HTTP dates.
+ */
+public final class HttpDate {
+
+    /**
+     * Most websites serve cookies in the blessed format. Eagerly create the parser to ensure such
+     * cookies are on the fast path.
+     */
+    private static final ThreadLocal<DateFormat> STANDARD_DATE_FORMAT
+            = new ThreadLocal<DateFormat>() {
+        @Override protected DateFormat initialValue() {
+            DateFormat rfc1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US);
+            rfc1123.setTimeZone(TimeZone.getTimeZone("UTC"));
+            return rfc1123;
+        }
+    };
+
+    /**
+     * If we fail to parse a date in a non-standard format, try each of these formats in sequence.
+     */
+    private static final String[] BROWSER_COMPATIBLE_DATE_FORMATS = new String[] {
+            /* This list comes from  {@code org.apache.http.impl.cookie.BrowserCompatSpec}. */
+            "EEEE, dd-MMM-yy HH:mm:ss zzz", // RFC 1036
+            "EEE MMM d HH:mm:ss yyyy", // ANSI C asctime()
+            "EEE, dd-MMM-yyyy HH:mm:ss z",
+            "EEE, dd-MMM-yyyy HH-mm-ss z",
+            "EEE, dd MMM yy HH:mm:ss z",
+            "EEE dd-MMM-yyyy HH:mm:ss z",
+            "EEE dd MMM yyyy HH:mm:ss z",
+            "EEE dd-MMM-yyyy HH-mm-ss z",
+            "EEE dd-MMM-yy HH:mm:ss z",
+            "EEE dd MMM yy HH:mm:ss z",
+            "EEE,dd-MMM-yy HH:mm:ss z",
+            "EEE,dd-MMM-yyyy HH:mm:ss z",
+            "EEE, dd-MM-yyyy HH:mm:ss z",
+
+            /* RI bug 6641315 claims a cookie of this format was once served by www.yahoo.com */
+            "EEE MMM d yyyy HH:mm:ss z",
+    };
+
+    /**
+     * Returns the date for {@code value}. Returns null if the value couldn't be
+     * parsed.
+     */
+    public static Date parse(String value) {
+        try {
+            return STANDARD_DATE_FORMAT.get().parse(value);
+        } catch (ParseException ignore) {
+        }
+        for (String formatString : BROWSER_COMPATIBLE_DATE_FORMATS) {
+            try {
+                return new SimpleDateFormat(formatString, Locale.US).parse(value);
+            } catch (ParseException ignore) {
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string for {@code value}.
+     */
+    public static String format(Date value) {
+        return STANDARD_DATE_FORMAT.get().format(value);
+    }
+
+    private HttpDate() {
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpEngine.java b/src/main/java/libcore/net/http/HttpEngine.java
new file mode 100644
index 0000000..9acb72f
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpEngine.java
@@ -0,0 +1,640 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import com.squareup.okhttp.OkHttpConnection;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.CookieHandler;
+import java.net.Proxy;
+import java.net.ResponseCache;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.GZIPInputStream;
+import javax.net.ssl.SSLSocketFactory;
+import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
+import libcore.util.ExtendedResponseCache;
+import libcore.util.Libcore;
+import libcore.util.ResponseSource;
+
+/**
+ * Handles a single HTTP request/response pair. Each HTTP engine follows this
+ * lifecycle:
+ * <ol>
+ *     <li>It is created.
+ *     <li>The HTTP request message is sent with sendRequest(). Once the request
+ *         is sent it is an error to modify the request headers. After
+ *         sendRequest() has been called the request body can be written to if
+ *         it exists.
+ *     <li>The HTTP response message is read with readResponse(). After the
+ *         response has been read the response headers and body can be read.
+ *         All responses have a response body input stream, though in some
+ *         instances this stream is empty.
+ * </ol>
+ *
+ * <p>The request and response may be served by the HTTP response cache, by the
+ * network, or by both in the event of a conditional GET.
+ *
+ * <p>This class may hold a socket connection that needs to be released or
+ * recycled. By default, this socket connection is held when the last byte of
+ * the response is consumed. To release the connection when it is no longer
+ * required, use {@link #automaticallyReleaseConnectionToPool()}.
+ */
+public class HttpEngine {
+    private static final CacheResponse BAD_GATEWAY_RESPONSE = new CacheResponse() {
+        @Override public Map<String, List<String>> getHeaders() throws IOException {
+            Map<String, List<String>> result = new HashMap<String, List<String>>();
+            result.put(null, Collections.singletonList("HTTP/1.1 502 Bad Gateway"));
+            return result;
+        }
+        @Override public InputStream getBody() throws IOException {
+            return new ByteArrayInputStream(EmptyArray.BYTE);
+        }
+    };
+    public static final int DEFAULT_CHUNK_LENGTH = 1024;
+
+    public static final String OPTIONS = "OPTIONS";
+    public static final String GET = "GET";
+    public static final String HEAD = "HEAD";
+    public static final String POST = "POST";
+    public static final String PUT = "PUT";
+    public static final String DELETE = "DELETE";
+    public static final String TRACE = "TRACE";
+    public static final String CONNECT = "CONNECT";
+
+    public static final int HTTP_CONTINUE = 100;
+
+    protected final HttpURLConnectionImpl policy;
+
+    protected final String method;
+
+    private ResponseSource responseSource;
+
+    protected HttpConnection connection;
+    private OutputStream requestBodyOut;
+
+    private Transport transport;
+
+    private InputStream responseBodyIn;
+
+    private final ResponseCache responseCache = ResponseCache.getDefault();
+    private CacheResponse cacheResponse;
+    private CacheRequest cacheRequest;
+
+    /** The time when the request headers were written, or -1 if they haven't been written yet. */
+    long sentRequestMillis = -1;
+
+    /**
+     * True if this client added an "Accept-Encoding: gzip" header field and is
+     * therefore responsible for also decompressing the transfer stream.
+     */
+    private boolean transparentGzip;
+
+    final URI uri;
+
+    final RequestHeaders requestHeaders;
+
+    /** Null until a response is received from the network or the cache. */
+    ResponseHeaders responseHeaders;
+
+    /*
+     * The cache response currently being validated on a conditional get. Null
+     * if the cached response doesn't exist or doesn't need validation. If the
+     * conditional get succeeds, these will be used for the response headers and
+     * body. If it fails, these be closed and set to null.
+     */
+    private ResponseHeaders cachedResponseHeaders;
+    private InputStream cachedResponseBody;
+
+    /**
+     * True if the socket connection should be released to the connection pool
+     * when the response has been fully read.
+     */
+    private boolean automaticallyReleaseConnectionToPool;
+
+    /** True if the socket connection is no longer needed by this engine. */
+    private boolean connectionReleased;
+
+    /**
+     * @param requestHeaders the client's supplied request headers. This class
+     *     creates a private copy that it can mutate.
+     * @param connection the connection used for an intermediate response
+     *     immediately prior to this request/response pair, such as a same-host
+     *     redirect. This engine assumes ownership of the connection and must
+     *     release it when it is unneeded.
+     */
+    public HttpEngine(HttpURLConnectionImpl policy, String method, RawHeaders requestHeaders,
+            HttpConnection connection, RetryableOutputStream requestBodyOut) throws IOException {
+        this.policy = policy;
+        this.method = method;
+        this.connection = connection;
+        this.requestBodyOut = requestBodyOut;
+
+        try {
+            uri = Libcore.toUriLenient(policy.getURL());
+        } catch (URISyntaxException e) {
+            throw new IOException(e);
+        }
+
+        this.requestHeaders = new RequestHeaders(uri, new RawHeaders(requestHeaders));
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    /**
+     * Figures out what the response source will be, and opens a socket to that
+     * source if necessary. Prepares the request headers and gets ready to start
+     * writing the request body if it exists.
+     */
+    public final void sendRequest() throws IOException {
+        if (responseSource != null) {
+            return;
+        }
+
+        prepareRawRequestHeaders();
+        initResponseSource();
+        if (responseCache instanceof ExtendedResponseCache) {
+            ((ExtendedResponseCache) responseCache).trackResponse(responseSource);
+        }
+
+        /*
+         * The raw response source may require the network, but the request
+         * headers may forbid network use. In that case, dispose of the network
+         * response and use a BAD_GATEWAY response instead.
+         */
+        if (requestHeaders.isOnlyIfCached() && responseSource.requiresConnection()) {
+            if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
+                IoUtils.closeQuietly(cachedResponseBody);
+            }
+            this.responseSource = ResponseSource.CACHE;
+            this.cacheResponse = BAD_GATEWAY_RESPONSE;
+            RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(cacheResponse.getHeaders());
+            setResponse(new ResponseHeaders(uri, rawResponseHeaders), cacheResponse.getBody());
+        }
+
+        if (responseSource.requiresConnection()) {
+            sendSocketRequest();
+        } else if (connection != null) {
+            HttpConnectionPool.INSTANCE.recycle(connection);
+            connection = null;
+        }
+    }
+
+    /**
+     * Initialize the source for this response. It may be corrected later if the
+     * request headers forbids network use.
+     */
+    private void initResponseSource() throws IOException {
+        responseSource = ResponseSource.NETWORK;
+        if (!policy.getUseCaches() || responseCache == null) {
+            return;
+        }
+
+        CacheResponse candidate = responseCache.get(uri, method,
+                requestHeaders.getHeaders().toMultimap());
+        if (candidate == null) {
+            return;
+        }
+
+        Map<String, List<String>> responseHeadersMap = candidate.getHeaders();
+        cachedResponseBody = candidate.getBody();
+        if (!acceptCacheResponseType(candidate)
+                || responseHeadersMap == null
+                || cachedResponseBody == null) {
+            IoUtils.closeQuietly(cachedResponseBody);
+            return;
+        }
+
+        RawHeaders rawResponseHeaders = RawHeaders.fromMultimap(responseHeadersMap);
+        cachedResponseHeaders = new ResponseHeaders(uri, rawResponseHeaders);
+        long now = System.currentTimeMillis();
+        this.responseSource = cachedResponseHeaders.chooseResponseSource(now, requestHeaders);
+        if (responseSource == ResponseSource.CACHE) {
+            this.cacheResponse = candidate;
+            setResponse(cachedResponseHeaders, cachedResponseBody);
+        } else if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
+            this.cacheResponse = candidate;
+        } else if (responseSource == ResponseSource.NETWORK) {
+            IoUtils.closeQuietly(cachedResponseBody);
+        } else {
+            throw new AssertionError();
+        }
+    }
+
+    private void sendSocketRequest() throws IOException {
+        if (connection == null) {
+            connect();
+        }
+
+        if (transport != null) {
+            throw new IllegalStateException();
+        }
+
+        transport = connection.newTransport(this);
+
+        if (hasRequestBody() && requestBodyOut == null) {
+            // Create a request body if we don't have one already. We'll already
+            // have one if we're retrying a failed POST.
+            requestBodyOut = transport.createRequestBody();
+        }
+    }
+
+    /**
+     * Connect to the origin server either directly or via a proxy.
+     */
+    protected void connect() throws IOException {
+        if (connection == null) {
+            connection = openSocketConnection();
+        }
+    }
+
+    protected final HttpConnection openSocketConnection() throws IOException {
+        HttpConnection result = HttpConnection.connect(uri, getSslSocketFactory(),
+                policy.getProxy(), requiresTunnel(), policy.getConnectTimeout());
+        Proxy proxy = result.getAddress().getProxy();
+        if (proxy != null) {
+            policy.setProxy(proxy);
+            // Add the authority to the request line when we're using a proxy.
+            requestHeaders.getHeaders().setStatusLine(getRequestLine());
+        }
+        result.setSoTimeout(policy.getReadTimeout());
+        return result;
+    }
+
+    /**
+     * @param body the response body, or null if it doesn't exist or isn't
+     *     available.
+     */
+    private void setResponse(ResponseHeaders headers, InputStream body) throws IOException {
+        if (this.responseBodyIn != null) {
+            throw new IllegalStateException();
+        }
+        this.responseHeaders = headers;
+        if (body != null) {
+            initContentStream(body);
+        }
+    }
+
+    boolean hasRequestBody() {
+        return method == POST || method == PUT;
+    }
+
+    /**
+     * Returns the request body or null if this request doesn't have a body.
+     */
+    public final OutputStream getRequestBody() {
+        if (responseSource == null) {
+            throw new IllegalStateException();
+        }
+        return requestBodyOut;
+    }
+
+    public final boolean hasResponse() {
+        return responseHeaders != null;
+    }
+
+    public final RequestHeaders getRequestHeaders() {
+        return requestHeaders;
+    }
+
+    public final ResponseHeaders getResponseHeaders() {
+        if (responseHeaders == null) {
+            throw new IllegalStateException();
+        }
+        return responseHeaders;
+    }
+
+    public final int getResponseCode() {
+        if (responseHeaders == null) {
+            throw new IllegalStateException();
+        }
+        return responseHeaders.getHeaders().getResponseCode();
+    }
+
+    public final InputStream getResponseBody() {
+        if (responseHeaders == null) {
+            throw new IllegalStateException();
+        }
+        return responseBodyIn;
+    }
+
+    public final CacheResponse getCacheResponse() {
+        return cacheResponse;
+    }
+
+    public final HttpConnection getConnection() {
+        return connection;
+    }
+
+    public final boolean hasRecycledConnection() {
+        return connection != null && connection.isRecycled();
+    }
+
+    /**
+     * Returns true if {@code cacheResponse} is of the right type. This
+     * condition is necessary but not sufficient for the cached response to
+     * be used.
+     */
+    protected boolean acceptCacheResponseType(CacheResponse cacheResponse) {
+        return true;
+    }
+
+    private void maybeCache() throws IOException {
+        // Are we caching at all?
+        if (!policy.getUseCaches() || responseCache == null) {
+            return;
+        }
+
+        // Should we cache this response for this request?
+        if (!responseHeaders.isCacheable(requestHeaders)) {
+            return;
+        }
+
+        // Offer this request to the cache.
+        cacheRequest = responseCache.put(uri, getHttpConnectionToCache());
+    }
+
+    protected OkHttpConnection getHttpConnectionToCache() {
+        return policy;
+    }
+
+    /**
+     * Cause the socket connection to be released to the connection pool when
+     * it is no longer needed. If it is already unneeded, it will be pooled
+     * immediately. Otherwise the connection is held so that redirects can be
+     * handled by the same connection.
+     */
+    public final void automaticallyReleaseConnectionToPool() {
+        automaticallyReleaseConnectionToPool = true;
+        if (connection != null && connectionReleased) {
+            HttpConnectionPool.INSTANCE.recycle(connection);
+            connection = null;
+        }
+    }
+
+    /**
+     * Releases this engine so that its resources may be either reused or
+     * closed. Also call {@link #automaticallyReleaseConnectionToPool} unless
+     * the connection will be used to follow a redirect.
+     */
+    public final void release(boolean reusable) {
+        // If the response body comes from the cache, close it.
+        if (responseBodyIn == cachedResponseBody) {
+            IoUtils.closeQuietly(responseBodyIn);
+        }
+
+        if (!connectionReleased && connection != null) {
+            connectionReleased = true;
+
+            if (!reusable || !transport.makeReusable(requestBodyOut, responseBodyIn)) {
+                connection.closeSocketAndStreams();
+                connection = null;
+            } else if (automaticallyReleaseConnectionToPool) {
+                HttpConnectionPool.INSTANCE.recycle(connection);
+                connection = null;
+            }
+        }
+    }
+
+    private void initContentStream(InputStream transferStream) throws IOException {
+        if (transparentGzip && responseHeaders.isContentEncodingGzip()) {
+            /*
+             * If the response was transparently gzipped, remove the gzip header field
+             * so clients don't double decompress. http://b/3009828
+             */
+            responseHeaders.stripContentEncoding();
+            responseBodyIn = new GZIPInputStream(transferStream);
+        } else {
+            responseBodyIn = transferStream;
+        }
+    }
+
+    /**
+     * Returns true if the response must have a (possibly 0-length) body.
+     * See RFC 2616 section 4.3.
+     */
+    public final boolean hasResponseBody() {
+        int responseCode = responseHeaders.getHeaders().getResponseCode();
+
+        // HEAD requests never yield a body regardless of the response headers.
+        if (method == HEAD) {
+            return false;
+        }
+
+        if (method != CONNECT
+                && (responseCode < HTTP_CONTINUE || responseCode >= 200)
+                && responseCode != HttpURLConnectionImpl.HTTP_NO_CONTENT
+                && responseCode != HttpURLConnectionImpl.HTTP_NOT_MODIFIED) {
+            return true;
+        }
+
+        /*
+         * If the Content-Length or Transfer-Encoding headers disagree with the
+         * response code, the response is malformed. For best compatibility, we
+         * honor the headers.
+         */
+        if (responseHeaders.getContentLength() != -1 || responseHeaders.isChunked()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Populates requestHeaders with defaults and cookies.
+     *
+     * <p>This client doesn't specify a default {@code Accept} header because it
+     * doesn't know what content types the application is interested in.
+     */
+    private void prepareRawRequestHeaders() throws IOException {
+        requestHeaders.getHeaders().setStatusLine(getRequestLine());
+
+        if (requestHeaders.getUserAgent() == null) {
+            requestHeaders.setUserAgent(getDefaultUserAgent());
+        }
+
+        if (requestHeaders.getHost() == null) {
+            requestHeaders.setHost(getOriginAddress(policy.getURL()));
+        }
+
+        // TODO: this shouldn't be set for SPDY (it's ignored)
+        if ((connection == null || connection.httpMinorVersion != 0)
+                && requestHeaders.getConnection() == null) {
+            requestHeaders.setConnection("Keep-Alive");
+        }
+
+        if (requestHeaders.getAcceptEncoding() == null) {
+            transparentGzip = true;
+            // TODO: this shouldn't be set for SPDY (it isn't necessary)
+            requestHeaders.setAcceptEncoding("gzip");
+        }
+
+        if (hasRequestBody() && requestHeaders.getContentType() == null) {
+            requestHeaders.setContentType("application/x-www-form-urlencoded");
+        }
+
+        long ifModifiedSince = policy.getIfModifiedSince();
+        if (ifModifiedSince != 0) {
+            requestHeaders.setIfModifiedSince(new Date(ifModifiedSince));
+        }
+
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler != null) {
+            requestHeaders.addCookies(
+                    cookieHandler.get(uri, requestHeaders.getHeaders().toMultimap()));
+        }
+    }
+
+    /**
+     * Returns the request status line, like "GET / HTTP/1.1". This is exposed
+     * to the application by {@link HttpURLConnectionImpl#getHeaderFields}, so
+     * it needs to be set even if the transport is SPDY.
+     */
+    String getRequestLine() {
+        String protocol = (connection == null || connection.httpMinorVersion != 0)
+                ? "HTTP/1.1"
+                : "HTTP/1.0";
+        return method + " " + requestString() + " " + protocol;
+    }
+
+    private String requestString() {
+        URL url = policy.getURL();
+        if (includeAuthorityInRequestLine()) {
+            return url.toString();
+        } else {
+            String fileOnly = url.getFile();
+            if (fileOnly == null) {
+                fileOnly = "/";
+            } else if (!fileOnly.startsWith("/")) {
+                fileOnly = "/" + fileOnly;
+            }
+            return fileOnly;
+        }
+    }
+
+    /**
+     * Returns true if the request line should contain the full URL with host
+     * and port (like "GET http://android.com/foo HTTP/1.1") or only the path
+     * (like "GET /foo HTTP/1.1").
+     *
+     * <p>This is non-final because for HTTPS it's never necessary to supply the
+     * full URL, even if a proxy is in use.
+     */
+    protected boolean includeAuthorityInRequestLine() {
+        return policy.usingProxy();
+    }
+
+    /**
+     * Returns the SSL configuration for connections created by this engine.
+     * We cannot reuse HTTPS connections if the socket factory has changed.
+     */
+    protected SSLSocketFactory getSslSocketFactory() {
+        return null;
+    }
+
+    protected final String getDefaultUserAgent() {
+        String agent = System.getProperty("http.agent");
+        return agent != null ? agent : ("Java" + System.getProperty("java.version"));
+    }
+
+    protected final String getOriginAddress(URL url) {
+        int port = url.getPort();
+        String result = url.getHost();
+        if (port > 0 && port != policy.getDefaultPort()) {
+            result = result + ":" + port;
+        }
+        return result;
+    }
+
+    protected boolean requiresTunnel() {
+        return false;
+    }
+
+    /**
+     * Flushes the remaining request header and body, parses the HTTP response
+     * headers and starts reading the HTTP response body if it exists.
+     */
+    public final void readResponse() throws IOException {
+        if (hasResponse()) {
+            return;
+        }
+
+        if (responseSource == null) {
+            throw new IllegalStateException("readResponse() without sendRequest()");
+        }
+
+        if (!responseSource.requiresConnection()) {
+            return;
+        }
+
+        if (sentRequestMillis == -1) {
+            if (requestBodyOut instanceof RetryableOutputStream) {
+                int contentLength = ((RetryableOutputStream) requestBodyOut).contentLength();
+                requestHeaders.setContentLength(contentLength);
+            }
+            transport.writeRequestHeaders();
+        }
+
+        if (requestBodyOut != null) {
+            requestBodyOut.close();
+            if (requestBodyOut instanceof RetryableOutputStream) {
+                transport.writeRequestBody((RetryableOutputStream) requestBodyOut);
+            }
+        }
+
+        transport.flushRequest();
+
+        responseHeaders = transport.readResponseHeaders();
+        responseHeaders.setLocalTimestamps(sentRequestMillis, System.currentTimeMillis());
+
+        if (responseSource == ResponseSource.CONDITIONAL_CACHE) {
+            if (cachedResponseHeaders.validate(responseHeaders)) {
+                release(true);
+                ResponseHeaders combinedHeaders = cachedResponseHeaders.combine(responseHeaders);
+                setResponse(combinedHeaders, cachedResponseBody);
+                if (responseCache instanceof ExtendedResponseCache) {
+                    ExtendedResponseCache httpResponseCache = (ExtendedResponseCache) responseCache;
+                    httpResponseCache.trackConditionalCacheHit();
+                    httpResponseCache.update(cacheResponse, getHttpConnectionToCache());
+                }
+                return;
+            } else {
+                IoUtils.closeQuietly(cachedResponseBody);
+            }
+        }
+
+        if (hasResponseBody()) {
+            maybeCache(); // reentrant. this calls into user code which may call back into this!
+        }
+
+        initContentStream(transport.getTransferStream(cacheRequest));
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpResponseCache.java b/src/main/java/libcore/net/http/HttpResponseCache.java
new file mode 100644
index 0000000..13d540e
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpResponseCache.java
@@ -0,0 +1,599 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import com.squareup.okhttp.OkHttpConnection;
+import com.squareup.okhttp.OkHttpsConnection;
+import java.io.BufferedInputStream;
+import java.io.BufferedWriter;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ResponseCache;
+import java.net.SecureCacheResponse;
+import java.net.URI;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateEncodingException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import libcore.io.Base64;
+import libcore.io.DiskLruCache;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
+import libcore.util.Charsets;
+import libcore.util.ExtendedResponseCache;
+import libcore.util.IntegralToString;
+import libcore.util.ResponseSource;
+
+/**
+ * Cache responses in a directory on the file system. Most clients should use
+ * {@code android.net.HttpResponseCache}, the stable, documented front end for
+ * this.
+ */
+public final class HttpResponseCache extends ResponseCache implements ExtendedResponseCache {
+    // TODO: add APIs to iterate the cache?
+    private static final int VERSION = 201105;
+    private static final int ENTRY_METADATA = 0;
+    private static final int ENTRY_BODY = 1;
+    private static final int ENTRY_COUNT = 2;
+
+    private final DiskLruCache cache;
+
+    /* read and write statistics, all guarded by 'this' */
+    private int writeSuccessCount;
+    private int writeAbortCount;
+    private int networkCount;
+    private int hitCount;
+    private int requestCount;
+
+    public HttpResponseCache(File directory, long maxSize) throws IOException {
+        cache = DiskLruCache.open(directory, VERSION, ENTRY_COUNT, maxSize);
+    }
+
+    private String uriToKey(URI uri) {
+        try {
+            MessageDigest messageDigest = MessageDigest.getInstance("MD5");
+            byte[] md5bytes = messageDigest.digest(uri.toString().getBytes("UTF-8"));
+            return IntegralToString.bytesToHexString(md5bytes, false);
+        } catch (NoSuchAlgorithmException e) {
+            throw new AssertionError(e);
+        } catch (UnsupportedEncodingException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    @Override public CacheResponse get(URI uri, String requestMethod,
+            Map<String, List<String>> requestHeaders) {
+        String key = uriToKey(uri);
+        DiskLruCache.Snapshot snapshot;
+        Entry entry;
+        try {
+            snapshot = cache.get(key);
+            if (snapshot == null) {
+                return null;
+            }
+            entry = new Entry(new BufferedInputStream(snapshot.getInputStream(ENTRY_METADATA)));
+        } catch (IOException e) {
+            // Give up because the cache cannot be read.
+            return null;
+        }
+
+        if (!entry.matches(uri, requestMethod, requestHeaders)) {
+            snapshot.close();
+            return null;
+        }
+
+        return entry.isHttps()
+                ? new EntrySecureCacheResponse(entry, snapshot)
+                : new EntryCacheResponse(entry, snapshot);
+    }
+
+    @Override public CacheRequest put(URI uri, URLConnection urlConnection) throws IOException {
+        if (!(urlConnection instanceof OkHttpConnection)) {
+            return null;
+        }
+
+        OkHttpConnection httpConnection = (OkHttpConnection) urlConnection;
+        String requestMethod = httpConnection.getRequestMethod();
+        String key = uriToKey(uri);
+
+        if (requestMethod.equals(HttpEngine.POST)
+                || requestMethod.equals(HttpEngine.PUT)
+                || requestMethod.equals(HttpEngine.DELETE)) {
+            try {
+                cache.remove(key);
+            } catch (IOException ignored) {
+                // The cache cannot be written.
+            }
+            return null;
+        } else if (!requestMethod.equals(HttpEngine.GET)) {
+            /*
+             * Don't cache non-GET responses. We're technically allowed to cache
+             * HEAD requests and some POST requests, but the complexity of doing
+             * so is high and the benefit is low.
+             */
+            return null;
+        }
+
+        HttpEngine httpEngine = getHttpEngine(httpConnection);
+        if (httpEngine == null) {
+            // Don't cache unless the HTTP implementation is ours.
+            return null;
+        }
+
+        ResponseHeaders response = httpEngine.getResponseHeaders();
+        if (response.hasVaryAll()) {
+            return null;
+        }
+
+        RawHeaders varyHeaders = httpEngine.getRequestHeaders().getHeaders().getAll(
+                response.getVaryFields());
+        Entry entry = new Entry(uri, varyHeaders, httpConnection);
+        DiskLruCache.Editor editor = null;
+        try {
+            editor = cache.edit(key);
+            if (editor == null) {
+                return null;
+            }
+            entry.writeTo(editor);
+            return new CacheRequestImpl(editor);
+        } catch (IOException e) {
+            abortQuietly(editor);
+            return null;
+        }
+    }
+
+    /**
+     * Handles a conditional request hit by updating the stored cache response
+     * with the headers from {@code httpConnection}. The cached response body is
+     * not updated. If the stored response has changed since {@code
+     * conditionalCacheHit} was returned, this does nothing.
+     */
+    @Override
+    public void update(CacheResponse conditionalCacheHit, OkHttpConnection httpConnection) {
+        HttpEngine httpEngine = getHttpEngine(httpConnection);
+        URI uri = httpEngine.getUri();
+        ResponseHeaders response = httpEngine.getResponseHeaders();
+        RawHeaders varyHeaders = httpEngine.getRequestHeaders().getHeaders()
+                .getAll(response.getVaryFields());
+        Entry entry = new Entry(uri, varyHeaders, httpConnection);
+        DiskLruCache.Snapshot snapshot = (conditionalCacheHit instanceof EntryCacheResponse)
+                ? ((EntryCacheResponse) conditionalCacheHit).snapshot
+                : ((EntrySecureCacheResponse) conditionalCacheHit).snapshot;
+        DiskLruCache.Editor editor = null;
+        try {
+            editor = snapshot.edit(); // returns null if snapshot is not current
+            if (editor != null) {
+                entry.writeTo(editor);
+                editor.commit();
+            }
+        } catch (IOException e) {
+            abortQuietly(editor);
+        }
+    }
+
+    private void abortQuietly(DiskLruCache.Editor editor) {
+        // Give up because the cache cannot be written.
+        try {
+            if (editor != null) {
+                editor.abort();
+            }
+        } catch (IOException ignored) {
+        }
+    }
+
+    private HttpEngine getHttpEngine(URLConnection httpConnection) {
+        if (httpConnection instanceof HttpURLConnectionImpl) {
+            return ((HttpURLConnectionImpl) httpConnection).getHttpEngine();
+        } else if (httpConnection instanceof HttpsURLConnectionImpl) {
+            return ((HttpsURLConnectionImpl) httpConnection).getHttpEngine();
+        } else {
+            return null;
+        }
+    }
+
+    public DiskLruCache getCache() {
+        return cache;
+    }
+
+    public synchronized int getWriteAbortCount() {
+        return writeAbortCount;
+    }
+
+    public synchronized int getWriteSuccessCount() {
+        return writeSuccessCount;
+    }
+
+    public synchronized void trackResponse(ResponseSource source) {
+        requestCount++;
+
+        switch (source) {
+        case CACHE:
+            hitCount++;
+            break;
+        case CONDITIONAL_CACHE:
+        case NETWORK:
+            networkCount++;
+            break;
+        }
+    }
+
+    public synchronized void trackConditionalCacheHit() {
+        hitCount++;
+    }
+
+    public synchronized int getNetworkCount() {
+        return networkCount;
+    }
+
+    public synchronized int getHitCount() {
+        return hitCount;
+    }
+
+    public synchronized int getRequestCount() {
+        return requestCount;
+    }
+
+    private final class CacheRequestImpl extends CacheRequest {
+        private final DiskLruCache.Editor editor;
+        private OutputStream cacheOut;
+        private boolean done;
+        private OutputStream body;
+
+        public CacheRequestImpl(final DiskLruCache.Editor editor) throws IOException {
+            this.editor = editor;
+            this.cacheOut = editor.newOutputStream(ENTRY_BODY);
+            this.body = new FilterOutputStream(cacheOut) {
+                @Override public void close() throws IOException {
+                    synchronized (HttpResponseCache.this) {
+                        if (done) {
+                            return;
+                        }
+                        done = true;
+                        writeSuccessCount++;
+                    }
+                    super.close();
+                    editor.commit();
+                }
+            };
+        }
+
+        @Override public void abort() {
+            synchronized (HttpResponseCache.this) {
+                if (done) {
+                    return;
+                }
+                done = true;
+                writeAbortCount++;
+            }
+            IoUtils.closeQuietly(cacheOut);
+            try {
+                editor.abort();
+            } catch (IOException ignored) {
+            }
+        }
+
+        @Override public OutputStream getBody() throws IOException {
+            return body;
+        }
+    }
+
+    private static final class Entry {
+        private final String uri;
+        private final RawHeaders varyHeaders;
+        private final String requestMethod;
+        private final RawHeaders responseHeaders;
+        private final String cipherSuite;
+        private final Certificate[] peerCertificates;
+        private final Certificate[] localCertificates;
+
+        /*
+         * Reads an entry from an input stream. A typical entry looks like this:
+         *   http://google.com/foo
+         *   GET
+         *   2
+         *   Accept-Language: fr-CA
+         *   Accept-Charset: UTF-8
+         *   HTTP/1.1 200 OK
+         *   3
+         *   Content-Type: image/png
+         *   Content-Length: 100
+         *   Cache-Control: max-age=600
+         *
+         * A typical HTTPS file looks like this:
+         *   https://google.com/foo
+         *   GET
+         *   2
+         *   Accept-Language: fr-CA
+         *   Accept-Charset: UTF-8
+         *   HTTP/1.1 200 OK
+         *   3
+         *   Content-Type: image/png
+         *   Content-Length: 100
+         *   Cache-Control: max-age=600
+         *
+         *   AES_256_WITH_MD5
+         *   2
+         *   base64-encoded peerCertificate[0]
+         *   base64-encoded peerCertificate[1]
+         *   -1
+         *
+         * The file is newline separated. The first two lines are the URL and
+         * the request method. Next is the number of HTTP Vary request header
+         * lines, followed by those lines.
+         *
+         * Next is the response status line, followed by the number of HTTP
+         * response header lines, followed by those lines.
+         *
+         * HTTPS responses also contain SSL session information. This begins
+         * with a blank line, and then a line containing the cipher suite. Next
+         * is the length of the peer certificate chain. These certificates are
+         * base64-encoded and appear each on their own line. The next line
+         * contains the length of the local certificate chain. These
+         * certificates are also base64-encoded and appear each on their own
+         * line. A length of -1 is used to encode a null array.
+         */
+        public Entry(InputStream in) throws IOException {
+            try {
+                uri = Streams.readAsciiLine(in);
+                requestMethod = Streams.readAsciiLine(in);
+                varyHeaders = new RawHeaders();
+                int varyRequestHeaderLineCount = readInt(in);
+                for (int i = 0; i < varyRequestHeaderLineCount; i++) {
+                    varyHeaders.addLine(Streams.readAsciiLine(in));
+                }
+
+                responseHeaders = new RawHeaders();
+                responseHeaders.setStatusLine(Streams.readAsciiLine(in));
+                int responseHeaderLineCount = readInt(in);
+                for (int i = 0; i < responseHeaderLineCount; i++) {
+                    responseHeaders.addLine(Streams.readAsciiLine(in));
+                }
+
+                if (isHttps()) {
+                    String blank = Streams.readAsciiLine(in);
+                    if (blank.length() != 0) {
+                        throw new IOException("expected \"\" but was \"" + blank + "\"");
+                    }
+                    cipherSuite = Streams.readAsciiLine(in);
+                    peerCertificates = readCertArray(in);
+                    localCertificates = readCertArray(in);
+                } else {
+                    cipherSuite = null;
+                    peerCertificates = null;
+                    localCertificates = null;
+                }
+            } finally {
+                in.close();
+            }
+        }
+
+        public Entry(URI uri, RawHeaders varyHeaders, OkHttpConnection httpConnection) {
+            this.uri = uri.toString();
+            this.varyHeaders = varyHeaders;
+            this.requestMethod = httpConnection.getRequestMethod();
+            this.responseHeaders = RawHeaders.fromMultimap(httpConnection.getHeaderFields());
+
+            if (isHttps()) {
+                OkHttpsConnection httpsConnection
+                        = (OkHttpsConnection) httpConnection;
+                cipherSuite = httpsConnection.getCipherSuite();
+                Certificate[] peerCertificatesNonFinal = null;
+                try {
+                    peerCertificatesNonFinal = httpsConnection.getServerCertificates();
+                } catch (SSLPeerUnverifiedException ignored) {
+                }
+                peerCertificates = peerCertificatesNonFinal;
+                localCertificates = httpsConnection.getLocalCertificates();
+            } else {
+                cipherSuite = null;
+                peerCertificates = null;
+                localCertificates = null;
+            }
+        }
+
+        public void writeTo(DiskLruCache.Editor editor) throws IOException {
+            OutputStream out = editor.newOutputStream(0);
+            Writer writer = new BufferedWriter(new OutputStreamWriter(out, Charsets.UTF_8));
+
+            writer.write(uri + '\n');
+            writer.write(requestMethod + '\n');
+            writer.write(Integer.toString(varyHeaders.length()) + '\n');
+            for (int i = 0; i < varyHeaders.length(); i++) {
+                writer.write(varyHeaders.getFieldName(i) + ": "
+                        + varyHeaders.getValue(i) + '\n');
+            }
+
+            writer.write(responseHeaders.getStatusLine() + '\n');
+            writer.write(Integer.toString(responseHeaders.length()) + '\n');
+            for (int i = 0; i < responseHeaders.length(); i++) {
+                writer.write(responseHeaders.getFieldName(i) + ": "
+                        + responseHeaders.getValue(i) + '\n');
+            }
+
+            if (isHttps()) {
+                writer.write('\n');
+                writer.write(cipherSuite + '\n');
+                writeCertArray(writer, peerCertificates);
+                writeCertArray(writer, localCertificates);
+            }
+            writer.close();
+        }
+
+        private boolean isHttps() {
+            return uri.startsWith("https://");
+        }
+
+        private int readInt(InputStream in) throws IOException {
+            String intString = Streams.readAsciiLine(in);
+            try {
+                return Integer.parseInt(intString);
+            } catch (NumberFormatException e) {
+                throw new IOException("expected an int but was \"" + intString + "\"");
+            }
+        }
+
+        private Certificate[] readCertArray(InputStream in) throws IOException {
+            int length = readInt(in);
+            if (length == -1) {
+                return null;
+            }
+            try {
+                CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
+                Certificate[] result = new Certificate[length];
+                for (int i = 0; i < result.length; i++) {
+                    String line = Streams.readAsciiLine(in);
+                    byte[] bytes = Base64.decode(line.getBytes("US-ASCII"));
+                    result[i] = certificateFactory.generateCertificate(
+                            new ByteArrayInputStream(bytes));
+                }
+                return result;
+            } catch (CertificateException e) {
+                throw new IOException(e);
+            }
+        }
+
+        private void writeCertArray(Writer writer, Certificate[] certificates) throws IOException {
+            if (certificates == null) {
+                writer.write("-1\n");
+                return;
+            }
+            try {
+                writer.write(Integer.toString(certificates.length) + '\n');
+                for (Certificate certificate : certificates) {
+                    byte[] bytes = certificate.getEncoded();
+                    String line = Base64.encode(bytes);
+                    writer.write(line + '\n');
+                }
+            } catch (CertificateEncodingException e) {
+                throw new IOException(e);
+            }
+        }
+
+        public boolean matches(URI uri, String requestMethod,
+                Map<String, List<String>> requestHeaders) {
+            return this.uri.equals(uri.toString())
+                    && this.requestMethod.equals(requestMethod)
+                    && new ResponseHeaders(uri, responseHeaders)
+                            .varyMatches(varyHeaders.toMultimap(), requestHeaders);
+        }
+    }
+
+    /**
+     * Returns an input stream that reads the body of a snapshot, closing the
+     * snapshot when the stream is closed.
+     */
+    private static InputStream newBodyInputStream(final DiskLruCache.Snapshot snapshot) {
+        return new FilterInputStream(snapshot.getInputStream(ENTRY_BODY)) {
+            @Override public void close() throws IOException {
+                snapshot.close();
+                super.close();
+            }
+        };
+    }
+
+    static class EntryCacheResponse extends CacheResponse {
+        private final Entry entry;
+        private final DiskLruCache.Snapshot snapshot;
+        private final InputStream in;
+
+        public EntryCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
+            this.entry = entry;
+            this.snapshot = snapshot;
+            this.in = newBodyInputStream(snapshot);
+        }
+
+        @Override public Map<String, List<String>> getHeaders() {
+            return entry.responseHeaders.toMultimap();
+        }
+
+        @Override public InputStream getBody() {
+            return in;
+        }
+    }
+
+    static class EntrySecureCacheResponse extends SecureCacheResponse {
+        private final Entry entry;
+        private final DiskLruCache.Snapshot snapshot;
+        private final InputStream in;
+
+        public EntrySecureCacheResponse(Entry entry, DiskLruCache.Snapshot snapshot) {
+            this.entry = entry;
+            this.snapshot = snapshot;
+            this.in = newBodyInputStream(snapshot);
+        }
+
+        @Override public Map<String, List<String>> getHeaders() {
+            return entry.responseHeaders.toMultimap();
+        }
+
+        @Override public InputStream getBody() {
+            return in;
+        }
+
+        @Override public String getCipherSuite() {
+            return entry.cipherSuite;
+        }
+
+        @Override public List<Certificate> getServerCertificateChain()
+                throws SSLPeerUnverifiedException {
+            if (entry.peerCertificates == null || entry.peerCertificates.length == 0) {
+                throw new SSLPeerUnverifiedException(null);
+            }
+            return Arrays.asList(entry.peerCertificates.clone());
+        }
+
+        @Override public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+            if (entry.peerCertificates == null || entry.peerCertificates.length == 0) {
+                throw new SSLPeerUnverifiedException(null);
+            }
+            return ((X509Certificate) entry.peerCertificates[0]).getSubjectX500Principal();
+        }
+
+        @Override public List<Certificate> getLocalCertificateChain() {
+            if (entry.localCertificates == null || entry.localCertificates.length == 0) {
+                return null;
+            }
+            return Arrays.asList(entry.localCertificates.clone());
+        }
+
+        @Override public Principal getLocalPrincipal() {
+            if (entry.localCertificates == null || entry.localCertificates.length == 0) {
+                return null;
+            }
+            return ((X509Certificate) entry.localCertificates[0]).getSubjectX500Principal();
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpTransport.java b/src/main/java/libcore/net/http/HttpTransport.java
new file mode 100644
index 0000000..d307349
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpTransport.java
@@ -0,0 +1,595 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheRequest;
+import java.net.CookieHandler;
+import java.net.URL;
+import libcore.io.Streams;
+import libcore.util.Libcore;
+
+final class HttpTransport implements Transport {
+    /**
+     * The maximum number of bytes to buffer when sending headers and a request
+     * body. When the headers and body can be sent in a single write, the
+     * request completes sooner. In one WiFi benchmark, using a large enough
+     * buffer sped up some uploads by half.
+     */
+    private static final int MAX_REQUEST_BUFFER_LENGTH = 32768;
+
+    private final HttpEngine httpEngine;
+    private final InputStream socketIn;
+    private final OutputStream socketOut;
+
+    /**
+     * This stream buffers the request headers and the request body when their
+     * combined size is less than MAX_REQUEST_BUFFER_LENGTH. By combining them
+     * we can save socket writes, which in turn saves a packet transmission.
+     * This is socketOut if the request size is large or unknown.
+     */
+    private OutputStream requestOut;
+
+    public HttpTransport(HttpEngine httpEngine,
+            OutputStream outputStream, InputStream inputStream) {
+        this.httpEngine = httpEngine;
+        this.socketOut = outputStream;
+        this.requestOut = outputStream;
+        this.socketIn = inputStream;
+    }
+
+    @Override public OutputStream createRequestBody() throws IOException {
+        boolean chunked = httpEngine.requestHeaders.isChunked();
+        if (!chunked
+                && httpEngine.policy.getChunkLength() > 0
+                && httpEngine.connection.httpMinorVersion != 0) {
+            httpEngine.requestHeaders.setChunked();
+            chunked = true;
+        }
+
+        // Stream a request body of unknown length.
+        if (chunked) {
+            int chunkLength = httpEngine.policy.getChunkLength();
+            if (chunkLength == -1) {
+                chunkLength = HttpEngine.DEFAULT_CHUNK_LENGTH;
+            }
+            writeRequestHeaders();
+            return new ChunkedOutputStream(requestOut, chunkLength);
+        }
+
+        // Stream a request body of a known length.
+        int fixedContentLength = httpEngine.policy.getFixedContentLength();
+        if (fixedContentLength != -1) {
+            httpEngine.requestHeaders.setContentLength(fixedContentLength);
+            writeRequestHeaders();
+            return new FixedLengthOutputStream(requestOut, fixedContentLength);
+        }
+
+        // Buffer a request body of a known length.
+        int contentLength = httpEngine.requestHeaders.getContentLength();
+        if (contentLength != -1) {
+            writeRequestHeaders();
+            return new RetryableOutputStream(contentLength);
+        }
+
+        // Buffer a request body of an unknown length. Don't write request
+        // headers until the entire body is ready; otherwise we can't set the
+        // Content-Length header correctly.
+        return new RetryableOutputStream();
+    }
+
+    @Override public void flushRequest() throws IOException {
+        requestOut.flush();
+        requestOut = socketOut;
+    }
+
+    @Override public void writeRequestBody(RetryableOutputStream requestBody) throws IOException {
+        requestBody.writeToSocket(requestOut);
+    }
+
+    /**
+     * Prepares the HTTP headers and sends them to the server.
+     *
+     * <p>For streaming requests with a body, headers must be prepared
+     * <strong>before</strong> the output stream has been written to. Otherwise
+     * the body would need to be buffered!
+     *
+     * <p>For non-streaming requests with a body, headers must be prepared
+     * <strong>after</strong> the output stream has been written to and closed.
+     * This ensures that the {@code Content-Length} header field receives the
+     * proper value.
+     */
+    public void writeRequestHeaders() throws IOException {
+        if (httpEngine.sentRequestMillis != -1) {
+            throw new IllegalStateException();
+        }
+        httpEngine.sentRequestMillis = System.currentTimeMillis();
+
+        int contentLength = httpEngine.requestHeaders.getContentLength();
+        RawHeaders headersToSend = getNetworkRequestHeaders();
+        byte[] bytes = headersToSend.toHeaderString().getBytes("ISO-8859-1");
+
+        if (contentLength != -1 && bytes.length + contentLength <= MAX_REQUEST_BUFFER_LENGTH) {
+            requestOut = new BufferedOutputStream(socketOut, bytes.length + contentLength);
+        }
+
+        requestOut.write(bytes);
+    }
+
+    private RawHeaders getNetworkRequestHeaders() {
+        return httpEngine.method == HttpEngine.CONNECT
+                ? getTunnelNetworkRequestHeaders()
+                : httpEngine.requestHeaders.getHeaders();
+    }
+
+    /**
+     * If we're establishing an HTTPS tunnel with CONNECT (RFC 2817 5.2), send
+     * only the minimum set of headers. This avoids sending potentially
+     * sensitive data like HTTP cookies to the proxy unencrypted.
+     */
+    private RawHeaders getTunnelNetworkRequestHeaders() {
+        RequestHeaders privateHeaders = httpEngine.requestHeaders;
+        URL url = httpEngine.policy.getURL();
+
+        RawHeaders result = new RawHeaders();
+        result.setStatusLine("CONNECT " + url.getHost() + ":" + Libcore.getEffectivePort(url)
+                + " HTTP/1.1");
+
+        // Always set Host and User-Agent.
+        String host = privateHeaders.getHost();
+        if (host == null) {
+            host = httpEngine.getOriginAddress(url);
+        }
+        result.set("Host", host);
+
+        String userAgent = privateHeaders.getUserAgent();
+        if (userAgent == null) {
+            userAgent = httpEngine.getDefaultUserAgent();
+        }
+        result.set("User-Agent", userAgent);
+
+        // Copy over the Proxy-Authorization header if it exists.
+        String proxyAuthorization = privateHeaders.getProxyAuthorization();
+        if (proxyAuthorization != null) {
+            result.set("Proxy-Authorization", proxyAuthorization);
+        }
+
+        // Always set the Proxy-Connection to Keep-Alive for the benefit of
+        // HTTP/1.0 proxies like Squid.
+        result.set("Proxy-Connection", "Keep-Alive");
+        return result;
+    }
+
+    @Override public ResponseHeaders readResponseHeaders() throws IOException {
+        RawHeaders headers;
+        do {
+            headers = new RawHeaders();
+            headers.setStatusLine(Streams.readAsciiLine(socketIn));
+            httpEngine.connection.httpMinorVersion = headers.getHttpMinorVersion();
+            readHeaders(headers);
+        } while (headers.getResponseCode() == HttpEngine.HTTP_CONTINUE);
+        return new ResponseHeaders(httpEngine.uri, headers);
+    }
+
+    /**
+     * Reads headers or trailers and updates the cookie store.
+     */
+    private void readHeaders(RawHeaders headers) throws IOException {
+        // parse the result headers until the first blank line
+        String line;
+        while ((line = Streams.readAsciiLine(socketIn)).length() != 0) {
+            headers.addLine(line);
+        }
+
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler != null) {
+            cookieHandler.put(httpEngine.uri, headers.toMultimap());
+        }
+    }
+
+    public boolean makeReusable(OutputStream requestBodyOut, InputStream responseBodyIn) {
+        // We cannot reuse sockets that have incomplete output.
+        if (requestBodyOut != null && !((AbstractHttpOutputStream) requestBodyOut).closed) {
+            return false;
+        }
+
+        // If the headers specify that the connection shouldn't be reused, don't reuse it.
+        if (httpEngine.requestHeaders.hasConnectionClose()
+                || (httpEngine.responseHeaders != null
+                && httpEngine.responseHeaders.hasConnectionClose())) {
+            return false;
+        }
+
+        if (responseBodyIn instanceof UnknownLengthHttpInputStream) {
+            return false;
+        }
+
+        if (responseBodyIn != null) {
+            // Discard the response body before the connection can be reused.
+            try {
+                Streams.skipAll(responseBodyIn);
+            } catch (IOException e) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override public InputStream getTransferStream(CacheRequest cacheRequest) throws IOException {
+        if (!httpEngine.hasResponseBody()) {
+            return new FixedLengthInputStream(socketIn, cacheRequest, httpEngine, 0);
+        }
+
+        if (httpEngine.responseHeaders.isChunked()) {
+            return new ChunkedInputStream(socketIn, cacheRequest, this);
+        }
+
+        if (httpEngine.responseHeaders.getContentLength() != -1) {
+            return new FixedLengthInputStream(socketIn, cacheRequest, httpEngine,
+                    httpEngine.responseHeaders.getContentLength());
+        }
+
+        /*
+         * Wrap the input stream from the HttpConnection (rather than
+         * just returning "socketIn" directly here), so that we can control
+         * its use after the reference escapes.
+         */
+        return new UnknownLengthHttpInputStream(socketIn, cacheRequest, httpEngine);
+    }
+
+    /**
+     * An HTTP body with a fixed length known in advance.
+     */
+    private static final class FixedLengthOutputStream extends AbstractHttpOutputStream {
+        private final OutputStream socketOut;
+        private int bytesRemaining;
+
+        private FixedLengthOutputStream(OutputStream socketOut, int bytesRemaining) {
+            this.socketOut = socketOut;
+            this.bytesRemaining = bytesRemaining;
+        }
+
+        @Override public void write(byte[] buffer, int offset, int count) throws IOException {
+            checkNotClosed();
+            Libcore.checkOffsetAndCount(buffer.length, offset, count);
+            if (count > bytesRemaining) {
+                throw new IOException("expected " + bytesRemaining
+                        + " bytes but received " + count);
+            }
+            socketOut.write(buffer, offset, count);
+            bytesRemaining -= count;
+        }
+
+        @Override public void flush() throws IOException {
+            if (closed) {
+                return; // don't throw; this stream might have been closed on the caller's behalf
+            }
+            socketOut.flush();
+        }
+
+        @Override public void close() throws IOException {
+            if (closed) {
+                return;
+            }
+            closed = true;
+            if (bytesRemaining > 0) {
+                throw new IOException("unexpected end of stream");
+            }
+        }
+    }
+
+    /**
+     * An HTTP body with alternating chunk sizes and chunk bodies. Chunks are
+     * buffered until {@code maxChunkLength} bytes are ready, at which point the
+     * chunk is written and the buffer is cleared.
+     */
+    private static final class ChunkedOutputStream extends AbstractHttpOutputStream {
+        private static final byte[] CRLF = {'\r', '\n'};
+        private static final byte[] HEX_DIGITS = {
+                '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+        };
+        private static final byte[] FINAL_CHUNK = new byte[] {'0', '\r', '\n', '\r', '\n'};
+
+        /** Scratch space for up to 8 hex digits, and then a constant CRLF. */
+        private final byte[] hex = {0, 0, 0, 0, 0, 0, 0, 0, '\r', '\n'};
+
+        private final OutputStream socketOut;
+        private final int maxChunkLength;
+        private final ByteArrayOutputStream bufferedChunk;
+
+        private ChunkedOutputStream(OutputStream socketOut, int maxChunkLength) {
+            this.socketOut = socketOut;
+            this.maxChunkLength = Math.max(1, dataLength(maxChunkLength));
+            this.bufferedChunk = new ByteArrayOutputStream(maxChunkLength);
+        }
+
+        /**
+         * Returns the amount of data that can be transmitted in a chunk whose total
+         * length (data+headers) is {@code dataPlusHeaderLength}. This is presumably
+         * useful to match sizes with wire-protocol packets.
+         */
+        private int dataLength(int dataPlusHeaderLength) {
+            int headerLength = 4; // "\r\n" after the size plus another "\r\n" after the data
+            for (int i = dataPlusHeaderLength - headerLength; i > 0; i >>= 4) {
+                headerLength++;
+            }
+            return dataPlusHeaderLength - headerLength;
+        }
+
+        @Override public synchronized void write(byte[] buffer, int offset, int count)
+                throws IOException {
+            checkNotClosed();
+            Libcore.checkOffsetAndCount(buffer.length, offset, count);
+
+            while (count > 0) {
+                int numBytesWritten;
+
+                if (bufferedChunk.size() > 0 || count < maxChunkLength) {
+                    // fill the buffered chunk and then maybe write that to the stream
+                    numBytesWritten = Math.min(count, maxChunkLength - bufferedChunk.size());
+                    // TODO: skip unnecessary copies from buffer->bufferedChunk?
+                    bufferedChunk.write(buffer, offset, numBytesWritten);
+                    if (bufferedChunk.size() == maxChunkLength) {
+                        writeBufferedChunkToSocket();
+                    }
+
+                } else {
+                    // write a single chunk of size maxChunkLength to the stream
+                    numBytesWritten = maxChunkLength;
+                    writeHex(numBytesWritten);
+                    socketOut.write(buffer, offset, numBytesWritten);
+                    socketOut.write(CRLF);
+                }
+
+                offset += numBytesWritten;
+                count -= numBytesWritten;
+            }
+        }
+
+        /**
+         * Equivalent to, but cheaper than writing Integer.toHexString().getBytes()
+         * followed by CRLF.
+         */
+        private void writeHex(int i) throws IOException {
+            int cursor = 8;
+            do {
+                hex[--cursor] = HEX_DIGITS[i & 0xf];
+            } while ((i >>>= 4) != 0);
+            socketOut.write(hex, cursor, hex.length - cursor);
+        }
+
+        @Override public synchronized void flush() throws IOException {
+            if (closed) {
+                return; // don't throw; this stream might have been closed on the caller's behalf
+            }
+            writeBufferedChunkToSocket();
+            socketOut.flush();
+        }
+
+        @Override public synchronized void close() throws IOException {
+            if (closed) {
+                return;
+            }
+            closed = true;
+            writeBufferedChunkToSocket();
+            socketOut.write(FINAL_CHUNK);
+        }
+
+        private void writeBufferedChunkToSocket() throws IOException {
+            int size = bufferedChunk.size();
+            if (size <= 0) {
+                return;
+            }
+
+            writeHex(size);
+            bufferedChunk.writeTo(socketOut);
+            bufferedChunk.reset();
+            socketOut.write(CRLF);
+        }
+    }
+
+    /**
+     * An HTTP body with a fixed length specified in advance.
+     */
+    private static class FixedLengthInputStream extends AbstractHttpInputStream {
+        private int bytesRemaining;
+
+        public FixedLengthInputStream(InputStream is, CacheRequest cacheRequest,
+                HttpEngine httpEngine, int length) throws IOException {
+            super(is, httpEngine, cacheRequest);
+            bytesRemaining = length;
+            if (bytesRemaining == 0) {
+                endOfInput(true);
+            }
+        }
+
+        @Override public int read(byte[] buffer, int offset, int count) throws IOException {
+            Libcore.checkOffsetAndCount(buffer.length, offset, count);
+            checkNotClosed();
+            if (bytesRemaining == 0) {
+                return -1;
+            }
+            int read = in.read(buffer, offset, Math.min(count, bytesRemaining));
+            if (read == -1) {
+                unexpectedEndOfInput(); // the server didn't supply the promised content length
+                throw new IOException("unexpected end of stream");
+            }
+            bytesRemaining -= read;
+            cacheWrite(buffer, offset, read);
+            if (bytesRemaining == 0) {
+                endOfInput(true);
+            }
+            return read;
+        }
+
+        @Override public int available() throws IOException {
+            checkNotClosed();
+            return bytesRemaining == 0 ? 0 : Math.min(in.available(), bytesRemaining);
+        }
+
+        @Override public void close() throws IOException {
+            if (closed) {
+                return;
+            }
+            closed = true;
+            if (bytesRemaining != 0) {
+                unexpectedEndOfInput();
+            }
+        }
+    }
+
+    /**
+     * An HTTP body with alternating chunk sizes and chunk bodies.
+     */
+    private static class ChunkedInputStream extends AbstractHttpInputStream {
+        private static final int MIN_LAST_CHUNK_LENGTH = "\r\n0\r\n\r\n".length();
+        private static final int NO_CHUNK_YET = -1;
+        private final HttpTransport transport;
+        private int bytesRemainingInChunk = NO_CHUNK_YET;
+        private boolean hasMoreChunks = true;
+
+        ChunkedInputStream(InputStream is, CacheRequest cacheRequest,
+                HttpTransport transport) throws IOException {
+            super(is, transport.httpEngine, cacheRequest);
+            this.transport = transport;
+        }
+
+        @Override public int read(byte[] buffer, int offset, int count) throws IOException {
+            Libcore.checkOffsetAndCount(buffer.length, offset, count);
+            checkNotClosed();
+
+            if (!hasMoreChunks) {
+                return -1;
+            }
+            if (bytesRemainingInChunk == 0 || bytesRemainingInChunk == NO_CHUNK_YET) {
+                readChunkSize();
+                if (!hasMoreChunks) {
+                    return -1;
+                }
+            }
+            int read = in.read(buffer, offset, Math.min(count, bytesRemainingInChunk));
+            if (read == -1) {
+                unexpectedEndOfInput(); // the server didn't supply the promised chunk length
+                throw new IOException("unexpected end of stream");
+            }
+            bytesRemainingInChunk -= read;
+            cacheWrite(buffer, offset, read);
+
+            /*
+            * If we're at the end of a chunk and the next chunk size is readable,
+            * read it! Reading the last chunk causes the underlying connection to
+            * be recycled and we want to do that as early as possible. Otherwise
+            * self-delimiting streams like gzip will never be recycled.
+            * http://code.google.com/p/android/issues/detail?id=7059
+            */
+            if (bytesRemainingInChunk == 0 && in.available() >= MIN_LAST_CHUNK_LENGTH) {
+                readChunkSize();
+            }
+
+            return read;
+        }
+
+        private void readChunkSize() throws IOException {
+            // read the suffix of the previous chunk
+            if (bytesRemainingInChunk != NO_CHUNK_YET) {
+                Streams.readAsciiLine(in);
+            }
+            String chunkSizeString = Streams.readAsciiLine(in);
+            int index = chunkSizeString.indexOf(";");
+            if (index != -1) {
+                chunkSizeString = chunkSizeString.substring(0, index);
+            }
+            try {
+                bytesRemainingInChunk = Integer.parseInt(chunkSizeString.trim(), 16);
+            } catch (NumberFormatException e) {
+                throw new IOException("Expected a hex chunk size, but was " + chunkSizeString);
+            }
+            if (bytesRemainingInChunk == 0) {
+                hasMoreChunks = false;
+                transport.readHeaders(httpEngine.responseHeaders.getHeaders());
+                endOfInput(true);
+            }
+        }
+
+        @Override public int available() throws IOException {
+            checkNotClosed();
+            if (!hasMoreChunks || bytesRemainingInChunk == NO_CHUNK_YET) {
+                return 0;
+            }
+            return Math.min(in.available(), bytesRemainingInChunk);
+        }
+
+        @Override public void close() throws IOException {
+            if (closed) {
+                return;
+            }
+
+            closed = true;
+            if (hasMoreChunks) {
+                unexpectedEndOfInput();
+            }
+        }
+    }
+
+    /**
+     * An HTTP payload terminated by the end of the socket stream.
+     */
+    private static final class UnknownLengthHttpInputStream extends AbstractHttpInputStream {
+        private boolean inputExhausted;
+
+        private UnknownLengthHttpInputStream(InputStream is, CacheRequest cacheRequest,
+                HttpEngine httpEngine) throws IOException {
+            super(is, httpEngine, cacheRequest);
+        }
+
+        @Override public int read(byte[] buffer, int offset, int count) throws IOException {
+            Libcore.checkOffsetAndCount(buffer.length, offset, count);
+            checkNotClosed();
+            if (in == null || inputExhausted) {
+                return -1;
+            }
+            int read = in.read(buffer, offset, count);
+            if (read == -1) {
+                inputExhausted = true;
+                endOfInput(false);
+                return -1;
+            }
+            cacheWrite(buffer, offset, read);
+            return read;
+        }
+
+        @Override public int available() throws IOException {
+            checkNotClosed();
+            return in == null ? 0 : in.available();
+        }
+
+        @Override public void close() throws IOException {
+            if (closed) {
+                return;
+            }
+            closed = true;
+            if (!inputExhausted) {
+                unexpectedEndOfInput();
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpURLConnectionImpl.java b/src/main/java/libcore/net/http/HttpURLConnectionImpl.java
new file mode 100644
index 0000000..99a6ac4
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpURLConnectionImpl.java
@@ -0,0 +1,513 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import com.squareup.okhttp.OkHttpConnection;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Authenticator;
+import java.net.HttpRetryException;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.PasswordAuthentication;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.security.Permission;
+import java.util.List;
+import java.util.Map;
+import libcore.io.Base64;
+import libcore.util.Libcore;
+
+/**
+ * This implementation uses HttpEngine to send requests and receive responses.
+ * This class may use multiple HttpEngines to follow redirects, authentication
+ * retries, etc. to retrieve the final response body.
+ *
+ * <h3>What does 'connected' mean?</h3>
+ * This class inherits a {@code connected} field from the superclass. That field
+ * is <strong>not</strong> used to indicate not whether this URLConnection is
+ * currently connected. Instead, it indicates whether a connection has ever been
+ * attempted. Once a connection has been attempted, certain properties (request
+ * header fields, request method, etc.) are immutable. Test the {@code
+ * connection} field on this class for null/non-null to determine of an instance
+ * is currently connected to a server.
+ */
+public class HttpURLConnectionImpl extends OkHttpConnection {
+    /**
+     * HTTP 1.1 doesn't specify how many redirects to follow, but HTTP/1.0
+     * recommended 5. http://www.w3.org/Protocols/HTTP/1.0/spec.html#Code3xx
+     */
+    private static final int MAX_REDIRECTS = 5;
+
+    private final int defaultPort;
+
+    private Proxy proxy;
+
+    private final RawHeaders rawRequestHeaders = new RawHeaders();
+
+    private int redirectionCount;
+
+    protected IOException httpEngineFailure;
+    protected HttpEngine httpEngine;
+
+    public HttpURLConnectionImpl(URL url, int port) {
+        super(url);
+        defaultPort = port;
+    }
+
+    public HttpURLConnectionImpl(URL url, int port, Proxy proxy) {
+        this(url, port);
+        this.proxy = proxy;
+    }
+
+    @Override public final void connect() throws IOException {
+        initHttpEngine();
+        try {
+            httpEngine.sendRequest();
+        } catch (IOException e) {
+            httpEngineFailure = e;
+            throw e;
+        }
+    }
+
+    @Override public final void disconnect() {
+        // Calling disconnect() before a connection exists should have no effect.
+        if (httpEngine != null) {
+            httpEngine.release(false);
+        }
+    }
+
+    /**
+     * Returns an input stream from the server in the case of error such as the
+     * requested file (txt, htm, html) is not found on the remote server.
+     */
+    @Override public final InputStream getErrorStream() {
+        try {
+            HttpEngine response = getResponse();
+            if (response.hasResponseBody()
+                    && response.getResponseCode() >= HTTP_BAD_REQUEST) {
+                return response.getResponseBody();
+            }
+            return null;
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value of the field at {@code position}. Returns null if there
+     * are fewer than {@code position} headers.
+     */
+    @Override public final String getHeaderField(int position) {
+        try {
+            return getResponse().getResponseHeaders().getHeaders().getValue(position);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value of the field corresponding to the {@code fieldName}, or
+     * null if there is no such field. If the field has multiple values, the
+     * last value is returned.
+     */
+    @Override public final String getHeaderField(String fieldName) {
+        try {
+            RawHeaders rawHeaders = getResponse().getResponseHeaders().getHeaders();
+            return fieldName == null
+                    ? rawHeaders.getStatusLine()
+                    : rawHeaders.get(fieldName);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    @Override public final String getHeaderFieldKey(int position) {
+        try {
+            return getResponse().getResponseHeaders().getHeaders().getFieldName(position);
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    @Override public final Map<String, List<String>> getHeaderFields() {
+        try {
+            return getResponse().getResponseHeaders().getHeaders().toMultimap();
+        } catch (IOException e) {
+            return null;
+        }
+    }
+
+    @Override public final Map<String, List<String>> getRequestProperties() {
+        if (connected) {
+            throw new IllegalStateException(
+                    "Cannot access request header fields after connection is set");
+        }
+        return rawRequestHeaders.toMultimap();
+    }
+
+    @Override public final InputStream getInputStream() throws IOException {
+        if (!doInput) {
+            throw new ProtocolException("This protocol does not support input");
+        }
+
+        HttpEngine response = getResponse();
+
+        /*
+         * if the requested file does not exist, throw an exception formerly the
+         * Error page from the server was returned if the requested file was
+         * text/html this has changed to return FileNotFoundException for all
+         * file types
+         */
+        if (getResponseCode() >= HTTP_BAD_REQUEST) {
+            throw new FileNotFoundException(url.toString());
+        }
+
+        InputStream result = response.getResponseBody();
+        if (result == null) {
+            throw new IOException("No response body exists; responseCode=" + getResponseCode());
+        }
+        return result;
+    }
+
+    @Override public final OutputStream getOutputStream() throws IOException {
+        connect();
+
+        OutputStream result = httpEngine.getRequestBody();
+        if (result == null) {
+            throw new ProtocolException("method does not support a request body: " + method);
+        } else if (httpEngine.hasResponse()) {
+            throw new ProtocolException("cannot write request body after response has been read");
+        }
+
+        return result;
+    }
+
+    @Override public final Permission getPermission() throws IOException {
+        String connectToAddress = getConnectToHost() + ":" + getConnectToPort();
+        return new SocketPermission(connectToAddress, "connect, resolve");
+    }
+
+    private String getConnectToHost() {
+        return usingProxy()
+                ? ((InetSocketAddress) proxy.address()).getHostName()
+                : getURL().getHost();
+    }
+
+    private int getConnectToPort() {
+        int hostPort = usingProxy()
+                ? ((InetSocketAddress) proxy.address()).getPort()
+                : getURL().getPort();
+        return hostPort < 0 ? getDefaultPort() : hostPort;
+    }
+
+    @Override public final String getRequestProperty(String field) {
+        if (field == null) {
+            return null;
+        }
+        return rawRequestHeaders.get(field);
+    }
+
+    private void initHttpEngine() throws IOException {
+        if (httpEngineFailure != null) {
+            throw httpEngineFailure;
+        } else if (httpEngine != null) {
+            return;
+        }
+
+        connected = true;
+        try {
+            if (doOutput) {
+                if (method == HttpEngine.GET) {
+                    // they are requesting a stream to write to. This implies a POST method
+                    method = HttpEngine.POST;
+                } else if (method != HttpEngine.POST && method != HttpEngine.PUT) {
+                    // If the request method is neither POST nor PUT, then you're not writing
+                    throw new ProtocolException(method + " does not support writing");
+                }
+            }
+            httpEngine = newHttpEngine(method, rawRequestHeaders, null, null);
+        } catch (IOException e) {
+            httpEngineFailure = e;
+            throw e;
+        }
+    }
+
+    /**
+     * Create a new HTTP engine. This hook method is non-final so it can be
+     * overridden by HttpsURLConnectionImpl.
+     */
+    protected HttpEngine newHttpEngine(String method, RawHeaders requestHeaders,
+            HttpConnection connection, RetryableOutputStream requestBody) throws IOException {
+        return new HttpEngine(this, method, requestHeaders, connection, requestBody);
+    }
+
+    /**
+     * Aggressively tries to get the final HTTP response, potentially making
+     * many HTTP requests in the process in order to cope with redirects and
+     * authentication.
+     */
+    private HttpEngine getResponse() throws IOException {
+        initHttpEngine();
+
+        if (httpEngine.hasResponse()) {
+            return httpEngine;
+        }
+
+        while (true) {
+            try {
+                httpEngine.sendRequest();
+                httpEngine.readResponse();
+            } catch (IOException e) {
+                /*
+                 * If the connection was recycled, its staleness may have caused
+                 * the failure. Silently retry with a different connection.
+                 */
+                OutputStream requestBody = httpEngine.getRequestBody();
+                if (httpEngine.hasRecycledConnection()
+                        && (requestBody == null || requestBody instanceof RetryableOutputStream)) {
+                    httpEngine.release(false);
+                    httpEngine = newHttpEngine(method, rawRequestHeaders, null,
+                            (RetryableOutputStream) requestBody);
+                    continue;
+                }
+                httpEngineFailure = e;
+                throw e;
+            }
+
+            Retry retry = processResponseHeaders();
+            if (retry == Retry.NONE) {
+                httpEngine.automaticallyReleaseConnectionToPool();
+                return httpEngine;
+            }
+
+            /*
+             * The first request was insufficient. Prepare for another...
+             */
+            String retryMethod = method;
+            OutputStream requestBody = httpEngine.getRequestBody();
+
+            /*
+             * Although RFC 2616 10.3.2 specifies that a HTTP_MOVED_PERM
+             * redirect should keep the same method, Chrome, Firefox and the
+             * RI all issue GETs when following any redirect.
+             */
+            int responseCode = getResponseCode();
+            if (responseCode == HTTP_MULT_CHOICE || responseCode == HTTP_MOVED_PERM
+                    || responseCode == HTTP_MOVED_TEMP || responseCode == HTTP_SEE_OTHER) {
+                retryMethod = HttpEngine.GET;
+                requestBody = null;
+            }
+
+            if (requestBody != null && !(requestBody instanceof RetryableOutputStream)) {
+                throw new HttpRetryException("Cannot retry streamed HTTP body",
+                        httpEngine.getResponseCode());
+            }
+
+            if (retry == Retry.DIFFERENT_CONNECTION) {
+                httpEngine.automaticallyReleaseConnectionToPool();
+            }
+
+            httpEngine.release(true);
+
+            httpEngine = newHttpEngine(retryMethod, rawRequestHeaders,
+                    httpEngine.getConnection(), (RetryableOutputStream) requestBody);
+        }
+    }
+
+    HttpEngine getHttpEngine() {
+        return httpEngine;
+    }
+
+    enum Retry {
+        NONE,
+        SAME_CONNECTION,
+        DIFFERENT_CONNECTION
+    }
+
+    /**
+     * Returns the retry action to take for the current response headers. The
+     * headers, proxy and target URL or this connection may be adjusted to
+     * prepare for a follow up request.
+     */
+    private Retry processResponseHeaders() throws IOException {
+        switch (getResponseCode()) {
+        case HTTP_PROXY_AUTH:
+            if (!usingProxy()) {
+                throw new IOException(
+                        "Received HTTP_PROXY_AUTH (407) code while not using proxy");
+            }
+            // fall-through
+        case HTTP_UNAUTHORIZED:
+            boolean credentialsFound = processAuthHeader(getResponseCode(),
+                    httpEngine.getResponseHeaders(), rawRequestHeaders);
+            return credentialsFound ? Retry.SAME_CONNECTION : Retry.NONE;
+
+        case HTTP_MULT_CHOICE:
+        case HTTP_MOVED_PERM:
+        case HTTP_MOVED_TEMP:
+        case HTTP_SEE_OTHER:
+            if (!getInstanceFollowRedirects()) {
+                return Retry.NONE;
+            }
+            if (++redirectionCount > MAX_REDIRECTS) {
+                throw new ProtocolException("Too many redirects");
+            }
+            String location = getHeaderField("Location");
+            if (location == null) {
+                return Retry.NONE;
+            }
+            URL previousUrl = url;
+            url = new URL(previousUrl, location);
+            if (!previousUrl.getProtocol().equals(url.getProtocol())) {
+                return Retry.NONE; // the scheme changed; don't retry.
+            }
+            if (previousUrl.getHost().equals(url.getHost())
+                    && Libcore.getEffectivePort(previousUrl) == Libcore.getEffectivePort(url)) {
+                return Retry.SAME_CONNECTION;
+            } else {
+                return Retry.DIFFERENT_CONNECTION;
+            }
+
+        default:
+            return Retry.NONE;
+        }
+    }
+
+    /**
+     * React to a failed authorization response by looking up new credentials.
+     *
+     * @return true if credentials have been added to successorRequestHeaders
+     *     and another request should be attempted.
+     */
+    final boolean processAuthHeader(int responseCode, ResponseHeaders response,
+            RawHeaders successorRequestHeaders) throws IOException {
+        if (responseCode != HTTP_PROXY_AUTH && responseCode != HTTP_UNAUTHORIZED) {
+            throw new IllegalArgumentException();
+        }
+
+        // keep asking for username/password until authorized
+        String challengeHeader = responseCode == HTTP_PROXY_AUTH
+                ? "Proxy-Authenticate"
+                : "WWW-Authenticate";
+        String credentials = getAuthorizationCredentials(response.getHeaders(), challengeHeader);
+        if (credentials == null) {
+            return false; // could not find credentials, end request cycle
+        }
+
+        // add authorization credentials, bypassing the already-connected check
+        String fieldName = responseCode == HTTP_PROXY_AUTH
+                ? "Proxy-Authorization"
+                : "Authorization";
+        successorRequestHeaders.set(fieldName, credentials);
+        return true;
+    }
+
+    /**
+     * Returns the authorization credentials on the base of provided challenge.
+     */
+    private String getAuthorizationCredentials(RawHeaders responseHeaders, String challengeHeader)
+            throws IOException {
+        List<Challenge> challenges = HeaderParser.parseChallenges(responseHeaders, challengeHeader);
+        if (challenges.isEmpty()) {
+            throw new IOException("No authentication challenges found");
+        }
+
+        for (Challenge challenge : challenges) {
+            // use the global authenticator to get the password
+            PasswordAuthentication auth = Authenticator.requestPasswordAuthentication(
+                    getConnectToInetAddress(), getConnectToPort(), url.getProtocol(),
+                    challenge.realm, challenge.scheme);
+            if (auth == null) {
+                continue;
+            }
+
+            // base64 encode the username and password
+            String usernameAndPassword = auth.getUserName() + ":" + new String(auth.getPassword());
+            byte[] bytes = usernameAndPassword.getBytes("ISO-8859-1");
+            String encoded = Base64.encode(bytes);
+            return challenge.scheme + " " + encoded;
+        }
+
+        return null;
+    }
+
+    private InetAddress getConnectToInetAddress() throws IOException {
+        return usingProxy()
+                ? ((InetSocketAddress) proxy.address()).getAddress()
+                : InetAddress.getByName(getURL().getHost());
+    }
+
+    final int getDefaultPort() {
+        return defaultPort;
+    }
+
+    /** @see java.net.HttpURLConnection#setFixedLengthStreamingMode(int) */
+    final int getFixedContentLength() {
+        return fixedContentLength;
+    }
+
+    /** @see java.net.HttpURLConnection#setChunkedStreamingMode(int) */
+    final int getChunkLength() {
+        return chunkLength;
+    }
+
+    final Proxy getProxy() {
+        return proxy;
+    }
+
+    final void setProxy(Proxy proxy) {
+        this.proxy = proxy;
+    }
+
+    @Override public final boolean usingProxy() {
+        return (proxy != null && proxy.type() != Proxy.Type.DIRECT);
+    }
+
+    @Override public String getResponseMessage() throws IOException {
+        return getResponse().getResponseHeaders().getHeaders().getResponseMessage();
+    }
+
+    @Override public final int getResponseCode() throws IOException {
+        return getResponse().getResponseCode();
+    }
+
+    @Override public final void setRequestProperty(String field, String newValue) {
+        if (connected) {
+            throw new IllegalStateException("Cannot set request property after connection is made");
+        }
+        if (field == null) {
+            throw new NullPointerException("field == null");
+        }
+        rawRequestHeaders.set(field, newValue);
+    }
+
+    @Override public final void addRequestProperty(String field, String value) {
+        if (connected) {
+            throw new IllegalStateException("Cannot add request property after connection is made");
+        }
+        if (field == null) {
+            throw new NullPointerException("field == null");
+        }
+        rawRequestHeaders.add(field, value);
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpsHandler.java b/src/main/java/libcore/net/http/HttpsHandler.java
new file mode 100644
index 0000000..ed9ba72
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpsHandler.java
@@ -0,0 +1,42 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+
+public final class HttpsHandler extends URLStreamHandler {
+
+    @Override protected URLConnection openConnection(URL url) throws IOException {
+        return new HttpsURLConnectionImpl(url, getDefaultPort());
+    }
+
+    @Override protected URLConnection openConnection(URL url, Proxy proxy) throws IOException {
+        if (url == null || proxy == null) {
+            throw new IllegalArgumentException("url == null || proxy == null");
+        }
+        return new HttpsURLConnectionImpl(url, getDefaultPort(), proxy);
+    }
+
+    @Override protected int getDefaultPort() {
+        return 443;
+    }
+}
diff --git a/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java b/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java
new file mode 100644
index 0000000..0ea33f7
--- /dev/null
+++ b/src/main/java/libcore/net/http/HttpsURLConnectionImpl.java
@@ -0,0 +1,535 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+package libcore.net.http;
+
+import com.squareup.okhttp.OkHttpConnection;
+import com.squareup.okhttp.OkHttpsConnection;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheResponse;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.SecureCacheResponse;
+import java.net.URL;
+import java.security.Permission;
+import java.security.Principal;
+import java.security.cert.Certificate;
+import java.security.cert.CertificateException;
+import java.util.List;
+import java.util.Map;
+import javax.net.ssl.SSLHandshakeException;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLSocketFactory;
+
+public final class HttpsURLConnectionImpl extends OkHttpsConnection {
+
+    /** HttpUrlConnectionDelegate allows reuse of HttpURLConnectionImpl. */
+    private final HttpUrlConnectionDelegate delegate;
+
+    public HttpsURLConnectionImpl(URL url, int port) {
+        super(url);
+        delegate = new HttpUrlConnectionDelegate(url, port);
+    }
+
+    public HttpsURLConnectionImpl(URL url, int port, Proxy proxy) {
+        super(url);
+        delegate = new HttpUrlConnectionDelegate(url, port, proxy);
+    }
+
+    private void checkConnected() {
+        if (delegate.getSSLSocket() == null) {
+            throw new IllegalStateException("Connection has not yet been established");
+        }
+    }
+
+    HttpEngine getHttpEngine() {
+        return delegate.getHttpEngine();
+    }
+
+    @Override
+    public String getCipherSuite() {
+        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
+        if (cacheResponse != null) {
+            return cacheResponse.getCipherSuite();
+        }
+        checkConnected();
+        return delegate.getSSLSocket().getSession().getCipherSuite();
+    }
+
+    @Override
+    public Certificate[] getLocalCertificates() {
+        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
+        if (cacheResponse != null) {
+            List<Certificate> result = cacheResponse.getLocalCertificateChain();
+            return result != null ? result.toArray(new Certificate[result.size()]) : null;
+        }
+        checkConnected();
+        return delegate.getSSLSocket().getSession().getLocalCertificates();
+    }
+
+    @Override
+    public Certificate[] getServerCertificates() throws SSLPeerUnverifiedException {
+        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
+        if (cacheResponse != null) {
+            List<Certificate> result = cacheResponse.getServerCertificateChain();
+            return result != null ? result.toArray(new Certificate[result.size()]) : null;
+        }
+        checkConnected();
+        return delegate.getSSLSocket().getSession().getPeerCertificates();
+    }
+
+    @Override
+    public Principal getPeerPrincipal() throws SSLPeerUnverifiedException {
+        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
+        if (cacheResponse != null) {
+            return cacheResponse.getPeerPrincipal();
+        }
+        checkConnected();
+        return delegate.getSSLSocket().getSession().getPeerPrincipal();
+    }
+
+    @Override
+    public Principal getLocalPrincipal() {
+        SecureCacheResponse cacheResponse = delegate.getCacheResponse();
+        if (cacheResponse != null) {
+            return cacheResponse.getLocalPrincipal();
+        }
+        checkConnected();
+        return delegate.getSSLSocket().getSession().getLocalPrincipal();
+    }
+
+    @Override
+    public void disconnect() {
+        delegate.disconnect();
+    }
+
+    @Override
+    public InputStream getErrorStream() {
+        return delegate.getErrorStream();
+    }
+
+    @Override
+    public String getRequestMethod() {
+        return delegate.getRequestMethod();
+    }
+
+    @Override
+    public int getResponseCode() throws IOException {
+        return delegate.getResponseCode();
+    }
+
+    @Override
+    public String getResponseMessage() throws IOException {
+        return delegate.getResponseMessage();
+    }
+
+    @Override
+    public void setRequestMethod(String method) throws ProtocolException {
+        delegate.setRequestMethod(method);
+    }
+
+    @Override
+    public boolean usingProxy() {
+        return delegate.usingProxy();
+    }
+
+    @Override
+    public boolean getInstanceFollowRedirects() {
+        return delegate.getInstanceFollowRedirects();
+    }
+
+    @Override
+    public void setInstanceFollowRedirects(boolean followRedirects) {
+        delegate.setInstanceFollowRedirects(followRedirects);
+    }
+
+    @Override
+    public void connect() throws IOException {
+        connected = true;
+        delegate.connect();
+    }
+
+    @Override
+    public boolean getAllowUserInteraction() {
+        return delegate.getAllowUserInteraction();
+    }
+
+    @Override
+    public Object getContent() throws IOException {
+        return delegate.getContent();
+    }
+
+    @SuppressWarnings("unchecked") // Spec does not generify
+    @Override
+    public Object getContent(Class[] types) throws IOException {
+        return delegate.getContent(types);
+    }
+
+    @Override
+    public String getContentEncoding() {
+        return delegate.getContentEncoding();
+    }
+
+    @Override
+    public int getContentLength() {
+        return delegate.getContentLength();
+    }
+
+    @Override
+    public String getContentType() {
+        return delegate.getContentType();
+    }
+
+    @Override
+    public long getDate() {
+        return delegate.getDate();
+    }
+
+    @Override
+    public boolean getDefaultUseCaches() {
+        return delegate.getDefaultUseCaches();
+    }
+
+    @Override
+    public boolean getDoInput() {
+        return delegate.getDoInput();
+    }
+
+    @Override
+    public boolean getDoOutput() {
+        return delegate.getDoOutput();
+    }
+
+    @Override
+    public long getExpiration() {
+        return delegate.getExpiration();
+    }
+
+    @Override
+    public String getHeaderField(int pos) {
+        return delegate.getHeaderField(pos);
+    }
+
+    @Override
+    public Map<String, List<String>> getHeaderFields() {
+        return delegate.getHeaderFields();
+    }
+
+    @Override
+    public Map<String, List<String>> getRequestProperties() {
+        return delegate.getRequestProperties();
+    }
+
+    @Override
+    public void addRequestProperty(String field, String newValue) {
+        delegate.addRequestProperty(field, newValue);
+    }
+
+    @Override
+    public String getHeaderField(String key) {
+        return delegate.getHeaderField(key);
+    }
+
+    @Override
+    public long getHeaderFieldDate(String field, long defaultValue) {
+        return delegate.getHeaderFieldDate(field, defaultValue);
+    }
+
+    @Override
+    public int getHeaderFieldInt(String field, int defaultValue) {
+        return delegate.getHeaderFieldInt(field, defaultValue);
+    }
+
+    @Override
+    public String getHeaderFieldKey(int posn) {
+        return delegate.getHeaderFieldKey(posn);
+    }
+
+    @Override
+    public long getIfModifiedSince() {
+        return delegate.getIfModifiedSince();
+    }
+
+    @Override
+    public InputStream getInputStream() throws IOException {
+        return delegate.getInputStream();
+    }
+
+    @Override
+    public long getLastModified() {
+        return delegate.getLastModified();
+    }
+
+    @Override
+    public OutputStream getOutputStream() throws IOException {
+        return delegate.getOutputStream();
+    }
+
+    @Override
+    public Permission getPermission() throws IOException {
+        return delegate.getPermission();
+    }
+
+    @Override
+    public String getRequestProperty(String field) {
+        return delegate.getRequestProperty(field);
+    }
+
+    @Override
+    public URL getURL() {
+        return delegate.getURL();
+    }
+
+    @Override
+    public boolean getUseCaches() {
+        return delegate.getUseCaches();
+    }
+
+    @Override
+    public void setAllowUserInteraction(boolean newValue) {
+        delegate.setAllowUserInteraction(newValue);
+    }
+
+    @Override
+    public void setDefaultUseCaches(boolean newValue) {
+        delegate.setDefaultUseCaches(newValue);
+    }
+
+    @Override
+    public void setDoInput(boolean newValue) {
+        delegate.setDoInput(newValue);
+    }
+
+    @Override
+    public void setDoOutput(boolean newValue) {
+        delegate.setDoOutput(newValue);
+    }
+
+    @Override
+    public void setIfModifiedSince(long newValue) {
+        delegate.setIfModifiedSince(newValue);
+    }
+
+    @Override
+    public void setRequestProperty(String field, String newValue) {
+        delegate.setRequestProperty(field, newValue);
+    }
+
+    @Override
+    public void setUseCaches(boolean newValue) {
+        delegate.setUseCaches(newValue);
+    }
+
+    @Override
+    public void setConnectTimeout(int timeoutMillis) {
+        delegate.setConnectTimeout(timeoutMillis);
+    }
+
+    @Override
+    public int getConnectTimeout() {
+        return delegate.getConnectTimeout();
+    }
+
+    @Override
+    public void setReadTimeout(int timeoutMillis) {
+        delegate.setReadTimeout(timeoutMillis);
+    }
+
+    @Override
+    public int getReadTimeout() {
+        return delegate.getReadTimeout();
+    }
+
+    @Override
+    public String toString() {
+        return delegate.toString();
+    }
+
+    @Override
+    public void setFixedLengthStreamingMode(int contentLength) {
+        delegate.setFixedLengthStreamingMode(contentLength);
+    }
+
+    @Override
+    public void setChunkedStreamingMode(int chunkLength) {
+        delegate.setChunkedStreamingMode(chunkLength);
+    }
+
+    private final class HttpUrlConnectionDelegate extends HttpURLConnectionImpl {
+        private HttpUrlConnectionDelegate(URL url, int port) {
+            super(url, port);
+        }
+
+        private HttpUrlConnectionDelegate(URL url, int port, Proxy proxy) {
+            super(url, port, proxy);
+        }
+
+        @Override protected HttpEngine newHttpEngine(String method, RawHeaders requestHeaders,
+                HttpConnection connection, RetryableOutputStream requestBody) throws IOException {
+            return new HttpsEngine(this, method, requestHeaders, connection, requestBody,
+                    HttpsURLConnectionImpl.this);
+        }
+
+        public SecureCacheResponse getCacheResponse() {
+            HttpsEngine engine = (HttpsEngine) httpEngine;
+            return engine != null ? (SecureCacheResponse) engine.getCacheResponse() : null;
+        }
+
+        public SSLSocket getSSLSocket() {
+            HttpsEngine engine = (HttpsEngine) httpEngine;
+            return engine != null ? engine.sslSocket : null;
+        }
+    }
+
+    private static final class HttpsEngine extends HttpEngine {
+
+        /**
+         * Local stash of HttpsEngine.connection.sslSocket for answering
+         * queries such as getCipherSuite even after
+         * httpsEngine.Connection has been recycled. It's presence is also
+         * used to tell if the HttpsURLConnection is considered connected,
+         * as opposed to the connected field of URLConnection or the a
+         * non-null connect in HttpURLConnectionImpl
+         */
+        private SSLSocket sslSocket;
+
+        private final HttpsURLConnectionImpl enclosing;
+
+        /**
+         * @param policy the HttpURLConnectionImpl with connection configuration
+         * @param enclosing the HttpsURLConnection with HTTPS features
+         */
+        private HttpsEngine(HttpURLConnectionImpl policy, String method, RawHeaders requestHeaders,
+                HttpConnection connection, RetryableOutputStream requestBody,
+                HttpsURLConnectionImpl enclosing) throws IOException {
+            super(policy, method, requestHeaders, connection, requestBody);
+            this.sslSocket = connection != null ? connection.getSecureSocketIfConnected() : null;
+            this.enclosing = enclosing;
+        }
+
+        @Override protected void connect() throws IOException {
+            // First try an SSL connection with compression and various TLS
+            // extensions enabled, if it fails (and its not unheard of that it
+            // will) fallback to a barebones connection.
+            try {
+                makeSslConnection(true);
+            } catch (IOException e) {
+                // If the problem was a CertificateException from the X509TrustManager,
+                // do not retry, we didn't have an abrupt server initiated exception.
+                if (e instanceof SSLHandshakeException
+                        && e.getCause() instanceof CertificateException) {
+                    throw e;
+                }
+                release(false);
+                makeSslConnection(false);
+            }
+        }
+
+        /**
+         * Attempt to make an HTTPS connection.
+         *
+         * @param tlsTolerant If true, assume server can handle common
+         * TLS extensions and SSL deflate compression. If false, use
+         * an SSL3 only fallback mode without compression.
+         */
+        private void makeSslConnection(boolean tlsTolerant) throws IOException {
+            // make an SSL Tunnel on the first message pair of each SSL + proxy connection
+            if (connection == null) {
+                connection = openSocketConnection();
+                if (connection.getAddress().getProxy() != null) {
+                    makeTunnel(policy, connection, getRequestHeaders());
+                }
+            }
+
+            // if super.makeConnection returned a connection from the
+            // pool, sslSocket needs to be initialized here. If it is
+            // a new connection, it will be initialized by
+            // getSecureSocket below.
+            sslSocket = connection.getSecureSocketIfConnected();
+
+            // we already have an SSL connection,
+            if (sslSocket != null) {
+                return;
+            }
+
+            sslSocket = connection.setupSecureSocket(
+                    enclosing.getSSLSocketFactory(), enclosing.getHostnameVerifier(), tlsTolerant);
+        }
+
+        /**
+         * To make an HTTPS connection over an HTTP proxy, send an unencrypted
+         * CONNECT request to create the proxy connection. This may need to be
+         * retried if the proxy requires authorization.
+         */
+        private void makeTunnel(HttpURLConnectionImpl policy, HttpConnection connection,
+                RequestHeaders requestHeaders) throws IOException {
+            RawHeaders rawRequestHeaders = requestHeaders.getHeaders();
+            while (true) {
+                HttpEngine connect = new ProxyConnectEngine(policy, rawRequestHeaders, connection);
+                connect.sendRequest();
+                connect.readResponse();
+
+                int responseCode = connect.getResponseCode();
+                switch (connect.getResponseCode()) {
+                case HTTP_OK:
+                    return;
+                case HTTP_PROXY_AUTH:
+                    rawRequestHeaders = new RawHeaders(rawRequestHeaders);
+                    boolean credentialsFound = policy.processAuthHeader(HTTP_PROXY_AUTH,
+                            connect.getResponseHeaders(), rawRequestHeaders);
+                    if (credentialsFound) {
+                        continue;
+                    } else {
+                        throw new IOException("Failed to authenticate with proxy");
+                    }
+                default:
+                    throw new IOException("Unexpected response code for CONNECT: " + responseCode);
+                }
+            }
+        }
+
+        @Override protected boolean acceptCacheResponseType(CacheResponse cacheResponse) {
+            return cacheResponse instanceof SecureCacheResponse;
+        }
+
+        @Override protected boolean includeAuthorityInRequestLine() {
+            // Even if there is a proxy, it isn't involved. Always request just the file.
+            return false;
+        }
+
+        @Override protected SSLSocketFactory getSslSocketFactory() {
+            return enclosing.getSSLSocketFactory();
+        }
+
+        @Override protected OkHttpConnection getHttpConnectionToCache() {
+            return enclosing;
+        }
+    }
+
+    private static class ProxyConnectEngine extends HttpEngine {
+        public ProxyConnectEngine(HttpURLConnectionImpl policy, RawHeaders requestHeaders,
+                HttpConnection connection) throws IOException {
+            super(policy, HttpEngine.CONNECT, requestHeaders, connection, null);
+        }
+
+        @Override protected boolean requiresTunnel() {
+            return true;
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/RawHeaders.java b/src/main/java/libcore/net/http/RawHeaders.java
new file mode 100644
index 0000000..642c61d
--- /dev/null
+++ b/src/main/java/libcore/net/http/RawHeaders.java
@@ -0,0 +1,390 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import libcore.util.Libcore;
+
+/**
+ * The HTTP status and unparsed header fields of a single HTTP message. Values
+ * are represented as uninterpreted strings; use {@link RequestHeaders} and
+ * {@link ResponseHeaders} for interpreted headers. This class maintains the
+ * order of the header fields within the HTTP message.
+ *
+ * <p>This class tracks fields line-by-line. A field with multiple comma-
+ * separated values on the same line will be treated as a field with a single
+ * value by this class. It is the caller's responsibility to detect and split
+ * on commas if their field permits multiple values. This simplifies use of
+ * single-valued fields whose values routinely contain commas, such as cookies
+ * or dates.
+ *
+ * <p>This class trims whitespace from values. It never returns values with
+ * leading or trailing whitespace.
+ */
+public final class RawHeaders {
+    private static final Comparator<String> FIELD_NAME_COMPARATOR = new Comparator<String>() {
+        // @FindBugsSuppressWarnings("ES_COMPARING_PARAMETER_STRING_WITH_EQ")
+        @Override public int compare(String a, String b) {
+            if (a == b) {
+                return 0;
+            } else if (a == null) {
+                return -1;
+            } else if (b == null) {
+                return 1;
+            } else {
+                return String.CASE_INSENSITIVE_ORDER.compare(a, b);
+            }
+        }
+    };
+
+    private final List<String> namesAndValues = new ArrayList<String>(20);
+    private String statusLine;
+    private int httpMinorVersion = 1;
+    private int responseCode = -1;
+    private String responseMessage;
+
+    public RawHeaders() {
+    }
+
+    public RawHeaders(RawHeaders copyFrom) {
+        namesAndValues.addAll(copyFrom.namesAndValues);
+        statusLine = copyFrom.statusLine;
+        httpMinorVersion = copyFrom.httpMinorVersion;
+        responseCode = copyFrom.responseCode;
+        responseMessage = copyFrom.responseMessage;
+    }
+
+    /**
+     * Sets the response status line (like "HTTP/1.0 200 OK") or request line
+     * (like "GET / HTTP/1.1").
+     */
+    public void setStatusLine(String statusLine) {
+        statusLine = statusLine.trim();
+        this.statusLine = statusLine;
+
+        if (statusLine == null || !statusLine.startsWith("HTTP/")) {
+            return;
+        }
+        statusLine = statusLine.trim();
+        int mark = statusLine.indexOf(" ") + 1;
+        if (mark == 0) {
+            return;
+        }
+        if (statusLine.charAt(mark - 2) != '1') {
+            this.httpMinorVersion = 0;
+        }
+        int last = mark + 3;
+        if (last > statusLine.length()) {
+            last = statusLine.length();
+        }
+        this.responseCode = Integer.parseInt(statusLine.substring(mark, last));
+        if (last + 1 <= statusLine.length()) {
+            this.responseMessage = statusLine.substring(last + 1);
+        }
+    }
+
+    public void computeResponseStatusLineFromSpdyHeaders() throws IOException {
+        String status = null;
+        String version = null;
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            String name = namesAndValues.get(i);
+            if ("status".equals(name)) {
+                status = namesAndValues.get(i + 1);
+            } else if ("version".equals(name)) {
+                version = namesAndValues.get(i + 1);
+            }
+        }
+        if (status == null || version == null) {
+            throw new IOException("Expected 'status' and 'version' headers not present");
+        }
+        setStatusLine(version + " " + status);
+    }
+
+    /**
+     * @param method like "GET", "POST", "HEAD", etc.
+     * @param scheme like "https"
+     * @param url like "/foo/bar.html"
+     * @param version like "HTTP/1.1"
+     */
+    public void addSpdyRequestHeaders(String method, String scheme, String url, String version) {
+        // TODO: populate the statusLine for the client's benefit?
+        add("method", method);
+        add("scheme", scheme);
+        add("url", url);
+        add("version", version);
+    }
+
+    public String getStatusLine() {
+        return statusLine;
+    }
+
+    /**
+     * Returns the status line's HTTP minor version. This returns 0 for HTTP/1.0
+     * and 1 for HTTP/1.1. This returns 1 if the HTTP version is unknown.
+     */
+    public int getHttpMinorVersion() {
+        return httpMinorVersion != -1 ? httpMinorVersion : 1;
+    }
+
+    /**
+     * Returns the HTTP status code or -1 if it is unknown.
+     */
+    public int getResponseCode() {
+        return responseCode;
+    }
+
+    /**
+     * Returns the HTTP status message or null if it is unknown.
+     */
+    public String getResponseMessage() {
+        return responseMessage;
+    }
+
+    /**
+     * Add an HTTP header line containing a field name, a literal colon, and a
+     * value.
+     */
+    public void addLine(String line) {
+        int index = line.indexOf(":");
+        if (index == -1) {
+            add("", line);
+        } else {
+            add(line.substring(0, index), line.substring(index + 1));
+        }
+    }
+
+    /**
+     * Add a field with the specified value.
+     */
+    public void add(String fieldName, String value) {
+        if (fieldName == null) {
+            throw new IllegalArgumentException("fieldName == null");
+        }
+        if (value == null) {
+            /*
+             * Given null values, the RI sends a malformed field line like
+             * "Accept\r\n". For platform compatibility and HTTP compliance, we
+             * print a warning and ignore null values.
+             */
+            Libcore.logW("Ignoring HTTP header field '" + fieldName + "' because its value is null");
+            return;
+        }
+        namesAndValues.add(fieldName);
+        namesAndValues.add(value.trim());
+    }
+
+    public void removeAll(String fieldName) {
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            if (fieldName.equalsIgnoreCase(namesAndValues.get(i))) {
+                namesAndValues.remove(i); // field name
+                namesAndValues.remove(i); // value
+            }
+        }
+    }
+
+    public void addAll(String fieldName, List<String> headerFields) {
+        for (String value : headerFields) {
+            add(fieldName, value);
+        }
+    }
+
+    /**
+     * Set a field with the specified value. If the field is not found, it is
+     * added. If the field is found, the existing values are replaced.
+     */
+    public void set(String fieldName, String value) {
+        removeAll(fieldName);
+        add(fieldName, value);
+    }
+
+    /**
+     * Returns the number of field values.
+     */
+    public int length() {
+        return namesAndValues.size() / 2;
+    }
+
+    /**
+     * Returns the field at {@code position} or null if that is out of range.
+     */
+    public String getFieldName(int index) {
+        int fieldNameIndex = index * 2;
+        if (fieldNameIndex < 0 || fieldNameIndex >= namesAndValues.size()) {
+            return null;
+        }
+        return namesAndValues.get(fieldNameIndex);
+    }
+
+    /**
+     * Returns the value at {@code index} or null if that is out of range.
+     */
+    public String getValue(int index) {
+        int valueIndex = index * 2 + 1;
+        if (valueIndex < 0 || valueIndex >= namesAndValues.size()) {
+            return null;
+        }
+        return namesAndValues.get(valueIndex);
+    }
+
+    /**
+     * Returns the last value corresponding to the specified field, or null.
+     */
+    public String get(String fieldName) {
+        for (int i = namesAndValues.size() - 2; i >= 0; i -= 2) {
+            if (fieldName.equalsIgnoreCase(namesAndValues.get(i))) {
+                return namesAndValues.get(i + 1);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @param fieldNames a case-insensitive set of HTTP header field names.
+     */
+    public RawHeaders getAll(Set<String> fieldNames) {
+        RawHeaders result = new RawHeaders();
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            String fieldName = namesAndValues.get(i);
+            if (fieldNames.contains(fieldName)) {
+                result.add(fieldName, namesAndValues.get(i + 1));
+            }
+        }
+        return result;
+    }
+
+    public String toHeaderString() {
+        StringBuilder result = new StringBuilder(256);
+        result.append(statusLine).append("\r\n");
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            result.append(namesAndValues.get(i)).append(": ")
+                    .append(namesAndValues.get(i + 1)).append("\r\n");
+        }
+        result.append("\r\n");
+        return result.toString();
+    }
+
+    /**
+     * Returns an immutable map containing each field to its list of values. The
+     * status line is mapped to null.
+     */
+    public Map<String, List<String>> toMultimap() {
+        Map<String, List<String>> result = new TreeMap<String, List<String>>(FIELD_NAME_COMPARATOR);
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            String fieldName = namesAndValues.get(i);
+            String value = namesAndValues.get(i + 1);
+
+            List<String> allValues = new ArrayList<String>();
+            List<String> otherValues = result.get(fieldName);
+            if (otherValues != null) {
+                allValues.addAll(otherValues);
+            }
+            allValues.add(value);
+            result.put(fieldName, Collections.unmodifiableList(allValues));
+        }
+        if (statusLine != null) {
+            result.put(null, Collections.unmodifiableList(Collections.singletonList(statusLine)));
+        }
+        return Collections.unmodifiableMap(result);
+    }
+
+    /**
+     * Creates a new instance from the given map of fields to values. If
+     * present, the null field's last element will be used to set the status
+     * line.
+     */
+    public static RawHeaders fromMultimap(Map<String, List<String>> map) {
+        RawHeaders result = new RawHeaders();
+        for (Entry<String, List<String>> entry : map.entrySet()) {
+            String fieldName = entry.getKey();
+            List<String> values = entry.getValue();
+            if (fieldName != null) {
+                result.addAll(fieldName, values);
+            } else if (!values.isEmpty()) {
+                result.setStatusLine(values.get(values.size() - 1));
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns a list of alternating names and values. Names are all lower case.
+     * No names are repeated. If any name has multiple values, they are
+     * concatenated using "\0" as a delimiter.
+     */
+    public List<String> toNameValueBlock() {
+        Set<String> names = new HashSet<String>();
+        List<String> result = new ArrayList<String>();
+        for (int i = 0; i < namesAndValues.size(); i += 2) {
+            String name = namesAndValues.get(i).toLowerCase(Locale.US);
+            String value = namesAndValues.get(i + 1);
+
+            // TODO: promote this check to where names and values are created
+            if (name.length() == 0 || value.length() == 0
+                    || name.indexOf('\0') != -1 || value.indexOf('\0') != -1) {
+                throw new IllegalArgumentException("Unexpected header: " + name + ": " + value);
+            }
+
+            // If we haven't seen this name before, add the pair to the end of the list...
+            if (names.add(name)) {
+                result.add(name);
+                result.add(value);
+                continue;
+            }
+
+            // ...otherwise concatenate the existing values and this value.
+            for (int j = 0; j < result.size(); j += 2) {
+                if (name.equals(result.get(j))) {
+                    result.set(j + 1, result.get(j + 1) + "\0" + value);
+                    break;
+                }
+            }
+        }
+        return result;
+    }
+
+    public static RawHeaders fromNameValueBlock(List<String> nameValueBlock) {
+        if (nameValueBlock.size() % 2 != 0) {
+            throw new IllegalArgumentException("Unexpected name value block: " + nameValueBlock);
+        }
+        RawHeaders result = new RawHeaders();
+        for (int i = 0; i < nameValueBlock.size(); i += 2) {
+            String name = nameValueBlock.get(i);
+            String values = nameValueBlock.get(i + 1);
+            for (int start = 0; start < values.length();) {
+                int end = values.indexOf(start, '\0');
+                if (end == -1) {
+                    end = values.length();
+                }
+                result.namesAndValues.add(name);
+                result.namesAndValues.add(values.substring(start, end));
+                start = end + 1;
+            }
+        }
+        return result;
+    }
+}
diff --git a/src/main/java/libcore/net/http/RequestHeaders.java b/src/main/java/libcore/net/http/RequestHeaders.java
new file mode 100644
index 0000000..a84437e
--- /dev/null
+++ b/src/main/java/libcore/net/http/RequestHeaders.java
@@ -0,0 +1,292 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parsed HTTP request headers.
+ */
+public final class RequestHeaders {
+    private final URI uri;
+    private final RawHeaders headers;
+
+    /** Don't use a cache to satisfy this request. */
+    private boolean noCache;
+    private int maxAgeSeconds = -1;
+    private int maxStaleSeconds = -1;
+    private int minFreshSeconds = -1;
+
+    /**
+     * This field's name "only-if-cached" is misleading. It actually means "do
+     * not use the network". It is set by a client who only wants to make a
+     * request if it can be fully satisfied by the cache. Cached responses that
+     * would require validation (ie. conditional gets) are not permitted if this
+     * header is set.
+     */
+    private boolean onlyIfCached;
+
+    /**
+     * True if the request contains an authorization field. Although this isn't
+     * necessarily a shared cache, it follows the spec's strict requirements for
+     * shared caches.
+     */
+    private boolean hasAuthorization;
+
+    private int contentLength = -1;
+    private String transferEncoding;
+    private String userAgent;
+    private String host;
+    private String connection;
+    private String acceptEncoding;
+    private String contentType;
+    private String ifModifiedSince;
+    private String ifNoneMatch;
+    private String proxyAuthorization;
+
+    public RequestHeaders(URI uri, RawHeaders headers) {
+        this.uri = uri;
+        this.headers = headers;
+
+        HeaderParser.CacheControlHandler handler = new HeaderParser.CacheControlHandler() {
+            @Override public void handle(String directive, String parameter) {
+                if ("no-cache".equalsIgnoreCase(directive)) {
+                    noCache = true;
+                } else if ("max-age".equalsIgnoreCase(directive)) {
+                    maxAgeSeconds = HeaderParser.parseSeconds(parameter);
+                } else if ("max-stale".equalsIgnoreCase(directive)) {
+                    maxStaleSeconds = HeaderParser.parseSeconds(parameter);
+                } else if ("min-fresh".equalsIgnoreCase(directive)) {
+                    minFreshSeconds = HeaderParser.parseSeconds(parameter);
+                } else if ("only-if-cached".equalsIgnoreCase(directive)) {
+                    onlyIfCached = true;
+                }
+            }
+        };
+
+        for (int i = 0; i < headers.length(); i++) {
+            String fieldName = headers.getFieldName(i);
+            String value = headers.getValue(i);
+            if ("Cache-Control".equalsIgnoreCase(fieldName)) {
+                HeaderParser.parseCacheControl(value, handler);
+            } else if ("Pragma".equalsIgnoreCase(fieldName)) {
+                if ("no-cache".equalsIgnoreCase(value)) {
+                    noCache = true;
+                }
+            } else if ("If-None-Match".equalsIgnoreCase(fieldName)) {
+                ifNoneMatch = value;
+            } else if ("If-Modified-Since".equalsIgnoreCase(fieldName)) {
+                ifModifiedSince = value;
+            } else if ("Authorization".equalsIgnoreCase(fieldName)) {
+                hasAuthorization = true;
+            } else if ("Content-Length".equalsIgnoreCase(fieldName)) {
+                try {
+                    contentLength = Integer.parseInt(value);
+                } catch (NumberFormatException ignored) {
+                }
+            } else if ("Transfer-Encoding".equalsIgnoreCase(fieldName)) {
+                transferEncoding = value;
+            } else if ("User-Agent".equalsIgnoreCase(fieldName)) {
+                userAgent = value;
+            } else if ("Host".equalsIgnoreCase(fieldName)) {
+                host = value;
+            } else if ("Connection".equalsIgnoreCase(fieldName)) {
+                connection = value;
+            } else if ("Accept-Encoding".equalsIgnoreCase(fieldName)) {
+                acceptEncoding = value;
+            } else if ("Content-Type".equalsIgnoreCase(fieldName)) {
+                contentType = value;
+            } else if ("Proxy-Authorization".equalsIgnoreCase(fieldName)) {
+                proxyAuthorization = value;
+            }
+        }
+    }
+
+    public boolean isChunked() {
+        return "chunked".equalsIgnoreCase(transferEncoding);
+    }
+
+    public boolean hasConnectionClose() {
+        return "close".equalsIgnoreCase(connection);
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public RawHeaders getHeaders() {
+        return headers;
+    }
+
+    public boolean isNoCache() {
+        return noCache;
+    }
+
+    public int getMaxAgeSeconds() {
+        return maxAgeSeconds;
+    }
+
+    public int getMaxStaleSeconds() {
+        return maxStaleSeconds;
+    }
+
+    public int getMinFreshSeconds() {
+        return minFreshSeconds;
+    }
+
+    public boolean isOnlyIfCached() {
+        return onlyIfCached;
+    }
+
+    public boolean hasAuthorization() {
+        return hasAuthorization;
+    }
+
+    public int getContentLength() {
+        return contentLength;
+    }
+
+    public String getTransferEncoding() {
+        return transferEncoding;
+    }
+
+    public String getUserAgent() {
+        return userAgent;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public String getConnection() {
+        return connection;
+    }
+
+    public String getAcceptEncoding() {
+        return acceptEncoding;
+    }
+
+    public String getContentType() {
+        return contentType;
+    }
+
+    public String getIfModifiedSince() {
+        return ifModifiedSince;
+    }
+
+    public String getIfNoneMatch() {
+        return ifNoneMatch;
+    }
+
+    public String getProxyAuthorization() {
+        return proxyAuthorization;
+    }
+
+    public void setChunked() {
+        if (this.transferEncoding != null) {
+            headers.removeAll("Transfer-Encoding");
+        }
+        headers.add("Transfer-Encoding", "chunked");
+        this.transferEncoding = "chunked";
+    }
+
+    public void setContentLength(int contentLength) {
+        if (this.contentLength != -1) {
+            headers.removeAll("Content-Length");
+        }
+        headers.add("Content-Length", Integer.toString(contentLength));
+        this.contentLength = contentLength;
+    }
+
+    public void setUserAgent(String userAgent) {
+        if (this.userAgent != null) {
+            headers.removeAll("User-Agent");
+        }
+        headers.add("User-Agent", userAgent);
+        this.userAgent = userAgent;
+    }
+
+    public void setHost(String host) {
+        if (this.host != null) {
+            headers.removeAll("Host");
+        }
+        headers.add("Host", host);
+        this.host = host;
+    }
+
+    public void setConnection(String connection) {
+        if (this.connection != null) {
+            headers.removeAll("Connection");
+        }
+        headers.add("Connection", connection);
+        this.connection = connection;
+    }
+
+    public void setAcceptEncoding(String acceptEncoding) {
+        if (this.acceptEncoding != null) {
+            headers.removeAll("Accept-Encoding");
+        }
+        headers.add("Accept-Encoding", acceptEncoding);
+        this.acceptEncoding = acceptEncoding;
+    }
+
+    public void setContentType(String contentType) {
+        if (this.contentType != null) {
+            headers.removeAll("Content-Type");
+        }
+        headers.add("Content-Type", contentType);
+        this.contentType = contentType;
+    }
+
+    public void setIfModifiedSince(Date date) {
+        if (ifModifiedSince != null) {
+            headers.removeAll("If-Modified-Since");
+        }
+        String formattedDate = HttpDate.format(date);
+        headers.add("If-Modified-Since", formattedDate);
+        ifModifiedSince = formattedDate;
+    }
+
+    public void setIfNoneMatch(String ifNoneMatch) {
+        if (this.ifNoneMatch != null) {
+            headers.removeAll("If-None-Match");
+        }
+        headers.add("If-None-Match", ifNoneMatch);
+        this.ifNoneMatch = ifNoneMatch;
+    }
+
+    /**
+     * Returns true if the request contains conditions that save the server from
+     * sending a response that the client has locally. When the caller adds
+     * conditions, this cache won't participate in the request.
+     */
+    public boolean hasConditions() {
+        return ifModifiedSince != null || ifNoneMatch != null;
+    }
+
+    public void addCookies(Map<String, List<String>> allCookieHeaders) {
+        for (Map.Entry<String, List<String>> entry : allCookieHeaders.entrySet()) {
+            String key = entry.getKey();
+            if ("Cookie".equalsIgnoreCase(key) || "Cookie2".equalsIgnoreCase(key)) {
+                headers.addAll(key, entry.getValue());
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/http/ResponseHeaders.java b/src/main/java/libcore/net/http/ResponseHeaders.java
new file mode 100644
index 0000000..236ce87
--- /dev/null
+++ b/src/main/java/libcore/net/http/ResponseHeaders.java
@@ -0,0 +1,503 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.util.Collections;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+import libcore.util.Objects;
+import libcore.util.ResponseSource;
+
+/**
+ * Parsed HTTP response headers.
+ */
+public final class ResponseHeaders {
+
+    /** HTTP header name for the local time when the request was sent. */
+    private static final String SENT_MILLIS = "X-Android-Sent-Millis";
+
+    /** HTTP header name for the local time when the response was received. */
+    private static final String RECEIVED_MILLIS = "X-Android-Received-Millis";
+
+    private final URI uri;
+    private final RawHeaders headers;
+
+    /** The server's time when this response was served, if known. */
+    private Date servedDate;
+
+    /** The last modified date of the response, if known. */
+    private Date lastModified;
+
+    /**
+     * The expiration date of the response, if known. If both this field and the
+     * max age are set, the max age is preferred.
+     */
+    private Date expires;
+
+    /**
+     * Extension header set by HttpURLConnectionImpl specifying the timestamp
+     * when the HTTP request was first initiated.
+     */
+    private long sentRequestMillis;
+
+    /**
+     * Extension header set by HttpURLConnectionImpl specifying the timestamp
+     * when the HTTP response was first received.
+     */
+    private long receivedResponseMillis;
+
+    /**
+     * In the response, this field's name "no-cache" is misleading. It doesn't
+     * prevent us from caching the response; it only means we have to validate
+     * the response with the origin server before returning it. We can do this
+     * with a conditional get.
+     */
+    private boolean noCache;
+
+    /** If true, this response should not be cached. */
+    private boolean noStore;
+
+    /**
+     * The duration past the response's served date that it can be served
+     * without validation.
+     */
+    private int maxAgeSeconds = -1;
+
+    /**
+     * The "s-maxage" directive is the max age for shared caches. Not to be
+     * confused with "max-age" for non-shared caches, As in Firefox and Chrome,
+     * this directive is not honored by this cache.
+     */
+    private int sMaxAgeSeconds = -1;
+
+    /**
+     * This request header field's name "only-if-cached" is misleading. It
+     * actually means "do not use the network". It is set by a client who only
+     * wants to make a request if it can be fully satisfied by the cache.
+     * Cached responses that would require validation (ie. conditional gets) are
+     * not permitted if this header is set.
+     */
+    private boolean isPublic;
+    private boolean mustRevalidate;
+    private String etag;
+    private int ageSeconds = -1;
+
+    /** Case-insensitive set of field names. */
+    private Set<String> varyFields = Collections.emptySet();
+
+    private String contentEncoding;
+    private String transferEncoding;
+    private int contentLength = -1;
+    private String connection;
+
+    public ResponseHeaders(URI uri, RawHeaders headers) {
+        this.uri = uri;
+        this.headers = headers;
+
+        HeaderParser.CacheControlHandler handler = new HeaderParser.CacheControlHandler() {
+            @Override public void handle(String directive, String parameter) {
+                if ("no-cache".equalsIgnoreCase(directive)) {
+                    noCache = true;
+                } else if ("no-store".equalsIgnoreCase(directive)) {
+                    noStore = true;
+                } else if ("max-age".equalsIgnoreCase(directive)) {
+                    maxAgeSeconds = HeaderParser.parseSeconds(parameter);
+                } else if ("s-maxage".equalsIgnoreCase(directive)) {
+                    sMaxAgeSeconds = HeaderParser.parseSeconds(parameter);
+                } else if ("public".equalsIgnoreCase(directive)) {
+                    isPublic = true;
+                } else if ("must-revalidate".equalsIgnoreCase(directive)) {
+                    mustRevalidate = true;
+                }
+            }
+        };
+
+        for (int i = 0; i < headers.length(); i++) {
+            String fieldName = headers.getFieldName(i);
+            String value = headers.getValue(i);
+            if ("Cache-Control".equalsIgnoreCase(fieldName)) {
+                HeaderParser.parseCacheControl(value, handler);
+            } else if ("Date".equalsIgnoreCase(fieldName)) {
+                servedDate = HttpDate.parse(value);
+            } else if ("Expires".equalsIgnoreCase(fieldName)) {
+                expires = HttpDate.parse(value);
+            } else if ("Last-Modified".equalsIgnoreCase(fieldName)) {
+                lastModified = HttpDate.parse(value);
+            } else if ("ETag".equalsIgnoreCase(fieldName)) {
+                etag = value;
+            } else if ("Pragma".equalsIgnoreCase(fieldName)) {
+                if ("no-cache".equalsIgnoreCase(value)) {
+                    noCache = true;
+                }
+            } else if ("Age".equalsIgnoreCase(fieldName)) {
+                ageSeconds = HeaderParser.parseSeconds(value);
+            } else if ("Vary".equalsIgnoreCase(fieldName)) {
+                // Replace the immutable empty set with something we can mutate.
+                if (varyFields.isEmpty()) {
+                    varyFields = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
+                }
+                for (String varyField : value.split(",")) {
+                    varyFields.add(varyField.trim());
+                }
+            } else if ("Content-Encoding".equalsIgnoreCase(fieldName)) {
+                contentEncoding = value;
+            } else if ("Transfer-Encoding".equalsIgnoreCase(fieldName)) {
+                transferEncoding = value;
+            } else if ("Content-Length".equalsIgnoreCase(fieldName)) {
+                try {
+                    contentLength = Integer.parseInt(value);
+                } catch (NumberFormatException ignored) {
+                }
+            } else if ("Connection".equalsIgnoreCase(fieldName)) {
+                connection = value;
+            } else if (SENT_MILLIS.equalsIgnoreCase(fieldName)) {
+                sentRequestMillis = Long.parseLong(value);
+            } else if (RECEIVED_MILLIS.equalsIgnoreCase(fieldName)) {
+                receivedResponseMillis = Long.parseLong(value);
+            }
+        }
+    }
+
+    public boolean isContentEncodingGzip() {
+        return "gzip".equalsIgnoreCase(contentEncoding);
+    }
+
+    public void stripContentEncoding() {
+        contentEncoding = null;
+        headers.removeAll("Content-Encoding");
+    }
+
+    public boolean isChunked() {
+        return "chunked".equalsIgnoreCase(transferEncoding);
+    }
+
+    public boolean hasConnectionClose() {
+        return "close".equalsIgnoreCase(connection);
+    }
+
+    public URI getUri() {
+        return uri;
+    }
+
+    public RawHeaders getHeaders() {
+        return headers;
+    }
+
+    public Date getServedDate() {
+        return servedDate;
+    }
+
+    public Date getLastModified() {
+        return lastModified;
+    }
+
+    public Date getExpires() {
+        return expires;
+    }
+
+    public boolean isNoCache() {
+        return noCache;
+    }
+
+    public boolean isNoStore() {
+        return noStore;
+    }
+
+    public int getMaxAgeSeconds() {
+        return maxAgeSeconds;
+    }
+
+    public int getSMaxAgeSeconds() {
+        return sMaxAgeSeconds;
+    }
+
+    public boolean isPublic() {
+        return isPublic;
+    }
+
+    public boolean isMustRevalidate() {
+        return mustRevalidate;
+    }
+
+    public String getEtag() {
+        return etag;
+    }
+
+    public Set<String> getVaryFields() {
+        return varyFields;
+    }
+
+    public String getContentEncoding() {
+        return contentEncoding;
+    }
+
+    public int getContentLength() {
+        return contentLength;
+    }
+
+    public String getConnection() {
+        return connection;
+    }
+
+    public void setLocalTimestamps(long sentRequestMillis, long receivedResponseMillis) {
+        this.sentRequestMillis = sentRequestMillis;
+        headers.add(SENT_MILLIS, Long.toString(sentRequestMillis));
+        this.receivedResponseMillis = receivedResponseMillis;
+        headers.add(RECEIVED_MILLIS, Long.toString(receivedResponseMillis));
+    }
+
+    /**
+     * Returns the current age of the response, in milliseconds. The calculation
+     * is specified by RFC 2616, 13.2.3 Age Calculations.
+     */
+    private long computeAge(long nowMillis) {
+        long apparentReceivedAge = servedDate != null
+                ? Math.max(0, receivedResponseMillis - servedDate.getTime())
+                : 0;
+        long receivedAge = ageSeconds != -1
+                ? Math.max(apparentReceivedAge, TimeUnit.SECONDS.toMillis(ageSeconds))
+                : apparentReceivedAge;
+        long responseDuration = receivedResponseMillis - sentRequestMillis;
+        long residentDuration = nowMillis - receivedResponseMillis;
+        return receivedAge + responseDuration + residentDuration;
+    }
+
+    /**
+     * Returns the number of milliseconds that the response was fresh for,
+     * starting from the served date.
+     */
+    private long computeFreshnessLifetime() {
+        if (maxAgeSeconds != -1) {
+            return TimeUnit.SECONDS.toMillis(maxAgeSeconds);
+        } else if (expires != null) {
+            long servedMillis = servedDate != null ? servedDate.getTime() : receivedResponseMillis;
+            long delta = expires.getTime() - servedMillis;
+            return delta > 0 ? delta : 0;
+        } else if (lastModified != null && uri.getRawQuery() == null) {
+            /*
+             * As recommended by the HTTP RFC and implemented in Firefox, the
+             * max age of a document should be defaulted to 10% of the
+             * document's age at the time it was served. Default expiration
+             * dates aren't used for URIs containing a query.
+             */
+            long servedMillis = servedDate != null ? servedDate.getTime() : sentRequestMillis;
+            long delta = servedMillis - lastModified.getTime();
+            return delta > 0 ? (delta / 10) : 0;
+        }
+        return 0;
+    }
+
+    /**
+     * Returns true if computeFreshnessLifetime used a heuristic. If we used a
+     * heuristic to serve a cached response older than 24 hours, we are required
+     * to attach a warning.
+     */
+    private boolean isFreshnessLifetimeHeuristic() {
+        return maxAgeSeconds == -1 && expires == null;
+    }
+
+    /**
+     * Returns true if this response can be stored to later serve another
+     * request.
+     */
+    public boolean isCacheable(RequestHeaders request) {
+        /*
+         * Always go to network for uncacheable response codes (RFC 2616, 13.4),
+         * This implementation doesn't support caching partial content.
+         */
+        int responseCode = headers.getResponseCode();
+        if (responseCode != HttpURLConnection.HTTP_OK
+                && responseCode != HttpURLConnection.HTTP_NOT_AUTHORITATIVE
+                && responseCode != HttpURLConnection.HTTP_MULT_CHOICE
+                && responseCode != HttpURLConnection.HTTP_MOVED_PERM
+                && responseCode != HttpURLConnection.HTTP_GONE) {
+            return false;
+        }
+
+        /*
+         * Responses to authorized requests aren't cacheable unless they include
+         * a 'public', 'must-revalidate' or 's-maxage' directive.
+         */
+        if (request.hasAuthorization()
+                && !isPublic
+                && !mustRevalidate
+                && sMaxAgeSeconds == -1) {
+            return false;
+        }
+
+        if (noStore) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns true if a Vary header contains an asterisk. Such responses cannot
+     * be cached.
+     */
+    public boolean hasVaryAll() {
+        return varyFields.contains("*");
+    }
+
+    /**
+     * Returns true if none of the Vary headers on this response have changed
+     * between {@code cachedRequest} and {@code newRequest}.
+     */
+    public boolean varyMatches(Map<String, List<String>> cachedRequest,
+            Map<String, List<String>> newRequest) {
+        for (String field : varyFields) {
+            if (!Objects.equal(cachedRequest.get(field), newRequest.get(field))) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Returns the source to satisfy {@code request} given this cached response.
+     */
+    public ResponseSource chooseResponseSource(long nowMillis, RequestHeaders request) {
+        /*
+         * If this response shouldn't have been stored, it should never be used
+         * as a response source. This check should be redundant as long as the
+         * persistence store is well-behaved and the rules are constant.
+         */
+        if (!isCacheable(request)) {
+            return ResponseSource.NETWORK;
+        }
+
+        if (request.isNoCache() || request.hasConditions()) {
+            return ResponseSource.NETWORK;
+        }
+
+        long ageMillis = computeAge(nowMillis);
+        long freshMillis = computeFreshnessLifetime();
+
+        if (request.getMaxAgeSeconds() != -1) {
+            freshMillis = Math.min(freshMillis,
+                    TimeUnit.SECONDS.toMillis(request.getMaxAgeSeconds()));
+        }
+
+        long minFreshMillis = 0;
+        if (request.getMinFreshSeconds() != -1) {
+            minFreshMillis = TimeUnit.SECONDS.toMillis(request.getMinFreshSeconds());
+        }
+
+        long maxStaleMillis = 0;
+        if (!mustRevalidate && request.getMaxStaleSeconds() != -1) {
+            maxStaleMillis = TimeUnit.SECONDS.toMillis(request.getMaxStaleSeconds());
+        }
+
+        if (!noCache && ageMillis + minFreshMillis < freshMillis + maxStaleMillis) {
+            if (ageMillis + minFreshMillis >= freshMillis) {
+                headers.add("Warning", "110 HttpURLConnection \"Response is stale\"");
+            }
+            if (ageMillis > TimeUnit.HOURS.toMillis(24) && isFreshnessLifetimeHeuristic()) {
+                headers.add("Warning", "113 HttpURLConnection \"Heuristic expiration\"");
+            }
+            return ResponseSource.CACHE;
+        }
+
+        if (lastModified != null) {
+            request.setIfModifiedSince(lastModified);
+        } else if (servedDate != null) {
+            request.setIfModifiedSince(servedDate);
+        }
+
+        if (etag != null) {
+            request.setIfNoneMatch(etag);
+        }
+
+        return request.hasConditions()
+                ? ResponseSource.CONDITIONAL_CACHE
+                : ResponseSource.NETWORK;
+    }
+
+    /**
+     * Returns true if this cached response should be used; false if the
+     * network response should be used.
+     */
+    public boolean validate(ResponseHeaders networkResponse) {
+        if (networkResponse.headers.getResponseCode() == HttpURLConnection.HTTP_NOT_MODIFIED) {
+            return true;
+        }
+
+        /*
+         * The HTTP spec says that if the network's response is older than our
+         * cached response, we may return the cache's response. Like Chrome (but
+         * unlike Firefox), this client prefers to return the newer response.
+         */
+        if (lastModified != null
+                && networkResponse.lastModified != null
+                && networkResponse.lastModified.getTime() < lastModified.getTime()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Combines this cached header with a network header as defined by RFC 2616,
+     * 13.5.3.
+     */
+    public ResponseHeaders combine(ResponseHeaders network) {
+        RawHeaders result = new RawHeaders();
+        result.setStatusLine(headers.getStatusLine());
+
+        for (int i = 0; i < headers.length(); i++) {
+            String fieldName = headers.getFieldName(i);
+            String value = headers.getValue(i);
+            if ("Warning".equals(fieldName) && value.startsWith("1")) {
+                continue; // drop 100-level freshness warnings
+            }
+            if (!isEndToEnd(fieldName) || network.headers.get(fieldName) == null) {
+                result.add(fieldName, value);
+            }
+        }
+
+        for (int i = 0; i < network.headers.length(); i++) {
+            String fieldName = network.headers.getFieldName(i);
+            if (isEndToEnd(fieldName)) {
+                result.add(fieldName, network.headers.getValue(i));
+            }
+        }
+
+        return new ResponseHeaders(uri, result);
+    }
+
+    /**
+     * Returns true if {@code fieldName} is an end-to-end HTTP header, as
+     * defined by RFC 2616, 13.5.1.
+     */
+    private static boolean isEndToEnd(String fieldName) {
+        return !"Connection".equalsIgnoreCase(fieldName)
+                && !"Keep-Alive".equalsIgnoreCase(fieldName)
+                && !"Proxy-Authenticate".equalsIgnoreCase(fieldName)
+                && !"Proxy-Authorization".equalsIgnoreCase(fieldName)
+                && !"TE".equalsIgnoreCase(fieldName)
+                && !"Trailers".equalsIgnoreCase(fieldName)
+                && !"Transfer-Encoding".equalsIgnoreCase(fieldName)
+                && !"Upgrade".equalsIgnoreCase(fieldName);
+    }
+}
diff --git a/src/main/java/libcore/net/http/RetryableOutputStream.java b/src/main/java/libcore/net/http/RetryableOutputStream.java
new file mode 100644
index 0000000..c8110be
--- /dev/null
+++ b/src/main/java/libcore/net/http/RetryableOutputStream.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import libcore.util.Libcore;
+
+/**
+ * An HTTP request body that's completely buffered in memory. This allows
+ * the post body to be transparently re-sent if the HTTP request must be
+ * sent multiple times.
+ */
+final class RetryableOutputStream extends AbstractHttpOutputStream {
+    private final int limit;
+    private final ByteArrayOutputStream content;
+
+    public RetryableOutputStream(int limit) {
+        this.limit = limit;
+        this.content = new ByteArrayOutputStream(limit);
+    }
+
+    public RetryableOutputStream() {
+        this.limit = -1;
+        this.content = new ByteArrayOutputStream();
+    }
+
+    @Override public synchronized void close() {
+        if (closed) {
+            return;
+        }
+        closed = true;
+        if (content.size() < limit) {
+            throw new IllegalStateException("content-length promised "
+                    + limit + " bytes, but received " + content.size());
+        }
+    }
+
+    @Override public synchronized void write(byte[] buffer, int offset, int count)
+            throws IOException {
+        checkNotClosed();
+        Libcore.checkOffsetAndCount(buffer.length, offset, count);
+        if (limit != -1 && content.size() > limit - count) {
+            throw new IOException("exceeded content-length limit of " + limit + " bytes");
+        }
+        content.write(buffer, offset, count);
+    }
+
+    public synchronized int contentLength() {
+        close();
+        return content.size();
+    }
+
+    public void writeToSocket(OutputStream socketOut) throws IOException  {
+        content.writeTo(socketOut);
+    }
+}
diff --git a/src/main/java/libcore/net/http/SpdyTransport.java b/src/main/java/libcore/net/http/SpdyTransport.java
new file mode 100644
index 0000000..d550ef7
--- /dev/null
+++ b/src/main/java/libcore/net/http/SpdyTransport.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.net.CacheRequest;
+import java.util.List;
+import libcore.net.spdy.SpdyConnection;
+import libcore.net.spdy.SpdyStream;
+
+final class SpdyTransport implements Transport {
+    private final HttpEngine httpEngine;
+    private final SpdyConnection spdyConnection;
+    private SpdyStream stream;
+
+    // TODO: set sentMillis
+    // TODO: set cookie stuff
+
+    SpdyTransport(HttpEngine httpEngine, SpdyConnection spdyConnection) {
+        this.httpEngine = httpEngine;
+        this.spdyConnection = spdyConnection;
+    }
+
+    @Override public OutputStream createRequestBody() throws IOException {
+        // TODO: if we aren't streaming up to the server, we should buffer the whole request
+        writeRequestHeaders();
+        return stream.getOutputStream();
+    }
+
+    @Override public void writeRequestHeaders() throws IOException {
+        if (stream != null) {
+            return;
+        }
+        RawHeaders requestHeaders = httpEngine.requestHeaders.getHeaders();
+        String version = httpEngine.connection.httpMinorVersion == 1 ? "HTTP/1.1" : "HTTP/1.0";
+        requestHeaders.addSpdyRequestHeaders(httpEngine.method, httpEngine.uri.getScheme(),
+                httpEngine.uri.getPath(), version);
+        boolean hasRequestBody = httpEngine.hasRequestBody();
+        boolean hasResponseBody = true;
+        stream = spdyConnection.newStream(requestHeaders.toNameValueBlock(),
+                hasRequestBody, hasResponseBody);
+    }
+
+    @Override public void writeRequestBody(RetryableOutputStream requestBody) throws IOException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override public void flushRequest() throws IOException {
+        stream.getOutputStream().close();
+    }
+
+    @Override public ResponseHeaders readResponseHeaders() throws IOException {
+        // TODO: fix the SPDY implementation so this throws a (buffered) IOException
+        try {
+            List<String> nameValueBlock = stream.getResponseHeaders();
+            RawHeaders rawHeaders = RawHeaders.fromNameValueBlock(nameValueBlock);
+            rawHeaders.computeResponseStatusLineFromSpdyHeaders();
+            return new ResponseHeaders(httpEngine.uri, rawHeaders);
+        } catch (InterruptedException e) {
+            InterruptedIOException rethrow = new InterruptedIOException();
+            rethrow.initCause(e);
+            throw rethrow;
+        }
+    }
+
+    @Override public InputStream getTransferStream(CacheRequest cacheRequest) throws IOException {
+        // TODO: handle HTTP responses that don't have a response body
+        return stream.getInputStream();
+    }
+
+    @Override public boolean makeReusable(OutputStream requestBodyOut, InputStream responseBodyIn) {
+        return true;
+    }
+}
diff --git a/src/main/java/libcore/net/http/Transport.java b/src/main/java/libcore/net/http/Transport.java
new file mode 100644
index 0000000..3d4c8dd
--- /dev/null
+++ b/src/main/java/libcore/net/http/Transport.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.CacheRequest;
+
+interface Transport {
+    /**
+     * Returns an output stream where the request body can be written. The
+     * returned stream will of one of two types:
+     * <ul>
+     *     <li><strong>Direct.</strong> Bytes are written to the socket and
+     *     forgotten. This is most efficient, particularly for large request
+     *     bodies. The returned stream may be buffered; the caller must call
+     *     {@link #flushRequest} before reading the response.</li>
+     *     <li><strong>Buffered.</strong> Bytes are written to an in memory
+     *     buffer, and must be explicitly flushed with a call to {@link
+     *     #writeRequestBody}. This allows HTTP authorization (401, 407)
+     *     responses to be retransmitted transparently.</li>
+     * </ul>
+     */
+    // TODO: don't bother retransmitting the request body? It's quite a corner
+    // case and there's uncertainty whether Firefox or Chrome do this
+    OutputStream createRequestBody() throws IOException;
+
+    /**
+     * This should update the HTTP engine's sentRequestMillis field.
+     */
+    void writeRequestHeaders() throws IOException;
+
+    /**
+     * Sends the request body returned by {@link #createRequestBody} to the
+     * remote peer.
+     */
+    void writeRequestBody(RetryableOutputStream requestBody) throws IOException;
+
+    /**
+     * Flush the request body to the underlying socket.
+     */
+    void flushRequest() throws IOException;
+
+    /**
+     * Read response headers and update the cookie manager.
+     */
+    ResponseHeaders readResponseHeaders() throws IOException;
+
+    // TODO: make this the content stream?
+    InputStream getTransferStream(CacheRequest cacheRequest) throws IOException;
+
+    /**
+     * Returns true if the underlying connection can be recycled.
+     */
+    boolean makeReusable(OutputStream requestBodyOut, InputStream responseBodyIn);
+}
diff --git a/src/main/java/libcore/net/spdy/IncomingStreamHandler.java b/src/main/java/libcore/net/spdy/IncomingStreamHandler.java
new file mode 100644
index 0000000..69cc8e1
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/IncomingStreamHandler.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.IOException;
+
+/**
+ * Listener to be notified when a connected peer creates a new stream.
+ */
+public interface IncomingStreamHandler {
+    IncomingStreamHandler REFUSE_INCOMING_STREAMS = new IncomingStreamHandler() {
+        @Override public void receive(SpdyStream stream) throws IOException {
+            stream.close(SpdyStream.RST_REFUSED_STREAM);
+        }
+    };
+
+    /**
+     * Handle a new stream from this connection's peer. Implementations should
+     * respond by either {@link SpdyStream#reply(java.util.List) replying to the
+     * stream} or {@link SpdyStream#close(int) closing it}. This response does
+     * not need to be synchronous.
+     */
+    void receive(SpdyStream stream) throws IOException;
+}
diff --git a/src/main/java/libcore/net/spdy/SpdyConnection.java b/src/main/java/libcore/net/spdy/SpdyConnection.java
new file mode 100644
index 0000000..44194f1
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/SpdyConnection.java
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ * A socket connection to a remote peer. A connection hosts streams which can
+ * send and receive data.
+ */
+public final class SpdyConnection implements Closeable {
+
+    /*
+     * Socket writes are guarded by this. Socket reads are unguarded but are
+     * only made by the reader thread.
+     */
+
+    static final int FLAG_FIN = 0x01;
+    static final int FLAG_UNIDIRECTIONAL = 0x02;
+
+    static final int TYPE_EOF = -1;
+    static final int TYPE_DATA = 0x00;
+    static final int TYPE_SYN_STREAM = 0x01;
+    static final int TYPE_SYN_REPLY = 0x02;
+    static final int TYPE_RST_STREAM = 0x03;
+    static final int TYPE_SETTINGS = 0x04;
+    static final int TYPE_NOOP = 0x05;
+    static final int TYPE_PING = 0x06;
+    static final int TYPE_GOAWAY = 0x07;
+    static final int TYPE_HEADERS = 0x08;
+    static final int VERSION = 2;
+
+    /** Guarded by this. */
+    private int nextStreamId;
+    private final SpdyReader spdyReader;
+    private final SpdyWriter spdyWriter;
+    private final Executor executor;
+
+    /**
+     * User code to run in response to an incoming stream. This must not be run
+     * on the read thread, otherwise a deadlock is possible.
+     */
+    private final IncomingStreamHandler handler;
+
+    private final Map<Integer, SpdyStream> streams = Collections.synchronizedMap(
+            new HashMap<Integer, SpdyStream>());
+
+    private SpdyConnection(Builder builder) {
+        nextStreamId = builder.client ? 1 : 2;
+        spdyReader = new SpdyReader(builder.in);
+        spdyWriter = new SpdyWriter(builder.out);
+        handler = builder.handler;
+
+        String name = isClient() ? "ClientReader" : "ServerReader";
+        executor = builder.executor != null
+                ? builder.executor
+                : Executors.newCachedThreadPool(Threads.newThreadFactory(name));
+        executor.execute(new Reader());
+    }
+
+    /**
+     * Returns true if this peer initiated the connection.
+     */
+    public boolean isClient() {
+        return nextStreamId % 2 == 1;
+    }
+
+    private SpdyStream getStream(int id) {
+        SpdyStream stream = streams.get(id);
+        if (stream == null) {
+            throw new UnsupportedOperationException("TODO " + id + "; " + streams); // TODO: rst stream
+        }
+        return stream;
+    }
+
+    void removeStream(int streamId) {
+        streams.remove(streamId);
+    }
+
+    /**
+     * Returns a new locally-initiated stream.
+     *
+     * @param out true to create an output stream that we can use to send data
+     *     to the remote peer. Corresponds to {@code FLAG_FIN}.
+     * @param in true to create an input stream that the remote peer can use to
+     *     send data to us. Corresponds to {@code FLAG_UNIDIRECTIONAL}.
+     */
+    public synchronized SpdyStream newStream(List<String> requestHeaders, boolean out, boolean in)
+            throws IOException {
+        int streamId = nextStreamId; // TODO
+        nextStreamId += 2;
+        int flags = (out ? 0 : FLAG_FIN) | (in ? 0 : FLAG_UNIDIRECTIONAL);
+        int associatedStreamId = 0;  // TODO
+        int priority = 0; // TODO
+
+        SpdyStream result = new SpdyStream(streamId, this, requestHeaders, flags);
+        streams.put(streamId, result);
+
+        spdyWriter.flags = flags;
+        spdyWriter.streamId = streamId;
+        spdyWriter.associatedStreamId = associatedStreamId;
+        spdyWriter.priority = priority;
+        spdyWriter.nameValueBlock = requestHeaders;
+        spdyWriter.synStream();
+
+        return result;
+    }
+
+    synchronized void writeSynReply(int streamId, List<String> alternating) throws IOException {
+        int flags = 0; // TODO
+        spdyWriter.flags = flags;
+        spdyWriter.streamId = streamId;
+        spdyWriter.nameValueBlock = alternating;
+        spdyWriter.synReply();
+    }
+
+    /** Writes a complete data frame. */
+    synchronized void writeFrame(byte[] bytes, int offset, int length) throws IOException {
+        spdyWriter.out.write(bytes, offset, length);
+    }
+
+    void writeSynResetLater(final int streamId, final int statusCode) {
+        executor.execute(new Runnable() {
+            @Override public void run() {
+                try {
+                    writeSynReset(streamId, statusCode);
+                } catch (IOException ignored) {
+                }
+            }
+        });
+    }
+
+    synchronized void writeSynReset(int streamId, int statusCode) throws IOException {
+        int flags = 0; // TODO
+        spdyWriter.flags = flags;
+        spdyWriter.streamId = streamId;
+        spdyWriter.statusCode = statusCode;
+        spdyWriter.synReset();
+    }
+
+    public synchronized void flush() throws IOException {
+        spdyWriter.out.flush();
+    }
+
+    @Override public synchronized void close() throws IOException {
+        // TODO: graceful close; send RST frames
+        // TODO: close all streams to release waiting readers
+        if (executor instanceof ExecutorService) {
+            ((ExecutorService) executor).shutdown();
+        }
+    }
+
+    public static class Builder {
+        private InputStream in;
+        private OutputStream out;
+        private IncomingStreamHandler handler = IncomingStreamHandler.REFUSE_INCOMING_STREAMS;
+        private Executor executor;
+        public boolean client;
+
+        /**
+         * @param client true if this peer initiated the connection; false if
+         *     this peer accepted the connection.
+         */
+        public Builder(boolean client, Socket socket) throws IOException {
+            this(client, socket.getInputStream(), socket.getOutputStream());
+        }
+
+        /**
+         * @param client true if this peer initiated the connection; false if this
+         *     peer accepted the connection.
+         */
+        public Builder(boolean client, InputStream in, OutputStream out) {
+            this.client = client;
+            this.in = in;
+            this.out = out;
+        }
+
+        public Builder executor(Executor executor) {
+            this.executor = executor;
+            return this;
+        }
+
+        public Builder handler(IncomingStreamHandler handler) {
+            this.handler = handler;
+            return this;
+        }
+
+        public SpdyConnection build() {
+            return new SpdyConnection(this);
+        }
+    }
+
+    private class Reader implements Runnable {
+        @Override public void run() {
+            try {
+                while (readFrame()) {
+                }
+                close();
+            } catch (Throwable e) {
+                e.printStackTrace(); // TODO
+            }
+        }
+
+        private boolean readFrame() throws IOException {
+            switch (spdyReader.nextFrame()) {
+            case TYPE_EOF:
+                return false;
+
+            case TYPE_DATA:
+                getStream(spdyReader.streamId)
+                        .receiveData(spdyReader.in, spdyReader.flags, spdyReader.length);
+                return true;
+
+            case TYPE_SYN_STREAM:
+                final SpdyStream stream = new SpdyStream(spdyReader.streamId, SpdyConnection.this,
+                        spdyReader.nameValueBlock, spdyReader.flags);
+                SpdyStream previous = streams.put(spdyReader.streamId, stream);
+                if (previous != null) {
+                    previous.close(SpdyStream.RST_PROTOCOL_ERROR);
+                }
+                executor.execute(new Runnable() {
+                    @Override public void run() {
+                        try {
+                            handler.receive(stream);
+                        } catch (IOException e) {
+                            throw new RuntimeException(e);
+                        }
+                    }
+                });
+                return true;
+
+            case TYPE_SYN_REPLY:
+                // TODO: honor flags
+                getStream(spdyReader.streamId).receiveReply(spdyReader.nameValueBlock);
+                return true;
+
+            case TYPE_RST_STREAM:
+                getStream(spdyReader.streamId).receiveRstStream(spdyReader.statusCode);
+                return true;
+
+            case SpdyConnection.TYPE_SETTINGS:
+                // TODO: implement
+                System.out.println("Unimplemented TYPE_SETTINGS frame discarded");
+                return true;
+
+            case SpdyConnection.TYPE_NOOP:
+            case SpdyConnection.TYPE_PING:
+            case SpdyConnection.TYPE_GOAWAY:
+            case SpdyConnection.TYPE_HEADERS:
+                throw new UnsupportedOperationException();
+
+            default:
+                // TODO: throw IOException here?
+                return false;
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/spdy/SpdyReader.java b/src/main/java/libcore/net/spdy/SpdyReader.java
new file mode 100644
index 0000000..38557c9
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/SpdyReader.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+import java.util.zip.DataFormatException;
+import java.util.zip.Inflater;
+import java.util.zip.InflaterInputStream;
+import libcore.io.Streams;
+
+/**
+ * Read version 2 SPDY frames.
+ */
+final class SpdyReader {
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+    private static final String DICTIONARY_STRING = ""
+            + "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-"
+            + "languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchi"
+            + "f-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser"
+            + "-agent10010120020120220320420520630030130230330430530630740040140240340440"
+            + "5406407408409410411412413414415416417500501502503504505accept-rangesageeta"
+            + "glocationproxy-authenticatepublicretry-afterservervarywarningwww-authentic"
+            + "ateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertran"
+            + "sfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locati"
+            + "oncontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMo"
+            + "ndayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSe"
+            + "pOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplic"
+            + "ation/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1"
+            + ".1statusversionurl\0";
+    public static final byte[] DICTIONARY;
+    static {
+        try {
+            DICTIONARY = DICTIONARY_STRING.getBytes("UTF-8");
+        } catch (UnsupportedEncodingException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    public final DataInputStream in;
+    public int flags;
+    public int length;
+    public int streamId;
+    public int associatedStreamId;
+    public int version;
+    public int type;
+    public int priority;
+    public int statusCode;
+
+    public List<String> nameValueBlock;
+    private final DataInputStream nameValueBlockIn;
+    private int compressedLimit;
+
+    SpdyReader(InputStream in) {
+        this.in = new DataInputStream(in);
+        this.nameValueBlockIn = newNameValueBlockStream();
+    }
+
+    /**
+     * Advance to the next frame in the source data. If the frame is of
+     * TYPE_DATA, it's the caller's responsibility to read length bytes from
+     * the input stream before the next call to nextFrame().
+     */
+    public int nextFrame() throws IOException {
+        int w1;
+        try {
+            w1 = in.readInt();
+        } catch (EOFException e) {
+            return SpdyConnection.TYPE_EOF;
+        }
+        int w2 = in.readInt();
+
+        boolean control = (w1 & 0x80000000) != 0;
+        flags = (w2 & 0xff000000) >>> 24;
+        length = (w2 & 0xffffff);
+
+        if (control) {
+            version = (w1 & 0x7fff0000) >>> 16;
+            type = (w1 & 0xffff);
+
+            switch (type) {
+            case SpdyConnection.TYPE_SYN_STREAM:
+                readSynStream();
+                return SpdyConnection.TYPE_SYN_STREAM;
+
+            case SpdyConnection.TYPE_SYN_REPLY:
+                readSynReply();
+                return SpdyConnection.TYPE_SYN_REPLY;
+
+            case SpdyConnection.TYPE_RST_STREAM:
+                readSynReset();
+                return SpdyConnection.TYPE_RST_STREAM;
+
+            default:
+                readControlFrame();
+                return type;
+            }
+        } else {
+            streamId = w1 & 0x7fffffff;
+            return SpdyConnection.TYPE_DATA;
+        }
+    }
+
+    private void readSynStream() throws IOException {
+        int w1 = in.readInt();
+        int w2 = in.readInt();
+        int s3 = in.readShort();
+        streamId = w1 & 0x7fffffff;
+        associatedStreamId = w2 & 0x7fffffff;
+        priority = s3 & 0xc000 >> 14;
+        // int unused = s3 & 0x3fff;
+        nameValueBlock = readNameValueBlock(length - 10);
+    }
+
+    private void readSynReply() throws IOException {
+        int w1 = in.readInt();
+        in.readShort(); // unused
+        streamId = w1 & 0x7fffffff;
+        nameValueBlock = readNameValueBlock(length - 6);
+    }
+
+    private void readSynReset() throws IOException {
+        streamId = in.readInt() & 0x7fffffff;
+        statusCode = in.readInt();
+    }
+
+    private void readControlFrame() throws IOException {
+        Streams.skipByReading(in, length);
+    }
+
+    private DataInputStream newNameValueBlockStream() {
+        // Limit the inflater input stream to only those bytes in the Name/Value block.
+        final InputStream throttleStream = new InputStream() {
+            @Override public int read() throws IOException {
+                return Streams.readSingleByte(this);
+            }
+
+            @Override public int read(byte[] buffer, int offset, int byteCount) throws IOException {
+                byteCount = Math.min(byteCount, compressedLimit);
+                int consumed = in.read(buffer, offset, byteCount);
+                compressedLimit -= consumed;
+                return consumed;
+            }
+
+            @Override public void close() throws IOException {
+                in.close();
+            }
+        };
+
+        // Subclass inflater to install a dictionary when it's needed.
+        Inflater inflater = new Inflater() {
+            @Override
+            public int inflate(byte[] buffer, int offset, int count) throws DataFormatException {
+                int result = super.inflate(buffer, offset, count);
+                if (result == 0 && needsDictionary()) {
+                    setDictionary(DICTIONARY);
+                    result = super.inflate(buffer, offset, count);
+                }
+                return result;
+            }
+        };
+
+        return new DataInputStream(new InflaterInputStream(throttleStream, inflater));
+    }
+
+    private List<String> readNameValueBlock(int length) throws IOException {
+        this.compressedLimit += length;
+        try {
+            List<String> entries = new ArrayList<String>();
+
+            int numberOfPairs = nameValueBlockIn.readShort();
+            for (int i = 0; i < numberOfPairs; i++) {
+                String name = readString();
+                String values = readString();
+                if (name.length() == 0 || values.length() == 0) {
+                    throw new IOException(); // TODO: PROTOCOL ERROR
+                }
+                entries.add(name);
+                entries.add(values);
+            }
+
+            if (compressedLimit != 0) {
+                Logger.getLogger(getClass().getName())
+                        .warning("compressedLimit > 0" + compressedLimit);
+            }
+
+            return entries;
+        } catch (DataFormatException e) {
+            throw new IOException(e);
+        }
+    }
+
+    private String readString() throws DataFormatException, IOException {
+        int length = nameValueBlockIn.readShort();
+        byte[] bytes = new byte[length];
+        Streams.readFully(nameValueBlockIn, bytes);
+        return new String(bytes, 0, length, "UTF-8");
+    }
+}
diff --git a/src/main/java/libcore/net/spdy/SpdyServer.java b/src/main/java/libcore/net/spdy/SpdyServer.java
new file mode 100644
index 0000000..52af83c
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/SpdyServer.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A basic SPDY server that serves the contents of a local directory. This
+ * server will service a single SPDY connection.
+ */
+public final class SpdyServer implements IncomingStreamHandler {
+    private final File baseDirectory;
+
+    public SpdyServer(File baseDirectory) {
+        this.baseDirectory = baseDirectory;
+    }
+
+    private void run() throws IOException {
+        ServerSocket serverSocket = new ServerSocket(8888);
+        serverSocket.setReuseAddress(true);
+
+        Socket socket = serverSocket.accept();
+        new SpdyConnection.Builder(false, socket)
+                .handler(this)
+                .build();
+    }
+
+    @Override public void receive(final SpdyStream stream) throws IOException {
+        List<String> requestHeaders = stream.getRequestHeaders();
+        String path = null;
+        for (int i = 0; i < requestHeaders.size(); i += 2) {
+            String s = requestHeaders.get(i);
+            if ("url".equals(s)) {
+                path = requestHeaders.get(i + 1);
+                break;
+            }
+        }
+
+        if (path == null) {
+            // TODO: send bad request error
+            throw new AssertionError();
+        }
+
+        File file = new File(baseDirectory + path);
+
+        if (file.exists() && !file.isDirectory()) {
+            serveFile(stream, file);
+        } else {
+            send404(stream, path);
+        }
+    }
+
+    private void send404(SpdyStream stream, String path) throws IOException {
+        List<String> responseHeaders = Arrays.asList(
+                "status", "404",
+                "version", "HTTP/1.1",
+                "content-type", "text/plain"
+        );
+        OutputStream out = stream.reply(responseHeaders);
+        String text = "Not found: " + path;
+        out.write(text.getBytes("UTF-8"));
+        out.close();
+    }
+
+    private void serveFile(SpdyStream stream, File file) throws IOException {
+        InputStream in = new FileInputStream(file);
+        byte[] buffer = new byte[8192];
+        OutputStream out = stream.reply(Arrays.asList(
+                "status", "200",
+                "version", "HTTP/1.1",
+                "content-type", contentType(file)
+        ));
+        int count;
+        while ((count = in.read(buffer)) != -1) {
+            out.write(buffer, 0, count);
+        }
+        out.close();
+    }
+
+    private String contentType(File file) {
+        return file.getName().endsWith(".html") ? "text/html" : "text/plain";
+    }
+
+    public static void main(String... args) throws IOException {
+        if (args.length != 1 || args[0].startsWith("-")) {
+            System.out.println("Usage: SpdyServer <base directory>");
+            return;
+        }
+
+        new SpdyServer(new File(args[0])).run();
+    }
+}
diff --git a/src/main/java/libcore/net/spdy/SpdyStream.java b/src/main/java/libcore/net/spdy/SpdyStream.java
new file mode 100644
index 0000000..4588a4a
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/SpdyStream.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.util.List;
+import libcore.io.Streams;
+import libcore.util.Libcore;
+
+import static java.nio.ByteOrder.BIG_ENDIAN;
+
+/**
+ * A logical bidirectional stream.
+ */
+public final class SpdyStream {
+
+    /*
+     * Internal state is guarded by this. No long-running or potentially
+     * blocking operations are performed while the lock is held.
+     */
+
+    private static final int DATA_FRAME_HEADER_LENGTH = 8;
+
+    public static final int RST_PROTOCOL_ERROR = 1;
+    public static final int RST_INVALID_STREAM = 2;
+    public static final int RST_REFUSED_STREAM = 3;
+    public static final int RST_UNSUPPORTED_VERSION = 4;
+    public static final int RST_CANCEL = 5;
+    public static final int RST_INTERNAL_ERROR = 6;
+    public static final int RST_FLOW_CONTROL_ERROR = 7;
+
+    private final int id;
+    private final SpdyConnection connection;
+
+    /** Headers sent by the stream initiator. Immutable and non null. */
+    private final List<String> requestHeaders;
+
+    /** Headers sent in the stream reply. Null if reply is either not sent or not sent yet. */
+    private List<String> responseHeaders;
+
+    private final SpdyDataInputStream in = new SpdyDataInputStream();
+    private final SpdyDataOutputStream out = new SpdyDataOutputStream();
+
+    /**
+     * The reason why this stream was abnormally closed. If there are multiple
+     * reasons to abnormally close this stream (such as both peers closing it
+     * near-simultaneously) then this is the first reason known to this peer.
+     */
+    private int rstStatusCode = -1;
+
+    /**
+     * True if either side has shut down the input stream. We will receive no
+     * more bytes beyond those already in the buffer. Guarded by this.
+     */
+    private boolean inFinished;
+
+    /**
+     * True if either side has shut down the output stream. We will write no
+     * more bytes to the output stream. Guarded by this.
+     */
+    private boolean outFinished;
+
+    SpdyStream(int id, SpdyConnection connection, List<String> requestHeaders, int flags) {
+        this.id = id;
+        this.connection = connection;
+        this.requestHeaders = requestHeaders;
+
+        if (isLocallyInitiated()) {
+            // I am the sender
+            inFinished = (flags & SpdyConnection.FLAG_UNIDIRECTIONAL) != 0;
+            outFinished = (flags & SpdyConnection.FLAG_FIN) != 0;
+        } else {
+            // I am the receiver
+            inFinished = (flags & SpdyConnection.FLAG_FIN) != 0;
+            outFinished = (flags & SpdyConnection.FLAG_UNIDIRECTIONAL) != 0;
+        }
+    }
+
+    /**
+     * Returns true if this stream was created by this peer.
+     */
+    public boolean isLocallyInitiated() {
+        boolean streamIsClient = (id % 2 == 1);
+        return connection.isClient() == streamIsClient;
+    }
+
+    public SpdyConnection getConnection() {
+        return connection;
+    }
+
+    public List<String> getRequestHeaders() {
+        return requestHeaders;
+    }
+
+    public synchronized List<String> getResponseHeaders() throws InterruptedException {
+        while (responseHeaders == null && rstStatusCode == -1) {
+            wait();
+        }
+        return responseHeaders;
+    }
+
+    /**
+     * Returns the reason why this stream was closed, or -1 if it closed
+     * normally or has not yet been closed.
+     */
+    public synchronized int getRstStatusCode() { // TODO: rename this?
+        return rstStatusCode;
+    }
+
+    public InputStream getInputStream() {
+        return in;
+    }
+
+    public OutputStream getOutputStream() {
+        if (!isLocallyInitiated()) {
+            throw new IllegalStateException("use reply for a remotely initiated stream");
+        }
+        return out;
+    }
+
+    /**
+     * Sends a reply.
+     */
+    // TODO: support reply with FIN
+    public synchronized OutputStream reply(List<String> responseHeaders) throws IOException {
+        if (responseHeaders == null) {
+            throw new NullPointerException("responseHeaders == null");
+        }
+        if (isLocallyInitiated()) {
+            throw new IllegalStateException("cannot reply to a locally initiated stream");
+        }
+        synchronized (this) {
+            if (this.responseHeaders != null) {
+                throw new IllegalStateException("reply already sent");
+            }
+            this.responseHeaders = responseHeaders;
+        }
+        connection.writeSynReply(id, responseHeaders);
+        return out;
+    }
+
+    /**
+     * Abnormally terminate this stream.
+     */
+    public synchronized void close(int rstStatusCode) {
+        // TODO: no-op if inFinished == true and outFinished == true ?
+        if (this.rstStatusCode != -1) {
+            this.rstStatusCode = rstStatusCode;
+            inFinished = true;
+            outFinished = true;
+            connection.removeStream(id);
+            notifyAll();
+            connection.writeSynResetLater(id, rstStatusCode);
+        }
+    }
+
+    synchronized void receiveReply(List<String> strings) throws IOException {
+        if (!isLocallyInitiated() || responseHeaders != null) {
+            throw new IOException(); // TODO: send RST
+        }
+        responseHeaders = strings;
+        notifyAll();
+    }
+
+    synchronized void receiveData(InputStream in, int flags, int length) throws IOException {
+        this.in.receive(in, length);
+        if ((flags & SpdyConnection.FLAG_FIN) != 0) {
+            inFinished = true;
+            notifyAll();
+        }
+    }
+
+    synchronized void receiveRstStream(int statusCode) {
+        if (rstStatusCode != -1) {
+            rstStatusCode = statusCode;
+            inFinished = true;
+            outFinished = true;
+            notifyAll();
+        }
+    }
+
+    /**
+     * An input stream that reads the incoming data frames of a stream. Although
+     * this class uses synchronization to safely receive incoming data frames,
+     * it is not intended for use by multiple readers.
+     */
+    private final class SpdyDataInputStream extends InputStream {
+        /*
+         * Store incoming data bytes in a circular buffer. When the buffer is
+         * empty, pos == -1. Otherwise pos is the first byte to read and limit
+         * is the first byte to write.
+         *
+         * { - - - X X X X - - - }
+         *         ^       ^
+         *        pos    limit
+         *
+         * { X X X - - - - X X X }
+         *         ^       ^
+         *       limit    pos
+         */
+
+        private final byte[] buffer = new byte[64 * 1024]; // 64KiB specified by TODO
+        /** the next byte to be read, or -1 if the buffer is empty. Never buffer.length */
+        private int pos = -1;
+        /** the last byte to be read. Never buffer.length */
+        private int limit;
+        /** True if the caller has closed this stream. */
+        private boolean closed;
+
+        @Override public int available() throws IOException {
+            synchronized (SpdyStream.this) {
+                checkNotClosed();
+                if (pos == -1) {
+                    return 0;
+                } else if (limit > pos) {
+                    return limit - pos;
+                } else {
+                    return limit + (buffer.length - pos);
+                }
+            }
+        }
+
+        @Override public int read() throws IOException {
+            return Streams.readSingleByte(this);
+        }
+
+        @Override public int read(byte[] b, int offset, int count) throws IOException {
+            synchronized (SpdyStream.this) {
+                checkNotClosed();
+                Libcore.checkOffsetAndCount(b.length, offset, count);
+
+                while (pos == -1 && !inFinished) {
+                    try {
+                        SpdyStream.this.wait();
+                    } catch (InterruptedException e) {
+                        throw new InterruptedIOException();
+                    }
+                }
+
+                if (pos == -1) {
+                    return -1;
+                }
+
+                int copied = 0;
+
+                // drain from [pos..buffer.length)
+                if (limit <= pos) {
+                    int bytesToCopy = Math.min(count, buffer.length - pos);
+                    System.arraycopy(buffer, pos, b, offset, bytesToCopy);
+                    pos += bytesToCopy;
+                    copied += bytesToCopy;
+                    if (pos == buffer.length) {
+                        pos = 0;
+                    }
+                }
+
+                // drain from [pos..limit)
+                if (copied < count) {
+                    int bytesToCopy = Math.min(limit - pos, count - copied);
+                    System.arraycopy(buffer, pos, b, offset + copied, bytesToCopy);
+                    pos += bytesToCopy;
+                    copied += bytesToCopy;
+                }
+
+                // TODO: notify peer of flow-control
+
+                if (pos == limit) {
+                    pos = -1;
+                    limit = 0;
+                }
+
+                return copied;
+            }
+        }
+
+        void receive(InputStream in, int byteCount) throws IOException {
+            if (inFinished) {
+                return; // ignore this; probably a benign race
+            }
+            if (byteCount == 0) {
+                return;
+            }
+
+            if (byteCount > buffer.length - available()) {
+                throw new IOException(); // TODO: RST the stream
+            }
+
+            // fill [limit..buffer.length)
+            if (pos < limit) {
+                int firstCopyCount = Math.min(byteCount, buffer.length - limit);
+                Streams.readFully(in, buffer, limit, firstCopyCount);
+                limit += firstCopyCount;
+                byteCount -= firstCopyCount;
+                if (limit == buffer.length) {
+                    limit = 0;
+                }
+            }
+
+            // fill [limit..pos)
+            if (byteCount > 0) {
+                Streams.readFully(in, buffer, limit, byteCount);
+                limit += byteCount;
+            }
+
+            if (pos == -1) {
+                pos = 0;
+                SpdyStream.this.notifyAll();
+            }
+        }
+
+        @Override public void close() throws IOException {
+            closed = true;
+            // TODO: send RST to peer if !inFinished
+        }
+
+        private void checkNotClosed() throws IOException {
+            if (closed) {
+                throw new IOException("stream closed");
+            }
+        }
+    }
+
+    /**
+     * An output stream that writes outgoing data frames of a stream. This class
+     * is not thread safe.
+     */
+    private final class SpdyDataOutputStream extends OutputStream {
+        private final byte[] buffer = new byte[8192];
+        private int pos = DATA_FRAME_HEADER_LENGTH;
+
+        /** True if the caller has closed this stream. */
+        private boolean closed;
+
+        @Override public void write(int b) throws IOException {
+            Streams.writeSingleByte(this, b);
+        }
+
+        @Override public void write(byte[] bytes, int offset, int count) throws IOException {
+            Libcore.checkOffsetAndCount(bytes.length, offset, count);
+            checkNotClosed();
+
+            while (count > 0) {
+                if (pos == buffer.length) {
+                    writeFrame(false);
+                }
+                int bytesToCopy = Math.min(count, buffer.length - pos);
+                System.arraycopy(bytes, offset, buffer, pos, bytesToCopy);
+                pos += bytesToCopy;
+                offset += bytesToCopy;
+                count -= bytesToCopy;
+            }
+        }
+
+        @Override public void flush() throws IOException {
+            checkNotClosed();
+            if (pos > DATA_FRAME_HEADER_LENGTH) {
+                writeFrame(false);
+                connection.flush();
+            }
+        }
+
+        @Override public void close() throws IOException {
+            if (!closed) {
+                closed = true;
+                writeFrame(true);
+                connection.flush();
+            }
+        }
+
+        private void writeFrame(boolean last) throws IOException {
+            int flags = 0;
+            if (last) {
+                flags |= SpdyConnection.FLAG_FIN;
+            }
+            int length = pos - DATA_FRAME_HEADER_LENGTH;
+            Libcore.pokeInt(buffer, 0, id & 0x7fffffff, BIG_ENDIAN);
+            Libcore.pokeInt(buffer, 4, (flags & 0xff) << 24 | length & 0xffffff, BIG_ENDIAN);
+            connection.writeFrame(buffer, 0, pos);
+            pos = DATA_FRAME_HEADER_LENGTH;
+        }
+
+        private void checkNotClosed() throws IOException {
+            synchronized (SpdyStream.this) {
+                if (closed) {
+                    throw new IOException("stream closed");
+                }
+                if (outFinished) {
+                    throw new IOException("output stream finished "
+                            + "(RST status code=" + rstStatusCode + ")");
+                }
+            }
+        }
+    }
+}
diff --git a/src/main/java/libcore/net/spdy/SpdyWriter.java b/src/main/java/libcore/net/spdy/SpdyWriter.java
new file mode 100644
index 0000000..5bc4644
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/SpdyWriter.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+
+/**
+ * Write version 2 SPDY frames.
+ */
+final class SpdyWriter {
+    final DataOutputStream out;
+    public int flags;
+    public int streamId;
+    public int associatedStreamId;
+    public int priority;
+    public int statusCode;
+
+    public List<String> nameValueBlock;
+    private final ByteArrayOutputStream nameValueBlockBuffer;
+    private final DataOutputStream nameValueBlockOut;
+
+    SpdyWriter(OutputStream out) {
+        this.out = new DataOutputStream(out);
+
+        Deflater deflater = new Deflater();
+        deflater.setDictionary(SpdyReader.DICTIONARY);
+        nameValueBlockBuffer = new ByteArrayOutputStream();
+        nameValueBlockOut = new DataOutputStream(
+                new DeflaterOutputStream(nameValueBlockBuffer, deflater, true));
+    }
+
+    public void synStream() throws IOException {
+        writeNameValueBlockToBuffer();
+        int length = 10 + nameValueBlockBuffer.size();
+        int type = SpdyConnection.TYPE_SYN_STREAM;
+
+        int unused = 0;
+        out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+        out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+        out.writeInt(streamId & 0x7fffffff);
+        out.writeInt(associatedStreamId & 0x7fffffff);
+        out.writeShort((priority & 0x3) << 30 | (unused & 0x3FFF) << 16);
+        nameValueBlockBuffer.writeTo(out);
+        out.flush();
+    }
+
+    public void synReply() throws IOException {
+        writeNameValueBlockToBuffer();
+        int type = SpdyConnection.TYPE_SYN_REPLY;
+        int length = nameValueBlockBuffer.size() + 6;
+        int unused = 0;
+
+        out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+        out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+        out.writeInt(streamId & 0x7fffffff);
+        out.writeShort(unused);
+        nameValueBlockBuffer.writeTo(out);
+        out.flush();
+    }
+
+    public void synReset() throws IOException {
+        int type = SpdyConnection.TYPE_RST_STREAM;
+        int length = 8;
+        out.writeInt(0x80000000 | (SpdyConnection.VERSION & 0x7fff) << 16 | type & 0xffff);
+        out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+        out.writeInt(streamId & 0x7fffffff);
+        out.writeInt(statusCode);
+    }
+
+    public void data(byte[] data) throws IOException {
+        int length = data.length;
+        out.writeInt(streamId & 0x7fffffff);
+        out.writeInt((flags & 0xff) << 24 | length & 0xffffff);
+        out.write(data);
+        out.flush();
+    }
+
+    private void writeNameValueBlockToBuffer() throws IOException {
+        nameValueBlockBuffer.reset();
+        int numberOfPairs = nameValueBlock.size() / 2;
+        nameValueBlockOut.writeShort(numberOfPairs);
+        for (String s : nameValueBlock) {
+            nameValueBlockOut.writeShort(s.length());
+            nameValueBlockOut.write(s.getBytes("UTF-8"));
+        }
+        nameValueBlockOut.flush();
+    }
+}
diff --git a/src/main/java/libcore/net/spdy/Threads.java b/src/main/java/libcore/net/spdy/Threads.java
new file mode 100644
index 0000000..a1fbf67
--- /dev/null
+++ b/src/main/java/libcore/net/spdy/Threads.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.util.concurrent.ThreadFactory;
+
+final class Threads {
+    public static ThreadFactory newThreadFactory(final String name) {
+        return new ThreadFactory() {
+            @Override public Thread newThread(Runnable r) {
+                return new Thread(r, name);
+            }
+        };
+    }
+
+    private Threads() {
+    }
+}
diff --git a/src/main/java/libcore/util/BasicLruCache.java b/src/main/java/libcore/util/BasicLruCache.java
new file mode 100644
index 0000000..b5f6fdf
--- /dev/null
+++ b/src/main/java/libcore/util/BasicLruCache.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * A minimal least-recently-used cache for libcore. Prefer {@code
+ * android.util.LruCache} where that is available.
+ */
+public class BasicLruCache<K, V> {
+    private final LinkedHashMap<K, V> map;
+    private final int maxSize;
+
+    public BasicLruCache(int maxSize) {
+        if (maxSize <= 0) {
+            throw new IllegalArgumentException("maxSize <= 0");
+        }
+        this.maxSize = maxSize;
+        this.map = new LinkedHashMap<K, V>(0, 0.75f, true);
+    }
+
+    /**
+     * Returns the value for {@code key} if it exists in the cache or can be
+     * created by {@code #create}. If a value was returned, it is moved to the
+     * head of the queue. This returns null if a value is not cached and cannot
+     * be created.
+     */
+    public synchronized final V get(K key) {
+        if (key == null) {
+            throw new NullPointerException();
+        }
+
+        V result = map.get(key);
+        if (result != null) {
+            return result;
+        }
+
+        result = create(key);
+
+        if (result != null) {
+            map.put(key, result);
+            trimToSize(maxSize);
+        }
+        return result;
+    }
+
+    /**
+     * Caches {@code value} for {@code key}. The value is moved to the head of
+     * the queue.
+     *
+     * @return the previous value mapped by {@code key}. Although that entry is
+     *     no longer cached, it has not been passed to {@link #entryEvicted}.
+     */
+    public synchronized final V put(K key, V value) {
+        if (key == null || value == null) {
+            throw new NullPointerException();
+        }
+
+        V previous = map.put(key, value);
+        trimToSize(maxSize);
+        return previous;
+    }
+
+    private void trimToSize(int maxSize) {
+        while (map.size() > maxSize) {
+            Map.Entry<K, V> toEvict = map.entrySet().iterator().next();
+
+            K key = toEvict.getKey();
+            V value = toEvict.getValue();
+            map.remove(key);
+
+            entryEvicted(key, value);
+        }
+    }
+
+    /**
+     * Called for entries that have reached the tail of the least recently used
+     * queue and are be removed. The default implementation does nothing.
+     */
+    protected void entryEvicted(K key, V value) {
+    }
+
+    /**
+     * Called after a cache miss to compute a value for the corresponding key.
+     * Returns the computed value or null if no value can be computed. The
+     * default implementation returns null.
+     */
+    protected V create(K key) {
+        return null;
+    }
+
+    /**
+     * Returns a copy of the current contents of the cache, ordered from least
+     * recently accessed to most recently accessed.
+     */
+    public synchronized final Map<K, V> snapshot() {
+        return new LinkedHashMap<K, V>(map);
+    }
+
+    /**
+     * Clear the cache, calling {@link #entryEvicted} on each removed entry.
+     */
+    public synchronized final void evictAll() {
+        trimToSize(0);
+    }
+}
diff --git a/src/main/java/libcore/util/Charsets.java b/src/main/java/libcore/util/Charsets.java
new file mode 100644
index 0000000..95848ee
--- /dev/null
+++ b/src/main/java/libcore/util/Charsets.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import java.nio.charset.Charset;
+
+/**
+ * Provides convenient access to the most important built-in charsets. Saves a hash lookup and
+ * unnecessary handling of UnsupportedEncodingException at call sites, compared to using the
+ * charset's name.
+ *
+ * Also various special-case charset conversions (for performance).
+ *
+ * @hide internal use only
+ */
+public final class Charsets {
+    /**
+     * A cheap and type-safe constant for the ISO-8859-1 Charset.
+     */
+    public static final Charset ISO_8859_1 = Charset.forName("ISO-8859-1");
+
+    /**
+     * A cheap and type-safe constant for the US-ASCII Charset.
+     */
+    public static final Charset US_ASCII = Charset.forName("US-ASCII");
+
+    /**
+     * A cheap and type-safe constant for the UTF-8 Charset.
+     */
+    public static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    private Charsets() {
+    }
+}
diff --git a/src/main/java/libcore/util/CollectionUtils.java b/src/main/java/libcore/util/CollectionUtils.java
new file mode 100644
index 0000000..45edf4f
--- /dev/null
+++ b/src/main/java/libcore/util/CollectionUtils.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import java.lang.ref.Reference;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.List;
+
+public final class CollectionUtils {
+    private CollectionUtils() {
+    }
+
+    /**
+     * Returns an iterator over the values referenced by the elements of {@code
+     * iterable}.
+     *
+     * @param trim true to remove reference objects from the iterable after
+     *     their referenced values have been cleared.
+     */
+    public static <T> Iterable<T> dereferenceIterable(
+            final Iterable<? extends Reference<T>> iterable, final boolean trim) {
+        return new Iterable<T>() {
+            public Iterator<T> iterator() {
+                return new Iterator<T>() {
+                    private final Iterator<? extends Reference<T>> delegate = iterable.iterator();
+                    private boolean removeIsOkay;
+                    private T next;
+
+                    private void computeNext() {
+                        removeIsOkay = false;
+                        while (next == null && delegate.hasNext()) {
+                            next = delegate.next().get();
+                            if (trim && next == null) {
+                                delegate.remove();
+                            }
+                        }
+                    }
+
+                    @Override public boolean hasNext() {
+                        computeNext();
+                        return next != null;
+                    }
+
+                    @Override public T next() {
+                        if (!hasNext()) {
+                            throw new IllegalStateException();
+                        }
+                        T result = next;
+                        removeIsOkay = true;
+                        next = null;
+                        return result;
+                    }
+
+                    public void remove() {
+                        if (!removeIsOkay) {
+                            throw new IllegalStateException();
+                        }
+                        delegate.remove();
+                    }
+                };
+            }
+        };
+    }
+
+    /**
+     * Sorts and removes duplicate elements from {@code list}. This method does
+     * not use {@link Object#equals}: only the comparator defines equality.
+     */
+    public static <T> void removeDuplicates(List<T> list, Comparator<? super T> comparator) {
+        Collections.sort(list, comparator);
+        int j = 1;
+        for (int i = 1; i < list.size(); i++) {
+            if (comparator.compare(list.get(j - 1), list.get(i)) != 0) {
+                T object = list.get(i);
+                list.set(j++, object);
+            }
+        }
+        if (j < list.size()) {
+            list.subList(j, list.size()).clear();
+        }
+    }
+}
diff --git a/src/main/java/libcore/util/DefaultFileNameMap.java b/src/main/java/libcore/util/DefaultFileNameMap.java
new file mode 100644
index 0000000..e817a72
--- /dev/null
+++ b/src/main/java/libcore/util/DefaultFileNameMap.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import java.net.FileNameMap;
+import java.util.Locale;
+import libcore.net.MimeUtils;
+
+/**
+ * Implements {@link java.net.FileNameMap} in terms of {@link libcore.net.MimeUtils}.
+ */
+class DefaultFileNameMap implements FileNameMap {
+    public String getContentTypeFor(String filename) {
+        if (filename.endsWith("/")) {
+            // a directory, return html
+            return MimeUtils.guessMimeTypeFromExtension("html");
+        }
+        int lastCharInExtension = filename.lastIndexOf('#');
+        if (lastCharInExtension < 0) {
+            lastCharInExtension = filename.length();
+        }
+        int firstCharInExtension = filename.lastIndexOf('.') + 1;
+        String ext = "";
+        if (firstCharInExtension > filename.lastIndexOf('/')) {
+            ext = filename.substring(firstCharInExtension, lastCharInExtension);
+        }
+        return MimeUtils.guessMimeTypeFromExtension(ext.toLowerCase(Locale.US));
+    }
+}
diff --git a/src/main/java/libcore/util/EmptyArray.java b/src/main/java/libcore/util/EmptyArray.java
new file mode 100644
index 0000000..0f919c5
--- /dev/null
+++ b/src/main/java/libcore/util/EmptyArray.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class EmptyArray {
+    private EmptyArray() {
+    }
+
+    public static final boolean[] BOOLEAN = new boolean[0];
+    public static final byte[] BYTE = new byte[0];
+    public static final char[] CHAR = new char[0];
+    public static final double[] DOUBLE = new double[0];
+    public static final int[] INT = new int[0];
+
+    public static final Class<?>[] CLASS = new Class[0];
+    public static final Object[] OBJECT = new Object[0];
+    public static final String[] STRING = new String[0];
+    public static final Throwable[] THROWABLE = new Throwable[0];
+    public static final StackTraceElement[] STACK_TRACE_ELEMENT = new StackTraceElement[0];
+}
diff --git a/src/main/java/libcore/util/ExtendedResponseCache.java b/src/main/java/libcore/util/ExtendedResponseCache.java
new file mode 100644
index 0000000..b3f9191
--- /dev/null
+++ b/src/main/java/libcore/util/ExtendedResponseCache.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+import com.squareup.okhttp.OkHttpConnection;
+import java.net.CacheResponse;
+
+/**
+ * A response cache that supports statistics tracking and updating stored
+ * responses. Implementations of {@link java.net.ResponseCache} should implement this
+ * interface to receive additional support from the HTTP engine.
+ *
+ * @hide
+ */
+public interface ExtendedResponseCache {
+
+    /*
+     * This hidden interface is defined in a non-hidden package (java.net) so
+     * its @hide tag will be parsed by Doclava. This hides this interface from
+     * implementing classes' documentation.
+     */
+
+    /**
+     * Track an HTTP response being satisfied by {@code source}.
+     * @hide
+     */
+    void trackResponse(ResponseSource source);
+
+    /**
+     * Track an conditional GET that was satisfied by this cache.
+     * @hide
+     */
+    void trackConditionalCacheHit();
+
+    /**
+     * Updates stored HTTP headers using a hit on a conditional GET.
+     * @hide
+     */
+    void update(CacheResponse conditionalCacheHit, OkHttpConnection httpConnection);
+}
diff --git a/src/main/java/libcore/util/IntegralToString.java b/src/main/java/libcore/util/IntegralToString.java
new file mode 100644
index 0000000..1b66e51
--- /dev/null
+++ b/src/main/java/libcore/util/IntegralToString.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Converts integral types to strings. This class is public but hidden so that it can also be
+ * used by java.util.Formatter to speed up %d. This class is in java.lang so that it can take
+ * advantage of the package-private String constructor.
+ *
+ * The most important methods are appendInt/appendLong and intToString(int)/longToString(int).
+ * The former are used in the implementation of StringBuilder, StringBuffer, and Formatter, while
+ * the latter are used by Integer.toString and Long.toString.
+ *
+ * The append methods take AbstractStringBuilder rather than Appendable because the latter requires
+ * CharSequences, while we only have raw char[]s. Since much of the savings come from not creating
+ * any garbage, we can't afford temporary CharSequence instances.
+ *
+ * One day the performance advantage of the binary/hex/octal specializations will be small enough
+ * that we can lose the duplication, but until then this class offers the full set.
+ *
+ * @hide
+ */
+public final class IntegralToString {
+    /**
+     * The digits for every supported radix.
+     */
+    private static final char[] DIGITS = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
+        'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
+        'u', 'v', 'w', 'x', 'y', 'z'
+    };
+
+    private static final char[] UPPER_CASE_DIGITS = {
+        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+        'U', 'V', 'W', 'X', 'Y', 'Z'
+    };
+
+    private IntegralToString() {
+    }
+
+    public static String bytesToHexString(byte[] bytes, boolean upperCase) {
+        char[] digits = upperCase ? UPPER_CASE_DIGITS : DIGITS;
+        char[] buf = new char[bytes.length * 2];
+        int c = 0;
+        for (byte b : bytes) {
+            buf[c++] = digits[(b >> 4) & 0xf];
+            buf[c++] = digits[b & 0xf];
+        }
+        return new String(buf);
+    }
+}
diff --git a/src/main/java/libcore/util/Libcore.java b/src/main/java/libcore/util/Libcore.java
new file mode 100644
index 0000000..740d678
--- /dev/null
+++ b/src/main/java/libcore/util/Libcore.java
@@ -0,0 +1,232 @@
+package libcore.util;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.List;
+import javax.net.ssl.SSLSocket;
+import org.eclipse.jetty.npn.NextProtoNego;
+
+/**
+ * APIs for interacting with Android's core library. This mostly emulates the
+ * Android core library for interoperability with other runtimes.
+ */
+public final class Libcore {
+
+    private Libcore() {
+    }
+
+    private static boolean useAndroidTlsApis;
+    private static Class<?> openSslSocketClass;
+    private static Method setEnabledCompressionMethods;
+    private static Method setUseSessionTickets;
+    private static Method setHostname;
+    private static boolean android23TlsOptionsAvailable;
+    private static Method setNpnProtocols;
+    private static Method getNpnSelectedProtocol;
+    private static boolean android41TlsOptionsAvailable;
+
+    static {
+        try {
+            openSslSocketClass = Class.forName(
+                    "org.apache.harmony.xnet.provider.jsse.OpenSSLSocketImpl");
+            useAndroidTlsApis = true;
+            setEnabledCompressionMethods = openSslSocketClass.getMethod(
+                    "setEnabledCompressionMethods", String[].class);
+            setUseSessionTickets = openSslSocketClass.getMethod(
+                    "setUseSessionTickets", boolean.class);
+            setHostname = openSslSocketClass.getMethod("setHostname", String.class);
+            android23TlsOptionsAvailable = true;
+            setNpnProtocols = openSslSocketClass.getMethod("setNpnProtocols", byte[].class);
+            getNpnSelectedProtocol = openSslSocketClass.getMethod("getNpnSelectedProtocol");
+            android41TlsOptionsAvailable = true;
+        } catch (ClassNotFoundException ignored) {
+            // This isn't an Android runtime.
+        } catch (NoSuchMethodException ignored) {
+            // This Android runtime is missing some optional TLS options.
+        }
+    }
+
+    public static void makeTlsTolerant(SSLSocket socket, String socketHost, boolean tlsTolerant) {
+        if (!tlsTolerant) {
+            socket.setEnabledProtocols(new String[] {"SSLv3"});
+            return;
+        }
+
+        if (android23TlsOptionsAvailable && openSslSocketClass.isInstance(socket)) {
+            // This is Android: use reflection on OpenSslSocketImpl.
+            try {
+                String[] compressionMethods = {"ZLIB"};
+                setEnabledCompressionMethods.invoke(socket,
+                        new Object[] {compressionMethods});
+                setUseSessionTickets.invoke(socket, true);
+                setHostname.invoke(socket, socketHost);
+            } catch (InvocationTargetException e) {
+                throw new RuntimeException(e);
+            } catch (IllegalAccessException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    /**
+     * Returns the negotiated protocol, or null if no protocol was negotiated.
+     */
+    public static byte[] getNpnSelectedProtocol(SSLSocket socket) {
+        if (useAndroidTlsApis) {
+            // This is Android: use reflection on OpenSslSocketImpl.
+            if (android41TlsOptionsAvailable && openSslSocketClass.isInstance(socket)) {
+                try {
+                    return (byte[]) getNpnSelectedProtocol.invoke(socket);
+                } catch (InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                } catch (IllegalAccessException e) {
+                    throw new AssertionError(e);
+                }
+            }
+            return null;
+        } else {
+            // This is OpenJDK: use JettyNpnProvider.
+            JettyNpnProvider provider = (JettyNpnProvider) NextProtoNego.get(socket);
+            if (!provider.unsupported && provider.selected == null) {
+                throw new IllegalStateException(
+                        "No callback received. Is NPN configured properly?");
+            }
+            try {
+                return provider.unsupported
+                        ? null
+                        : provider.selected.getBytes("US-ASCII");
+            } catch (UnsupportedEncodingException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    public static void setNpnProtocols(SSLSocket socket, byte[] npnProtocols) {
+        if (useAndroidTlsApis) {
+            // This is Android: use reflection on OpenSslSocketImpl.
+            if (android41TlsOptionsAvailable && openSslSocketClass.isInstance(socket)) {
+                try {
+                    setNpnProtocols.invoke(socket, new Object[] {npnProtocols});
+                } catch (IllegalAccessException e) {
+                    throw new AssertionError(e);
+                } catch (InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        } else {
+            // This is OpenJDK: use JettyNpnProvider.
+            try {
+                List<String> strings = new ArrayList<String>();
+                for (int i = 0; i < npnProtocols.length;) {
+                    int length = npnProtocols[i++];
+                    strings.add(new String(npnProtocols, i, length, "US-ASCII"));
+                    i += length;
+                }
+                JettyNpnProvider provider = new JettyNpnProvider();
+                provider.protocols = strings;
+                NextProtoNego.put(socket, provider);
+            } catch (UnsupportedEncodingException e) {
+                throw new AssertionError(e);
+            }
+        }
+    }
+
+    private static class JettyNpnProvider
+            implements NextProtoNego.ClientProvider, NextProtoNego.ServerProvider {
+        List<String> protocols;
+        boolean unsupported;
+        String selected;
+
+        @Override public boolean supports() {
+            return true;
+        }
+        @Override public List<String> protocols() {
+            return protocols;
+        }
+        @Override public void unsupported() {
+            this.unsupported = true;
+        }
+        @Override public void protocolSelected(String selected) {
+            this.selected = selected;
+        }
+        @Override public String selectProtocol(List<String> strings) {
+            // TODO: use OpenSSL's algorithm which uses 2 lists
+            System.out.println("CLIENT PROTOCOLS: " + protocols + " SERVER PROTOCOLS: " + strings);
+            String selected = protocols.get(0);
+            protocolSelected(selected);
+            return selected;
+        }
+    }
+
+    public static void deleteIfExists(File file) throws IOException {
+        // okhttp-changed: was Libcore.os.remove() in a try/catch block
+        file.delete();
+    }
+
+    public static void logW(String warning) {
+        // okhttp-changed: was System.logw()
+        System.out.println(warning);
+    }
+
+    public static int getEffectivePort(URI uri) {
+        return getEffectivePort(uri.getScheme(), uri.getPort());
+    }
+
+    public static int getEffectivePort(URL url) {
+        return getEffectivePort(url.getProtocol(), url.getPort());
+    }
+
+    private static int getEffectivePort(String scheme, int specifiedPort) {
+        if (specifiedPort != -1) {
+            return specifiedPort;
+        }
+
+        if ("http".equalsIgnoreCase(scheme)) {
+            return 80;
+        } else if ("https".equalsIgnoreCase(scheme)) {
+            return 443;
+        } else {
+            return -1;
+        }
+    }
+
+    public static void checkOffsetAndCount(int arrayLength, int offset, int count) {
+        if ((offset | count) < 0 || offset > arrayLength || arrayLength - offset < count) {
+            throw new ArrayIndexOutOfBoundsException();
+        }
+    }
+
+    public static void tagSocket(Socket socket) {
+    }
+
+    public static void untagSocket(Socket socket) throws SocketException {
+    }
+
+    public static URI toUriLenient(URL url) throws URISyntaxException {
+        return url.toURI(); // this isn't as good as the built-in toUriLenient
+    }
+
+    public static void pokeInt(byte[] dst, int offset, int value, ByteOrder order) {
+        if (order == ByteOrder.BIG_ENDIAN) {
+            dst[offset++] = (byte) ((value >> 24) & 0xff);
+            dst[offset++] = (byte) ((value >> 16) & 0xff);
+            dst[offset++] = (byte) ((value >>  8) & 0xff);
+            dst[offset  ] = (byte) ((value >>  0) & 0xff);
+        } else {
+            dst[offset++] = (byte) ((value >>  0) & 0xff);
+            dst[offset++] = (byte) ((value >>  8) & 0xff);
+            dst[offset++] = (byte) ((value >> 16) & 0xff);
+            dst[offset  ] = (byte) ((value >> 24) & 0xff);
+        }
+    }
+}
diff --git a/src/main/java/libcore/util/MutableBoolean.java b/src/main/java/libcore/util/MutableBoolean.java
new file mode 100644
index 0000000..359a8f9
--- /dev/null
+++ b/src/main/java/libcore/util/MutableBoolean.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableBoolean {
+    public boolean value;
+
+    public MutableBoolean(boolean value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableByte.java b/src/main/java/libcore/util/MutableByte.java
new file mode 100644
index 0000000..13f780b
--- /dev/null
+++ b/src/main/java/libcore/util/MutableByte.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableByte {
+    public byte value;
+
+    public MutableByte(byte value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableChar.java b/src/main/java/libcore/util/MutableChar.java
new file mode 100644
index 0000000..1cafc3c
--- /dev/null
+++ b/src/main/java/libcore/util/MutableChar.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableChar {
+    public char value;
+
+    public MutableChar(char value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableDouble.java b/src/main/java/libcore/util/MutableDouble.java
new file mode 100644
index 0000000..4473ae6
--- /dev/null
+++ b/src/main/java/libcore/util/MutableDouble.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableDouble {
+    public double value;
+
+    public MutableDouble(double value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableFloat.java b/src/main/java/libcore/util/MutableFloat.java
new file mode 100644
index 0000000..f81fba5
--- /dev/null
+++ b/src/main/java/libcore/util/MutableFloat.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableFloat {
+    public float value;
+
+    public MutableFloat(float value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableInt.java b/src/main/java/libcore/util/MutableInt.java
new file mode 100644
index 0000000..c8feb3a
--- /dev/null
+++ b/src/main/java/libcore/util/MutableInt.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableInt {
+    public int value;
+
+    public MutableInt(int value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableLong.java b/src/main/java/libcore/util/MutableLong.java
new file mode 100644
index 0000000..ad9b78e
--- /dev/null
+++ b/src/main/java/libcore/util/MutableLong.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableLong {
+    public long value;
+
+    public MutableLong(long value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/MutableShort.java b/src/main/java/libcore/util/MutableShort.java
new file mode 100644
index 0000000..78b4c33
--- /dev/null
+++ b/src/main/java/libcore/util/MutableShort.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class MutableShort {
+    public short value;
+
+    public MutableShort(short value) {
+        this.value = value;
+    }
+}
diff --git a/src/main/java/libcore/util/Objects.java b/src/main/java/libcore/util/Objects.java
new file mode 100644
index 0000000..050888d
--- /dev/null
+++ b/src/main/java/libcore/util/Objects.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+public final class Objects {
+    private Objects() {
+    }
+
+    /**
+     * Returns true if two possibly-null objects are equal.
+     */
+    public static boolean equal(Object a, Object b) {
+        return a == b || (a != null && a.equals(b));
+    }
+
+    public static int hashCode(Object o) {
+        return (o == null) ? 0 : o.hashCode();
+    }
+}
diff --git a/src/main/java/libcore/util/ResponseSource.java b/src/main/java/libcore/util/ResponseSource.java
new file mode 100644
index 0000000..8e7bfae
--- /dev/null
+++ b/src/main/java/libcore/util/ResponseSource.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Where the HTTP client should look for a response.
+ *
+ * @hide
+ */
+public enum ResponseSource {
+
+    /**
+     * Return the response from the cache immediately.
+     */
+    CACHE,
+
+    /**
+     * Make a conditional request to the host, returning the cache response if
+     * the cache is valid and the network response otherwise.
+     */
+    CONDITIONAL_CACHE,
+
+    /**
+     * Return the response from the network.
+     */
+    NETWORK;
+
+    public boolean requiresConnection() {
+        return this == CONDITIONAL_CACHE || this == NETWORK;
+    }
+}
diff --git a/src/main/java/libcore/util/SneakyThrow.java b/src/main/java/libcore/util/SneakyThrow.java
new file mode 100644
index 0000000..f5c077c
--- /dev/null
+++ b/src/main/java/libcore/util/SneakyThrow.java
@@ -0,0 +1,71 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+package libcore.util;
+
+/**
+ * Exploits a weakness in the runtime to throw an arbitrary throwable without
+ * the traditional declaration. <strong>This is a dangerous API that should be
+ * used with great caution.</strong> Typically this is useful when rethrowing
+ * throwables that are of a known range of types.
+ *
+ * <p>The following code must enumerate several types to rethrow:
+ * <pre>
+ * public void close() throws IOException {
+ *     Throwable thrown = null;
+ *     ...
+ *
+ *     if (thrown != null) {
+ *         if (thrown instanceof IOException) {
+ *             throw (IOException) thrown;
+ *         } else if (thrown instanceof RuntimeException) {
+ *             throw (RuntimeException) thrown;
+ *         } else if (thrown instanceof Error) {
+ *             throw (Error) thrown;
+ *         } else {
+ *             throw new AssertionError();
+ *         }
+ *     }
+ * }</pre>
+ * With SneakyThrow, rethrowing is easier:
+ * <pre>
+ * public void close() throws IOException {
+ *     Throwable thrown = null;
+ *     ...
+ *
+ *     if (thrown != null) {
+ *         SneakyThrow.sneakyThrow(thrown);
+ *     }
+ * }</pre>
+ */
+public final class SneakyThrow {
+    private SneakyThrow() {
+    }
+
+    public static void sneakyThrow(Throwable t) {
+        SneakyThrow.<Error>sneakyThrow2(t);
+    }
+
+    /**
+     * Exploits unsafety to throw an exception that the compiler wouldn't permit
+     * but that the runtime doesn't check. See Java Puzzlers #43.
+     */
+    @SuppressWarnings("unchecked")
+    private static <T extends Throwable> void sneakyThrow2(Throwable t) throws T {
+        throw (T) t;
+    }
+}
diff --git a/src/test/java/libcore/net/http/ExternalSpdyExample.java b/src/test/java/libcore/net/http/ExternalSpdyExample.java
new file mode 100644
index 0000000..dc8aa1e
--- /dev/null
+++ b/src/test/java/libcore/net/http/ExternalSpdyExample.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import com.squareup.okhttp.OkHttpConnection;
+import com.squareup.okhttp.OkHttpsConnection;
+import java.io.BufferedReader;
+import java.io.InputStreamReader;
+import java.net.URL;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+public final class ExternalSpdyExample {
+    public static void main(String[] args) throws Exception {
+        URL url = new URL("https://www.google.ca/");
+        OkHttpsConnection connection = (OkHttpsConnection) OkHttpConnection.open(url);
+
+        connection.setHostnameVerifier(new HostnameVerifier() {
+            @Override public boolean verify(String s, SSLSession sslSession) {
+                System.out.println("VERIFYING " + s);
+                return true;
+            }
+        });
+
+        int responseCode = connection.getResponseCode();
+        System.out.println(responseCode);
+
+        BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
+        String line;
+        while ((line = reader.readLine()) != null) {
+            System.out.println(line);
+        }
+    }
+}
diff --git a/src/test/java/libcore/net/http/NewURLConnectionTest.java b/src/test/java/libcore/net/http/NewURLConnectionTest.java
new file mode 100644
index 0000000..8c6121e
--- /dev/null
+++ b/src/test/java/libcore/net/http/NewURLConnectionTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import junit.framework.TestCase;
+
+public final class NewURLConnectionTest extends TestCase {
+
+    public void testUrlConnection() {
+    }
+
+    // TODO: write a test that shows pooled connections detect HTTP/1.0 (vs. HTTP/1.1)
+
+    // TODO: write a test that shows POST bodies are retained on AUTH problems (or prove it unnecessary)
+
+    // TODO: cookies + trailers. Do cookie headers get processed too many times?
+
+    // TODO: crash on header names or values containing the '\0' character
+
+    // TODO: crash on empty names and empty values
+
+    // TODO: deflate compression
+
+    // TODO: read the outgoing status line and incoming status line?
+
+}
diff --git a/src/test/java/libcore/net/http/URLConnectionTest.java b/src/test/java/libcore/net/http/URLConnectionTest.java
new file mode 100644
index 0000000..6df8f53
--- /dev/null
+++ b/src/test/java/libcore/net/http/URLConnectionTest.java
@@ -0,0 +1,2081 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.http;
+
+import com.google.mockwebserver.MockResponse;
+import com.google.mockwebserver.MockWebServer;
+import com.google.mockwebserver.RecordedRequest;
+import com.google.mockwebserver.SocketPolicy;
+import com.squareup.okhttp.OkHttpConnection;
+import com.squareup.okhttp.OkHttpsConnection;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Authenticator;
+import java.net.CacheRequest;
+import java.net.CacheResponse;
+import java.net.ConnectException;
+import java.net.HttpRetryException;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.PasswordAuthentication;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.ResponseCache;
+import java.net.SocketTimeoutException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.UnknownHostException;
+import java.security.GeneralSecurityException;
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.X509TrustManager;
+import junit.framework.TestCase;
+import libcore.net.ssl.SslContextBuilder;
+
+import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_END;
+import static com.google.mockwebserver.SocketPolicy.DISCONNECT_AT_START;
+import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_INPUT_AT_END;
+import static com.google.mockwebserver.SocketPolicy.SHUTDOWN_OUTPUT_AT_END;
+
+/**
+ * Android's URLConnectionTest.
+ */
+public final class URLConnectionTest extends TestCase {
+
+    private static final Authenticator SIMPLE_AUTHENTICATOR = new Authenticator() {
+        protected PasswordAuthentication getPasswordAuthentication() {
+            return new PasswordAuthentication("username", "password".toCharArray());
+        }
+    };
+
+    /** base64("username:password") */
+    private static final String BASE_64_CREDENTIALS = "dXNlcm5hbWU6cGFzc3dvcmQ=";
+
+    private MockWebServer server = new MockWebServer();
+    private String hostName;
+
+    private static final SSLContext sslContext;
+
+    static {
+        try {
+            sslContext = new SslContextBuilder(InetAddress.getLocalHost().getHostName())
+                    .build();
+        } catch (GeneralSecurityException e) {
+            throw new RuntimeException(e);
+        } catch (UnknownHostException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override protected void setUp() throws Exception {
+        super.setUp();
+        hostName = server.getHostName();
+    }
+
+    @Override protected void tearDown() throws Exception {
+        ResponseCache.setDefault(null);
+        Authenticator.setDefault(null);
+        System.clearProperty("proxyHost");
+        System.clearProperty("proxyPort");
+        System.clearProperty("http.proxyHost");
+        System.clearProperty("http.proxyPort");
+        System.clearProperty("https.proxyHost");
+        System.clearProperty("https.proxyPort");
+        server.shutdown();
+        super.tearDown();
+    }
+    
+    private static OkHttpConnection openConnection(URL url) {
+        return OkHttpConnection.open(url);
+    }
+
+    private static OkHttpConnection openConnection(URL url, Proxy proxy) {
+        return OkHttpConnection.open(url, proxy);
+    }
+
+    public void testRequestHeaders() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection urlConnection = openConnection(server.getUrl("/"));
+        urlConnection.addRequestProperty("D", "e");
+        urlConnection.addRequestProperty("D", "f");
+        assertEquals("f", urlConnection.getRequestProperty("D"));
+        assertEquals("f", urlConnection.getRequestProperty("d"));
+        Map<String, List<String>> requestHeaders = urlConnection.getRequestProperties();
+        assertEquals(newSet("e", "f"), new HashSet<String>(requestHeaders.get("D")));
+        assertEquals(newSet("e", "f"), new HashSet<String>(requestHeaders.get("d")));
+        try {
+            requestHeaders.put("G", Arrays.asList("h"));
+            fail("Modified an unmodifiable view.");
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            requestHeaders.get("D").add("i");
+            fail("Modified an unmodifiable view.");
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            urlConnection.setRequestProperty(null, "j");
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            urlConnection.addRequestProperty(null, "k");
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        urlConnection.setRequestProperty("NullValue", null); // should fail silently!
+        assertNull(urlConnection.getRequestProperty("NullValue"));
+        urlConnection.addRequestProperty("AnotherNullValue", null);  // should fail silently!
+        assertNull(urlConnection.getRequestProperty("AnotherNullValue"));
+
+        urlConnection.getResponseCode();
+        RecordedRequest request = server.takeRequest();
+        assertContains(request.getHeaders(), "D: e");
+        assertContains(request.getHeaders(), "D: f");
+        assertContainsNoneMatching(request.getHeaders(), "NullValue.*");
+        assertContainsNoneMatching(request.getHeaders(), "AnotherNullValue.*");
+        assertContainsNoneMatching(request.getHeaders(), "G:.*");
+        assertContainsNoneMatching(request.getHeaders(), "null:.*");
+
+        try {
+            urlConnection.addRequestProperty("N", "o");
+            fail("Set header after connect");
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            urlConnection.setRequestProperty("P", "q");
+            fail("Set header after connect");
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            urlConnection.getRequestProperties();
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testGetRequestPropertyReturnsLastValue() throws Exception {
+        server.play();
+        OkHttpConnection urlConnection = openConnection(server.getUrl("/"));
+        urlConnection.addRequestProperty("A", "value1");
+        urlConnection.addRequestProperty("A", "value2");
+        assertEquals("value2", urlConnection.getRequestProperty("A"));
+    }
+
+    public void testResponseHeaders() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse()
+                .setStatus("HTTP/1.0 200 Fantastic")
+                .addHeader("A: c")
+                .addHeader("B: d")
+                .addHeader("A: e")
+                .setChunkedBody("ABCDE\nFGHIJ\nKLMNO\nPQR", 8));
+        server.play();
+
+        OkHttpConnection urlConnection = openConnection(server.getUrl("/"));
+        assertEquals(200, urlConnection.getResponseCode());
+        assertEquals("Fantastic", urlConnection.getResponseMessage());
+        assertEquals("HTTP/1.0 200 Fantastic", urlConnection.getHeaderField(null));
+        Map<String, List<String>> responseHeaders = urlConnection.getHeaderFields();
+        assertEquals(Arrays.asList("HTTP/1.0 200 Fantastic"), responseHeaders.get(null));
+        assertEquals(newSet("c", "e"), new HashSet<String>(responseHeaders.get("A")));
+        assertEquals(newSet("c", "e"), new HashSet<String>(responseHeaders.get("a")));
+        try {
+            responseHeaders.put("N", Arrays.asList("o"));
+            fail("Modified an unmodifiable view.");
+        } catch (UnsupportedOperationException expected) {
+        }
+        try {
+            responseHeaders.get("A").add("f");
+            fail("Modified an unmodifiable view.");
+        } catch (UnsupportedOperationException expected) {
+        }
+        assertEquals("A", urlConnection.getHeaderFieldKey(0));
+        assertEquals("c", urlConnection.getHeaderField(0));
+        assertEquals("B", urlConnection.getHeaderFieldKey(1));
+        assertEquals("d", urlConnection.getHeaderField(1));
+        assertEquals("A", urlConnection.getHeaderFieldKey(2));
+        assertEquals("e", urlConnection.getHeaderField(2));
+    }
+
+    public void testGetErrorStreamOnSuccessfulRequest() throws Exception {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertNull(connection.getErrorStream());
+    }
+
+    public void testGetErrorStreamOnUnsuccessfulRequest() throws Exception {
+        server.enqueue(new MockResponse().setResponseCode(404).setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("A", readAscii(connection.getErrorStream(), Integer.MAX_VALUE));
+    }
+
+    // Check that if we don't read to the end of a response, the next request on the
+    // recycled connection doesn't get the unread tail of the first request's response.
+    // http://code.google.com/p/android/issues/detail?id=2939
+    public void test_2939() throws Exception {
+        MockResponse response = new MockResponse().setChunkedBody("ABCDE\nFGHIJ\nKLMNO\nPQR", 8);
+
+        server.enqueue(response);
+        server.enqueue(response);
+        server.play();
+
+        assertContent("ABCDE", openConnection(server.getUrl("/")), 5);
+        assertContent("ABCDE", openConnection(server.getUrl("/")), 5);
+    }
+
+    // Check that we recognize a few basic mime types by extension.
+    // http://code.google.com/p/android/issues/detail?id=10100
+    public void test_10100() throws Exception {
+        assertEquals("image/jpeg", URLConnection.guessContentTypeFromName("someFile.jpg"));
+        assertEquals("application/pdf", URLConnection.guessContentTypeFromName("stuff.pdf"));
+    }
+
+    public void testConnectionsArePooled() throws Exception {
+        MockResponse response = new MockResponse().setBody("ABCDEFGHIJKLMNOPQR");
+
+        server.enqueue(response);
+        server.enqueue(response);
+        server.enqueue(response);
+        server.play();
+
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/foo")));
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/bar?baz=quux")));
+        assertEquals(1, server.takeRequest().getSequenceNumber());
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/z")));
+        assertEquals(2, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testChunkedConnectionsArePooled() throws Exception {
+        MockResponse response = new MockResponse().setChunkedBody("ABCDEFGHIJKLMNOPQR", 5);
+
+        server.enqueue(response);
+        server.enqueue(response);
+        server.enqueue(response);
+        server.play();
+
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/foo")));
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/bar?baz=quux")));
+        assertEquals(1, server.takeRequest().getSequenceNumber());
+        assertContent("ABCDEFGHIJKLMNOPQR", openConnection(server.getUrl("/z")));
+        assertEquals(2, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testServerClosesSocket() throws Exception {
+        testServerClosesOutput(DISCONNECT_AT_END);
+    }
+
+    public void testServerShutdownInput() throws Exception {
+        testServerClosesOutput(SHUTDOWN_INPUT_AT_END);
+    }
+
+    public void SUPPRESSED_testServerShutdownOutput() throws Exception {
+        testServerClosesOutput(SHUTDOWN_OUTPUT_AT_END);
+    }
+
+    private void testServerClosesOutput(SocketPolicy socketPolicy) throws Exception {
+        server.enqueue(new MockResponse()
+                .setBody("This connection won't pool properly")
+                .setSocketPolicy(socketPolicy));
+        server.enqueue(new MockResponse()
+                .setBody("This comes after a busted connection"));
+        server.play();
+
+        assertContent("This connection won't pool properly", openConnection(server.getUrl("/a")));
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertContent("This comes after a busted connection", openConnection(server.getUrl("/b")));
+        // sequence number 0 means the HTTP socket connection was not reused
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+    }
+
+    enum WriteKind { BYTE_BY_BYTE, SMALL_BUFFERS, LARGE_BUFFERS }
+
+    public void test_chunkedUpload_byteByByte() throws Exception {
+        doUpload(TransferKind.CHUNKED, WriteKind.BYTE_BY_BYTE);
+    }
+
+    public void test_chunkedUpload_smallBuffers() throws Exception {
+        doUpload(TransferKind.CHUNKED, WriteKind.SMALL_BUFFERS);
+    }
+
+    public void test_chunkedUpload_largeBuffers() throws Exception {
+        doUpload(TransferKind.CHUNKED, WriteKind.LARGE_BUFFERS);
+    }
+
+    public void SUPPRESSED_test_fixedLengthUpload_byteByByte() throws Exception {
+        doUpload(TransferKind.FIXED_LENGTH, WriteKind.BYTE_BY_BYTE);
+    }
+
+    public void test_fixedLengthUpload_smallBuffers() throws Exception {
+        doUpload(TransferKind.FIXED_LENGTH, WriteKind.SMALL_BUFFERS);
+    }
+
+    public void test_fixedLengthUpload_largeBuffers() throws Exception {
+        doUpload(TransferKind.FIXED_LENGTH, WriteKind.LARGE_BUFFERS);
+    }
+
+    private void doUpload(TransferKind uploadKind, WriteKind writeKind) throws Exception {
+        int n = 512*1024;
+        server.setBodyLimit(0);
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection conn = openConnection(server.getUrl("/"));
+        conn.setDoOutput(true);
+        conn.setRequestMethod("POST");
+        if (uploadKind == TransferKind.CHUNKED) {
+            conn.setChunkedStreamingMode(-1);
+        } else {
+            conn.setFixedLengthStreamingMode(n);
+        }
+        OutputStream out = conn.getOutputStream();
+        if (writeKind == WriteKind.BYTE_BY_BYTE) {
+            for (int i = 0; i < n; ++i) {
+                out.write('x');
+            }
+        } else {
+            byte[] buf = new byte[writeKind == WriteKind.SMALL_BUFFERS ? 256 : 64*1024];
+            Arrays.fill(buf, (byte) 'x');
+            for (int i = 0; i < n; i += buf.length) {
+                out.write(buf, 0, Math.min(buf.length, n - i));
+            }
+        }
+        out.close();
+        assertEquals(200, conn.getResponseCode());
+        RecordedRequest request = server.takeRequest();
+        assertEquals(n, request.getBodySize());
+        if (uploadKind == TransferKind.CHUNKED) {
+            assertTrue(request.getChunkSizes().size() > 0);
+        } else {
+            assertTrue(request.getChunkSizes().isEmpty());
+        }
+    }
+
+    public void testGetResponseCodeNoResponseBody() throws Exception {
+        server.enqueue(new MockResponse()
+                .addHeader("abc: def"));
+        server.play();
+
+        URL url = server.getUrl("/");
+        OkHttpConnection conn = openConnection(url);
+        conn.setDoInput(false);
+        assertEquals("def", conn.getHeaderField("abc"));
+        assertEquals(200, conn.getResponseCode());
+        try {
+            conn.getInputStream();
+            fail();
+        } catch (ProtocolException expected) {
+        }
+    }
+
+    public void testConnectViaHttps() throws Exception {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
+        server.play();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/foo"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+
+        assertContent("this response comes via HTTPS", connection);
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
+    }
+
+    public void testConnectViaHttpsReusingConnections() throws IOException, InterruptedException {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
+        server.enqueue(new MockResponse().setBody("another response via HTTPS"));
+        server.play();
+
+        // The pool will only reuse sockets if the SSL socket factories are the same.
+        SSLSocketFactory clientSocketFactory = sslContext.getSocketFactory();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(clientSocketFactory);
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertContent("this response comes via HTTPS", connection);
+
+        connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(clientSocketFactory);
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertContent("another response via HTTPS", connection);
+
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertEquals(1, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testConnectViaHttpsReusingConnectionsDifferentFactories()
+            throws IOException, InterruptedException {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
+        server.enqueue(new MockResponse().setBody("another response via HTTPS"));
+        server.play();
+
+        // install a custom SSL socket factory so the server can be authorized
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertContent("this response comes via HTTPS", connection);
+
+        connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        try {
+            readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+            fail("without an SSL socket factory, the connection should fail");
+        } catch (SSLException expected) {
+        }
+    }
+
+    public void testConnectViaHttpsWithSSLFallback() throws IOException, InterruptedException {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AT_START));
+        server.enqueue(new MockResponse().setBody("this response comes via SSL"));
+        server.play();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/foo"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+
+        assertContent("this response comes via SSL", connection);
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
+    }
+
+    /**
+     * Verify that we don't retry connections on certificate verification errors.
+     *
+     * http://code.google.com/p/android/issues/detail?id=13178
+     */
+//    public void testConnectViaHttpsToUntrustedServer() throws IOException, InterruptedException {
+//        TestSSLContext testSSLContext = TestSSLContext.create(TestKeyStore.getClientCA2(),
+//                                                              TestKeyStore.getServer());
+//
+//        server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
+//        server.enqueue(new MockResponse()); // unused
+//        server.play();
+//
+//        HttpsURLConnection connection = (HttpsURLConnection) server.getUrl("/foo").openConnection();
+//        connection.setSSLSocketFactory(testSSLContext.clientContext.getSocketFactory());
+//        try {
+//            connection.getInputStream();
+//            fail();
+//        } catch (SSLHandshakeException expected) {
+//            assertTrue(expected.getCause() instanceof CertificateException);
+//        }
+//        assertEquals(0, server.getRequestCount());
+//    }
+
+    public void testConnectViaProxyUsingProxyArg() throws Exception {
+        testConnectViaProxy(ProxyConfig.CREATE_ARG);
+    }
+
+    public void testConnectViaProxyUsingProxySystemProperty() throws Exception {
+        testConnectViaProxy(ProxyConfig.PROXY_SYSTEM_PROPERTY);
+    }
+
+    public void testConnectViaProxyUsingHttpProxySystemProperty() throws Exception {
+        testConnectViaProxy(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY);
+    }
+
+    private void testConnectViaProxy(ProxyConfig proxyConfig) throws Exception {
+        MockResponse mockResponse = new MockResponse().setBody("this response comes via a proxy");
+        server.enqueue(mockResponse);
+        server.play();
+
+        URL url = new URL("http://android.com/foo");
+        OkHttpConnection connection = proxyConfig.connect(server, url);
+        assertContent("this response comes via a proxy", connection);
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("GET http://android.com/foo HTTP/1.1", request.getRequestLine());
+        assertContains(request.getHeaders(), "Host: android.com");
+    }
+
+    public void testContentDisagreesWithContentLengthHeader() throws IOException {
+        server.enqueue(new MockResponse()
+                .setBody("abc\r\nYOU SHOULD NOT SEE THIS")
+                .clearHeaders()
+                .addHeader("Content-Length: 3"));
+        server.play();
+
+        assertContent("abc", openConnection(server.getUrl("/")));
+    }
+
+    public void testContentDisagreesWithChunkedHeader() throws IOException {
+        MockResponse mockResponse = new MockResponse();
+        mockResponse.setChunkedBody("abc", 3);
+        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+        bytesOut.write(mockResponse.getBody());
+        bytesOut.write("\r\nYOU SHOULD NOT SEE THIS".getBytes("UTF-8"));
+        mockResponse.setBody(bytesOut.toByteArray());
+        mockResponse.clearHeaders();
+        mockResponse.addHeader("Transfer-encoding: chunked");
+
+        server.enqueue(mockResponse);
+        server.play();
+
+        assertContent("abc", openConnection(server.getUrl("/")));
+    }
+
+    public void testConnectViaHttpProxyToHttpsUsingProxyArgWithNoProxy() throws Exception {
+        testConnectViaDirectProxyToHttps(ProxyConfig.NO_PROXY);
+    }
+
+    public void testConnectViaHttpProxyToHttpsUsingHttpProxySystemProperty() throws Exception {
+        // https should not use http proxy
+        testConnectViaDirectProxyToHttps(ProxyConfig.HTTP_PROXY_SYSTEM_PROPERTY);
+    }
+
+    private void testConnectViaDirectProxyToHttps(ProxyConfig proxyConfig) throws Exception {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setBody("this response comes via HTTPS"));
+        server.play();
+
+        URL url = server.getUrl("/foo");
+        OkHttpsConnection connection = (OkHttpsConnection) proxyConfig.connect(server, url);
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+
+        assertContent("this response comes via HTTPS", connection);
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", request.getRequestLine());
+    }
+
+    public void testConnectViaHttpProxyToHttpsUsingProxyArg() throws Exception {
+        testConnectViaHttpProxyToHttps(ProxyConfig.CREATE_ARG);
+    }
+
+    /**
+     * We weren't honoring all of the appropriate proxy system properties when
+     * connecting via HTTPS. http://b/3097518
+     */
+    public void testConnectViaHttpProxyToHttpsUsingProxySystemProperty() throws Exception {
+        testConnectViaHttpProxyToHttps(ProxyConfig.PROXY_SYSTEM_PROPERTY);
+    }
+
+    public void testConnectViaHttpProxyToHttpsUsingHttpsProxySystemProperty() throws Exception {
+        testConnectViaHttpProxyToHttps(ProxyConfig.HTTPS_PROXY_SYSTEM_PROPERTY);
+    }
+
+    /**
+     * We were verifying the wrong hostname when connecting to an HTTPS site
+     * through a proxy. http://b/3097277
+     */
+    private void testConnectViaHttpProxyToHttps(ProxyConfig proxyConfig) throws Exception {
+        RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
+
+        server.useHttps(sslContext.getSocketFactory(), true);
+        server.enqueue(new MockResponse()
+                .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
+                .clearHeaders());
+        server.enqueue(new MockResponse().setBody("this response comes via a secure proxy"));
+        server.play();
+
+        URL url = new URL("https://android.com/foo");
+        OkHttpsConnection connection = (OkHttpsConnection) proxyConfig.connect(server, url);
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(hostnameVerifier);
+
+        assertContent("this response comes via a secure proxy", connection);
+
+        RecordedRequest connect = server.takeRequest();
+        assertEquals("Connect line failure on proxy",
+                "CONNECT android.com:443 HTTP/1.1", connect.getRequestLine());
+        assertContains(connect.getHeaders(), "Host: android.com");
+
+        RecordedRequest get = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
+        assertContains(get.getHeaders(), "Host: android.com");
+        assertEquals(Arrays.asList("verify android.com"), hostnameVerifier.calls);
+    }
+
+    /**
+     * Test which headers are sent unencrypted to the HTTP proxy.
+     */
+    public void testProxyConnectIncludesProxyHeadersOnly()
+            throws IOException, InterruptedException {
+        RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
+
+        server.useHttps(sslContext.getSocketFactory(), true);
+        server.enqueue(new MockResponse()
+                .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
+                .clearHeaders());
+        server.enqueue(new MockResponse().setBody("encrypted response from the origin server"));
+        server.play();
+
+        URL url = new URL("https://android.com/foo");
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(
+                url, server.toProxyAddress());
+        connection.addRequestProperty("Private", "Secret");
+        connection.addRequestProperty("Proxy-Authorization", "bar");
+        connection.addRequestProperty("User-Agent", "baz");
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(hostnameVerifier);
+        assertContent("encrypted response from the origin server", connection);
+
+        RecordedRequest connect = server.takeRequest();
+        assertContainsNoneMatching(connect.getHeaders(), "Private.*");
+        assertContains(connect.getHeaders(), "Proxy-Authorization: bar");
+        assertContains(connect.getHeaders(), "User-Agent: baz");
+        assertContains(connect.getHeaders(), "Host: android.com");
+        assertContains(connect.getHeaders(), "Proxy-Connection: Keep-Alive");
+
+        RecordedRequest get = server.takeRequest();
+        assertContains(get.getHeaders(), "Private: Secret");
+        assertEquals(Arrays.asList("verify android.com"), hostnameVerifier.calls);
+    }
+
+    public void testProxyAuthenticateOnConnect() throws Exception {
+        Authenticator.setDefault(SIMPLE_AUTHENTICATOR);
+        server.useHttps(sslContext.getSocketFactory(), true);
+        server.enqueue(new MockResponse()
+                .setResponseCode(407)
+                .addHeader("Proxy-Authenticate: Basic realm=\"localhost\""));
+        server.enqueue(new MockResponse()
+                .setSocketPolicy(SocketPolicy.UPGRADE_TO_SSL_AT_END)
+                .clearHeaders());
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+
+        URL url = new URL("https://android.com/foo");
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(
+                url, server.toProxyAddress());
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertContent("A", connection);
+
+        RecordedRequest connect1 = server.takeRequest();
+        assertEquals("CONNECT android.com:443 HTTP/1.1", connect1.getRequestLine());
+        assertContainsNoneMatching(connect1.getHeaders(), "Proxy\\-Authorization.*");
+
+        RecordedRequest connect2 = server.takeRequest();
+        assertEquals("CONNECT android.com:443 HTTP/1.1", connect2.getRequestLine());
+        assertContains(connect2.getHeaders(), "Proxy-Authorization: Basic " + BASE_64_CREDENTIALS);
+
+        RecordedRequest get = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", get.getRequestLine());
+        assertContainsNoneMatching(get.getHeaders(), "Proxy\\-Authorization.*");
+    }
+
+    public void testDisconnectedConnection() throws IOException {
+        server.enqueue(new MockResponse().setBody("ABCDEFGHIJKLMNOPQR"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = connection.getInputStream();
+        assertEquals('A', (char) in.read());
+        connection.disconnect();
+        try {
+            in.read();
+            fail("Expected a connection closed exception");
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testDisconnectBeforeConnect() throws IOException {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.disconnect();
+
+        assertContent("A", connection);
+        assertEquals(200, connection.getResponseCode());
+    }
+
+    public void testDefaultRequestProperty() throws Exception {
+        URLConnection.setDefaultRequestProperty("X-testSetDefaultRequestProperty", "A");
+        assertNull(URLConnection.getDefaultRequestProperty("X-setDefaultRequestProperty"));
+    }
+
+    /**
+     * Reads {@code count} characters from the stream. If the stream is
+     * exhausted before {@code count} characters can be read, the remaining
+     * characters are returned and the stream is closed.
+     */
+    private String readAscii(InputStream in, int count) throws IOException {
+        StringBuilder result = new StringBuilder();
+        for (int i = 0; i < count; i++) {
+            int value = in.read();
+            if (value == -1) {
+                in.close();
+                break;
+            }
+            result.append((char) value);
+        }
+        return result.toString();
+    }
+
+    public void testMarkAndResetWithContentLengthHeader() throws IOException {
+        testMarkAndReset(TransferKind.FIXED_LENGTH);
+    }
+
+    public void testMarkAndResetWithChunkedEncoding() throws IOException {
+        testMarkAndReset(TransferKind.CHUNKED);
+    }
+
+    public void testMarkAndResetWithNoLengthHeaders() throws IOException {
+        testMarkAndReset(TransferKind.END_OF_STREAM);
+    }
+
+    private void testMarkAndReset(TransferKind transferKind) throws IOException {
+        MockResponse response = new MockResponse();
+        transferKind.setBody(response, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1024);
+        server.enqueue(response);
+        server.enqueue(response);
+        server.play();
+
+        InputStream in = openConnection(server.getUrl("/")).getInputStream();
+        assertFalse("This implementation claims to support mark().", in.markSupported());
+        in.mark(5);
+        assertEquals("ABCDE", readAscii(in, 5));
+        try {
+            in.reset();
+            fail();
+        } catch (IOException expected) {
+        }
+        assertEquals("FGHIJKLMNOPQRSTUVWXYZ", readAscii(in, Integer.MAX_VALUE));
+        assertContent("ABCDEFGHIJKLMNOPQRSTUVWXYZ", openConnection(server.getUrl("/")));
+    }
+
+    /**
+     * We've had a bug where we forget the HTTP response when we see response
+     * code 401. This causes a new HTTP request to be issued for every call into
+     * the URLConnection.
+     */
+    public void SUPPRESSED_testUnauthorizedResponseHandling() throws IOException {
+        MockResponse response = new MockResponse()
+                .addHeader("WWW-Authenticate: challenge")
+                .setResponseCode(401) // UNAUTHORIZED
+                .setBody("Unauthorized");
+        server.enqueue(response);
+        server.enqueue(response);
+        server.enqueue(response);
+        server.play();
+
+        URL url = server.getUrl("/");
+        OkHttpConnection conn = openConnection(url);
+
+        assertEquals(401, conn.getResponseCode());
+        assertEquals(401, conn.getResponseCode());
+        assertEquals(401, conn.getResponseCode());
+        assertEquals(1, server.getRequestCount());
+    }
+
+    public void testNonHexChunkSize() throws IOException {
+        server.enqueue(new MockResponse()
+                .setBody("5\r\nABCDE\r\nG\r\nFGHIJKLMNOPQRSTU\r\n0\r\n\r\n")
+                .clearHeaders()
+                .addHeader("Transfer-encoding: chunked"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        try {
+            readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+            fail();
+        } catch (IOException e) {
+        }
+    }
+
+    public void testMissingChunkBody() throws IOException {
+        server.enqueue(new MockResponse()
+                .setBody("5")
+                .clearHeaders()
+                .addHeader("Transfer-encoding: chunked")
+                .setSocketPolicy(DISCONNECT_AT_END));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        try {
+            readAscii(connection.getInputStream(), Integer.MAX_VALUE);
+            fail();
+        } catch (IOException e) {
+        }
+    }
+
+    /**
+     * This test checks whether connections are gzipped by default. This
+     * behavior in not required by the API, so a failure of this test does not
+     * imply a bug in the implementation.
+     */
+    public void testGzipEncodingEnabledByDefault() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse()
+                .setBody(gzip("ABCABCABC".getBytes("UTF-8")))
+                .addHeader("Content-Encoding: gzip"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("ABCABCABC", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        assertNull(connection.getContentEncoding());
+
+        RecordedRequest request = server.takeRequest();
+        assertContains(request.getHeaders(), "Accept-Encoding: gzip");
+    }
+
+    public void testClientConfiguredGzipContentEncoding() throws Exception {
+        server.enqueue(new MockResponse()
+                .setBody(gzip("ABCDEFGHIJKLMNOPQRSTUVWXYZ".getBytes("UTF-8")))
+                .addHeader("Content-Encoding: gzip"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        connection.addRequestProperty("Accept-Encoding", "gzip");
+        InputStream gunzippedIn = new GZIPInputStream(connection.getInputStream());
+        assertEquals("ABCDEFGHIJKLMNOPQRSTUVWXYZ", readAscii(gunzippedIn, Integer.MAX_VALUE));
+
+        RecordedRequest request = server.takeRequest();
+        assertContains(request.getHeaders(), "Accept-Encoding: gzip");
+    }
+
+    public void testGzipAndConnectionReuseWithFixedLength() throws Exception {
+        testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.FIXED_LENGTH);
+    }
+
+    public void testGzipAndConnectionReuseWithChunkedEncoding() throws Exception {
+        testClientConfiguredGzipContentEncodingAndConnectionReuse(TransferKind.CHUNKED);
+    }
+
+    public void testClientConfiguredCustomContentEncoding() throws Exception {
+        server.enqueue(new MockResponse()
+                .setBody("ABCDE")
+                .addHeader("Content-Encoding: custom"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        connection.addRequestProperty("Accept-Encoding", "custom");
+        assertEquals("ABCDE", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        RecordedRequest request = server.takeRequest();
+        assertContains(request.getHeaders(), "Accept-Encoding: custom");
+    }
+
+    /**
+     * Test a bug where gzip input streams weren't exhausting the input stream,
+     * which corrupted the request that followed.
+     * http://code.google.com/p/android/issues/detail?id=7059
+     */
+    private void testClientConfiguredGzipContentEncodingAndConnectionReuse(
+            TransferKind transferKind) throws Exception {
+        MockResponse responseOne = new MockResponse();
+        responseOne.addHeader("Content-Encoding: gzip");
+        transferKind.setBody(responseOne, gzip("one (gzipped)".getBytes("UTF-8")), 5);
+        server.enqueue(responseOne);
+        MockResponse responseTwo = new MockResponse();
+        transferKind.setBody(responseTwo, "two (identity)", 5);
+        server.enqueue(responseTwo);
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        connection.addRequestProperty("Accept-Encoding", "gzip");
+        InputStream gunzippedIn = new GZIPInputStream(connection.getInputStream());
+        assertEquals("one (gzipped)", readAscii(gunzippedIn, Integer.MAX_VALUE));
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+
+        connection = openConnection(server.getUrl("/"));
+        assertEquals("two (identity)", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        assertEquals(1, server.takeRequest().getSequenceNumber());
+    }
+
+    /**
+     * Obnoxiously test that the chunk sizes transmitted exactly equal the
+     * requested data+chunk header size. Although setChunkedStreamingMode()
+     * isn't specific about whether the size applies to the data or the
+     * complete chunk, the RI interprets it as a complete chunk.
+     */
+    public void testSetChunkedStreamingMode() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection urlConnection = openConnection(server.getUrl("/"));
+        urlConnection.setChunkedStreamingMode(8);
+        urlConnection.setDoOutput(true);
+        OutputStream outputStream = urlConnection.getOutputStream();
+        outputStream.write("ABCDEFGHIJKLMNOPQ".getBytes("US-ASCII"));
+        assertEquals(200, urlConnection.getResponseCode());
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("ABCDEFGHIJKLMNOPQ", new String(request.getBody(), "US-ASCII"));
+        assertEquals(Arrays.asList(3, 3, 3, 3, 3, 2), request.getChunkSizes());
+    }
+
+    public void testAuthenticateWithFixedLengthStreaming() throws Exception {
+        testAuthenticateWithStreamingPost(StreamingMode.FIXED_LENGTH);
+    }
+
+    public void testAuthenticateWithChunkedStreaming() throws Exception {
+        testAuthenticateWithStreamingPost(StreamingMode.CHUNKED);
+    }
+
+    private void testAuthenticateWithStreamingPost(StreamingMode streamingMode) throws Exception {
+        MockResponse pleaseAuthenticate = new MockResponse()
+                .setResponseCode(401)
+                .addHeader("WWW-Authenticate: Basic realm=\"protected area\"")
+                .setBody("Please authenticate.");
+        server.enqueue(pleaseAuthenticate);
+        server.play();
+
+        Authenticator.setDefault(SIMPLE_AUTHENTICATOR);
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setDoOutput(true);
+        byte[] requestBody = { 'A', 'B', 'C', 'D' };
+        if (streamingMode == StreamingMode.FIXED_LENGTH) {
+            connection.setFixedLengthStreamingMode(requestBody.length);
+        } else if (streamingMode == StreamingMode.CHUNKED) {
+            connection.setChunkedStreamingMode(0);
+        }
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(requestBody);
+        outputStream.close();
+        try {
+            connection.getInputStream();
+            fail();
+        } catch (HttpRetryException expected) {
+        }
+
+        // no authorization header for the request...
+        RecordedRequest request = server.takeRequest();
+        assertContainsNoneMatching(request.getHeaders(), "Authorization: Basic .*");
+        assertEquals(Arrays.toString(requestBody), Arrays.toString(request.getBody()));
+    }
+
+    public void testSetValidRequestMethod() throws Exception {
+        server.play();
+        assertValidRequestMethod("GET");
+        assertValidRequestMethod("DELETE");
+        assertValidRequestMethod("HEAD");
+        assertValidRequestMethod("OPTIONS");
+        assertValidRequestMethod("POST");
+        assertValidRequestMethod("PUT");
+        assertValidRequestMethod("TRACE");
+    }
+
+    private void assertValidRequestMethod(String requestMethod) throws Exception {
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setRequestMethod(requestMethod);
+        assertEquals(requestMethod, connection.getRequestMethod());
+    }
+
+    public void testSetInvalidRequestMethodLowercase() throws Exception {
+        server.play();
+        assertInvalidRequestMethod("get");
+    }
+
+    public void testSetInvalidRequestMethodConnect() throws Exception {
+        server.play();
+        assertInvalidRequestMethod("CONNECT");
+    }
+
+    private void assertInvalidRequestMethod(String requestMethod) throws Exception {
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        try {
+            connection.setRequestMethod(requestMethod);
+            fail();
+        } catch (ProtocolException expected) {
+        }
+    }
+
+    public void testCannotSetNegativeFixedLengthStreamingMode() throws Exception {
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        try {
+            connection.setFixedLengthStreamingMode(-2);
+            fail();
+        } catch (IllegalArgumentException expected) {
+        }
+    }
+
+    public void testCanSetNegativeChunkedStreamingMode() throws Exception {
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setChunkedStreamingMode(-2);
+    }
+
+    public void testCannotSetFixedLengthStreamingModeAfterConnect() throws Exception {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        try {
+            connection.setFixedLengthStreamingMode(1);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testCannotSetChunkedStreamingModeAfterConnect() throws Exception {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        try {
+            connection.setChunkedStreamingMode(1);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testCannotSetFixedLengthStreamingModeAfterChunkedStreamingMode() throws Exception {
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setChunkedStreamingMode(1);
+        try {
+            connection.setFixedLengthStreamingMode(1);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testCannotSetChunkedStreamingModeAfterFixedLengthStreamingMode() throws Exception {
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setFixedLengthStreamingMode(1);
+        try {
+            connection.setChunkedStreamingMode(1);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+    }
+
+    public void testSecureFixedLengthStreaming() throws Exception {
+        testSecureStreamingPost(StreamingMode.FIXED_LENGTH);
+    }
+
+    public void testSecureChunkedStreaming() throws Exception {
+        testSecureStreamingPost(StreamingMode.CHUNKED);
+    }
+
+    /**
+     * Users have reported problems using HTTPS with streaming request bodies.
+     * http://code.google.com/p/android/issues/detail?id=12860
+     */
+    private void testSecureStreamingPost(StreamingMode streamingMode) throws Exception {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse().setBody("Success!"));
+        server.play();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        connection.setDoOutput(true);
+        byte[] requestBody = { 'A', 'B', 'C', 'D' };
+        if (streamingMode == StreamingMode.FIXED_LENGTH) {
+            connection.setFixedLengthStreamingMode(requestBody.length);
+        } else if (streamingMode == StreamingMode.CHUNKED) {
+            connection.setChunkedStreamingMode(0);
+        }
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(requestBody);
+        outputStream.close();
+        assertEquals("Success!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("POST / HTTP/1.1", request.getRequestLine());
+        if (streamingMode == StreamingMode.FIXED_LENGTH) {
+            assertEquals(Collections.<Integer>emptyList(), request.getChunkSizes());
+        } else if (streamingMode == StreamingMode.CHUNKED) {
+            assertEquals(Arrays.asList(4), request.getChunkSizes());
+        }
+        assertEquals(Arrays.toString(requestBody), Arrays.toString(request.getBody()));
+    }
+
+    enum StreamingMode {
+        FIXED_LENGTH, CHUNKED
+    }
+
+    public void testAuthenticateWithPost() throws Exception {
+        MockResponse pleaseAuthenticate = new MockResponse()
+                .setResponseCode(401)
+                .addHeader("WWW-Authenticate: Basic realm=\"protected area\"")
+                .setBody("Please authenticate.");
+        // fail auth three times...
+        server.enqueue(pleaseAuthenticate);
+        server.enqueue(pleaseAuthenticate);
+        server.enqueue(pleaseAuthenticate);
+        // ...then succeed the fourth time
+        server.enqueue(new MockResponse().setBody("Successful auth!"));
+        server.play();
+
+        Authenticator.setDefault(SIMPLE_AUTHENTICATOR);
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setDoOutput(true);
+        byte[] requestBody = { 'A', 'B', 'C', 'D' };
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(requestBody);
+        outputStream.close();
+        assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        // no authorization header for the first request...
+        RecordedRequest request = server.takeRequest();
+        assertContainsNoneMatching(request.getHeaders(), "Authorization: Basic .*");
+
+        // ...but the three requests that follow include an authorization header
+        for (int i = 0; i < 3; i++) {
+            request = server.takeRequest();
+            assertEquals("POST / HTTP/1.1", request.getRequestLine());
+            assertContains(request.getHeaders(), "Authorization: Basic " + BASE_64_CREDENTIALS);
+            assertEquals(Arrays.toString(requestBody), Arrays.toString(request.getBody()));
+        }
+    }
+
+    public void testAuthenticateWithGet() throws Exception {
+        MockResponse pleaseAuthenticate = new MockResponse()
+                .setResponseCode(401)
+                .addHeader("WWW-Authenticate: Basic realm=\"protected area\"")
+                .setBody("Please authenticate.");
+        // fail auth three times...
+        server.enqueue(pleaseAuthenticate);
+        server.enqueue(pleaseAuthenticate);
+        server.enqueue(pleaseAuthenticate);
+        // ...then succeed the fourth time
+        server.enqueue(new MockResponse().setBody("Successful auth!"));
+        server.play();
+
+        Authenticator.setDefault(SIMPLE_AUTHENTICATOR);
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("Successful auth!", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        // no authorization header for the first request...
+        RecordedRequest request = server.takeRequest();
+        assertContainsNoneMatching(request.getHeaders(), "Authorization: Basic .*");
+
+        // ...but the three requests that follow requests include an authorization header
+        for (int i = 0; i < 3; i++) {
+            request = server.takeRequest();
+            assertEquals("GET / HTTP/1.1", request.getRequestLine());
+            assertContains(request.getHeaders(), "Authorization: Basic " + BASE_64_CREDENTIALS);
+        }
+    }
+
+    public void testRedirectedWithChunkedEncoding() throws Exception {
+        testRedirected(TransferKind.CHUNKED, true);
+    }
+
+    public void testRedirectedWithContentLengthHeader() throws Exception {
+        testRedirected(TransferKind.FIXED_LENGTH, true);
+    }
+
+    public void testRedirectedWithNoLengthHeaders() throws Exception {
+        testRedirected(TransferKind.END_OF_STREAM, false);
+    }
+
+    private void testRedirected(TransferKind transferKind, boolean reuse) throws Exception {
+        MockResponse response = new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: /foo");
+        transferKind.setBody(response, "This page has moved!", 10);
+        server.enqueue(response);
+        server.enqueue(new MockResponse().setBody("This is the new location!"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("This is the new location!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        RecordedRequest first = server.takeRequest();
+        assertEquals("GET / HTTP/1.1", first.getRequestLine());
+        RecordedRequest retry = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", retry.getRequestLine());
+        if (reuse) {
+            assertEquals("Expected connection reuse", 1, retry.getSequenceNumber());
+        }
+    }
+
+    public void testRedirectedOnHttps() throws IOException, InterruptedException {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse()
+                .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: /foo")
+                .setBody("This page has moved!"));
+        server.enqueue(new MockResponse().setBody("This is the new location!"));
+        server.play();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertEquals("This is the new location!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        RecordedRequest first = server.takeRequest();
+        assertEquals("GET / HTTP/1.1", first.getRequestLine());
+        RecordedRequest retry = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", retry.getRequestLine());
+        assertEquals("Expected connection reuse", 1, retry.getSequenceNumber());
+    }
+
+    public void testNotRedirectedFromHttpsToHttp() throws IOException, InterruptedException {
+        server.useHttps(sslContext.getSocketFactory(), false);
+        server.enqueue(new MockResponse()
+                .setResponseCode(HttpURLConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: http://anyhost/foo")
+                .setBody("This page has moved!"));
+        server.play();
+
+        OkHttpsConnection connection = (OkHttpsConnection) openConnection(server.getUrl("/"));
+        connection.setSSLSocketFactory(sslContext.getSocketFactory());
+        connection.setHostnameVerifier(new RecordingHostnameVerifier());
+        assertEquals("This page has moved!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+    }
+
+    public void testNotRedirectedFromHttpToHttps() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: https://anyhost/foo")
+                .setBody("This page has moved!"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("This page has moved!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+    }
+
+    public void SUPPRESSED_testRedirectToAnotherOriginServer() throws Exception {
+        MockWebServer server2 = new MockWebServer();
+        server2.enqueue(new MockResponse().setBody("This is the 2nd server!"));
+        server2.play();
+
+        server.enqueue(new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: " + server2.getUrl("/").toString())
+                .setBody("This page has moved!"));
+        server.enqueue(new MockResponse().setBody("This is the first server again!"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("This is the 2nd server!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        assertEquals(server2.getUrl("/"), connection.getURL());
+
+        // make sure the first server was careful to recycle the connection
+        assertEquals("This is the first server again!",
+                readAscii(server.getUrl("/").openStream(), Integer.MAX_VALUE));
+
+        RecordedRequest first = server.takeRequest();
+        assertContains(first.getHeaders(), "Host: " + hostName + ":" + server.getPort());
+        RecordedRequest second = server2.takeRequest();
+        assertContains(second.getHeaders(), "Host: " + hostName + ":" + server2.getPort());
+        RecordedRequest third = server.takeRequest();
+        assertEquals("Expected connection reuse", 1, third.getSequenceNumber());
+
+        server2.shutdown();
+    }
+
+    public void testResponse300MultipleChoiceWithPost() throws Exception {
+        // Chrome doesn't follow the redirect, but Firefox and the RI both do
+        testResponseRedirectedWithPost(OkHttpConnection.HTTP_MULT_CHOICE);
+    }
+
+    public void testResponse301MovedPermanentlyWithPost() throws Exception {
+        testResponseRedirectedWithPost(OkHttpConnection.HTTP_MOVED_PERM);
+    }
+
+    public void testResponse302MovedTemporarilyWithPost() throws Exception {
+        testResponseRedirectedWithPost(OkHttpConnection.HTTP_MOVED_TEMP);
+    }
+
+    public void testResponse303SeeOtherWithPost() throws Exception {
+        testResponseRedirectedWithPost(OkHttpConnection.HTTP_SEE_OTHER);
+    }
+
+    private void testResponseRedirectedWithPost(int redirectCode) throws Exception {
+        server.enqueue(new MockResponse()
+                .setResponseCode(redirectCode)
+                .addHeader("Location: /page2")
+                .setBody("This page has moved!"));
+        server.enqueue(new MockResponse().setBody("Page 2"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/page1"));
+        connection.setDoOutput(true);
+        byte[] requestBody = { 'A', 'B', 'C', 'D' };
+        OutputStream outputStream = connection.getOutputStream();
+        outputStream.write(requestBody);
+        outputStream.close();
+        assertEquals("Page 2", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        assertTrue(connection.getDoOutput());
+
+        RecordedRequest page1 = server.takeRequest();
+        assertEquals("POST /page1 HTTP/1.1", page1.getRequestLine());
+        assertEquals(Arrays.toString(requestBody), Arrays.toString(page1.getBody()));
+
+        RecordedRequest page2 = server.takeRequest();
+        assertEquals("GET /page2 HTTP/1.1", page2.getRequestLine());
+    }
+
+    public void testResponse305UseProxy() throws Exception {
+        server.play();
+        server.enqueue(new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_USE_PROXY)
+                .addHeader("Location: " + server.getUrl("/"))
+                .setBody("This page has moved!"));
+        server.enqueue(new MockResponse().setBody("Proxy Response"));
+
+        OkHttpConnection connection = openConnection(server.getUrl("/foo"));
+        // Fails on the RI, which gets "Proxy Response"
+        assertEquals("This page has moved!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        RecordedRequest page1 = server.takeRequest();
+        assertEquals("GET /foo HTTP/1.1", page1.getRequestLine());
+        assertEquals(1, server.getRequestCount());
+    }
+
+//    public void testHttpsWithCustomTrustManager() throws Exception {
+//        RecordingHostnameVerifier hostnameVerifier = new RecordingHostnameVerifier();
+//        RecordingTrustManager trustManager = new RecordingTrustManager();
+//        SSLContext sc = SSLContext.getInstance("TLS");
+//        sc.init(null, new TrustManager[] { trustManager }, new java.security.SecureRandom());
+//
+//        HostnameVerifier defaultHostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+//        HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
+//        SSLSocketFactory defaultSSLSocketFactory = HttpsURLConnection.getDefaultSSLSocketFactory();
+//        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
+//        try {
+//            TestSSLContext testSSLContext = TestSSLContext.create();
+//            server.useHttps(testSSLContext.serverContext.getSocketFactory(), false);
+//            server.enqueue(new MockResponse().setBody("ABC"));
+//            server.enqueue(new MockResponse().setBody("DEF"));
+//            server.enqueue(new MockResponse().setBody("GHI"));
+//            server.play();
+//
+//            URL url = server.getUrl("/");
+//            assertEquals("ABC", readAscii(url.openStream(), Integer.MAX_VALUE));
+//            assertEquals("DEF", readAscii(url.openStream(), Integer.MAX_VALUE));
+//            assertEquals("GHI", readAscii(url.openStream(), Integer.MAX_VALUE));
+//
+//            assertEquals(Arrays.asList("verify " + hostName), hostnameVerifier.calls);
+//            assertEquals(Arrays.asList("checkServerTrusted ["
+//                    + "CN=" + hostName + " 1, "
+//                    + "CN=Test Intermediate Certificate Authority 1, "
+//                    + "CN=Test Root Certificate Authority 1"
+//                    + "] RSA"),
+//                    trustManager.calls);
+//        } finally {
+//            HttpsURLConnection.setDefaultHostnameVerifier(defaultHostnameVerifier);
+//            HttpsURLConnection.setDefaultSSLSocketFactory(defaultSSLSocketFactory);
+//        }
+//    }
+//
+//    public void testConnectTimeouts() throws IOException {
+//        StuckServer ss = new StuckServer();
+//        int serverPort = ss.getLocalPort();
+//        URLConnection urlConnection = new URL("http://localhost:" + serverPort).openConnection();
+//        int timeout = 1000;
+//        urlConnection.setConnectTimeout(timeout);
+//        long start = System.currentTimeMillis();
+//        try {
+//            urlConnection.getInputStream();
+//            fail();
+//        } catch (SocketTimeoutException expected) {
+//            long actual = System.currentTimeMillis() - start;
+//            assertTrue(Math.abs(timeout - actual) < 500);
+//        } finally {
+//            ss.close();
+//        }
+//    }
+
+    public void testReadTimeouts() throws IOException {
+        /*
+         * This relies on the fact that MockWebServer doesn't close the
+         * connection after a response has been sent. This causes the client to
+         * try to read more bytes than are sent, which results in a timeout.
+         */
+        MockResponse timeout = new MockResponse()
+                .setBody("ABC")
+                .clearHeaders()
+                .addHeader("Content-Length: 4");
+        server.enqueue(timeout);
+        server.enqueue(new MockResponse().setBody("unused")); // to keep the server alive
+        server.play();
+
+        URLConnection urlConnection = openConnection(server.getUrl("/"));
+        urlConnection.setReadTimeout(1000);
+        InputStream in = urlConnection.getInputStream();
+        assertEquals('A', in.read());
+        assertEquals('B', in.read());
+        assertEquals('C', in.read());
+        try {
+            in.read(); // if Content-Length was accurate, this would return -1 immediately
+            fail();
+        } catch (SocketTimeoutException expected) {
+        }
+    }
+
+    public void testSetChunkedEncodingAsRequestProperty() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection urlConnection = openConnection(server.getUrl("/"));
+        urlConnection.setRequestProperty("Transfer-encoding", "chunked");
+        urlConnection.setDoOutput(true);
+        urlConnection.getOutputStream().write("ABC".getBytes("UTF-8"));
+        assertEquals(200, urlConnection.getResponseCode());
+
+        RecordedRequest request = server.takeRequest();
+        assertEquals("ABC", new String(request.getBody(), "UTF-8"));
+    }
+
+    public void testConnectionCloseInRequest() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse()); // server doesn't honor the connection: close header!
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection a = openConnection(server.getUrl("/"));
+        a.setRequestProperty("Connection", "close");
+        assertEquals(200, a.getResponseCode());
+
+        OkHttpConnection b = openConnection(server.getUrl("/"));
+        assertEquals(200, b.getResponseCode());
+
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertEquals("When connection: close is used, each request should get its own connection",
+                0, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testConnectionCloseInResponse() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse().addHeader("Connection: close"));
+        server.enqueue(new MockResponse());
+        server.play();
+
+        OkHttpConnection a = openConnection(server.getUrl("/"));
+        assertEquals(200, a.getResponseCode());
+
+        OkHttpConnection b = openConnection(server.getUrl("/"));
+        assertEquals(200, b.getResponseCode());
+
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertEquals("When connection: close is used, each request should get its own connection",
+                0, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testConnectionCloseWithRedirect() throws IOException, InterruptedException {
+        MockResponse response = new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_MOVED_TEMP)
+                .addHeader("Location: /foo")
+                .addHeader("Connection: close");
+        server.enqueue(response);
+        server.enqueue(new MockResponse().setBody("This is the new location!"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("This is the new location!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        assertEquals(0, server.takeRequest().getSequenceNumber());
+        assertEquals("When connection: close is used, each request should get its own connection",
+                0, server.takeRequest().getSequenceNumber());
+    }
+
+    public void testResponseCodeDisagreesWithHeaders() throws IOException, InterruptedException {
+        server.enqueue(new MockResponse()
+                .setResponseCode(OkHttpConnection.HTTP_NO_CONTENT)
+                .setBody("This body is not allowed!"));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("This body is not allowed!",
+                readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+    }
+
+    public void testSingleByteReadIsSigned() throws IOException {
+        server.enqueue(new MockResponse().setBody(new byte[] { -2, -1 }));
+        server.play();
+
+        URLConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = connection.getInputStream();
+        assertEquals(254, in.read());
+        assertEquals(255, in.read());
+        assertEquals(-1, in.read());
+    }
+
+    public void testFlushAfterStreamTransmittedWithChunkedEncoding() throws IOException {
+        testFlushAfterStreamTransmitted(TransferKind.CHUNKED);
+    }
+
+    public void testFlushAfterStreamTransmittedWithFixedLength() throws IOException {
+        testFlushAfterStreamTransmitted(TransferKind.FIXED_LENGTH);
+    }
+
+    public void testFlushAfterStreamTransmittedWithNoLengthHeaders() throws IOException {
+        testFlushAfterStreamTransmitted(TransferKind.END_OF_STREAM);
+    }
+
+    /**
+     * We explicitly permit apps to close the upload stream even after it has
+     * been transmitted.  We also permit flush so that buffered streams can
+     * do a no-op flush when they are closed. http://b/3038470
+     */
+    private void testFlushAfterStreamTransmitted(TransferKind transferKind) throws IOException {
+        server.enqueue(new MockResponse().setBody("abc"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setDoOutput(true);
+        byte[] upload = "def".getBytes("UTF-8");
+
+        if (transferKind == TransferKind.CHUNKED) {
+            connection.setChunkedStreamingMode(0);
+        } else if (transferKind == TransferKind.FIXED_LENGTH) {
+            connection.setFixedLengthStreamingMode(upload.length);
+        }
+
+        OutputStream out = connection.getOutputStream();
+        out.write(upload);
+        assertEquals("abc", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+
+        out.flush(); // dubious but permitted
+        try {
+            out.write("ghi".getBytes("UTF-8"));
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void testGetHeadersThrows() throws IOException {
+        server.enqueue(new MockResponse().setSocketPolicy(DISCONNECT_AT_START));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        try {
+            connection.getInputStream();
+            fail();
+        } catch (IOException expected) {
+        }
+
+        try {
+            connection.getInputStream();
+            fail();
+        } catch (IOException expected) {
+        }
+    }
+
+    public void SUPPRESSED_testGetKeepAlive() throws Exception {
+        MockWebServer server = new MockWebServer();
+        server.enqueue(new MockResponse().setBody("ABC"));
+        server.play();
+
+        // The request should work once and then fail
+        URLConnection connection = openConnection(server.getUrl(""));
+        InputStream input = connection.getInputStream();
+        assertEquals("ABC", readAscii(input, Integer.MAX_VALUE));
+        input.close();
+        try {
+            openConnection(server.getUrl("")).getInputStream();
+            fail();
+        } catch (ConnectException expected) {
+        }
+    }
+
+    /**
+     * This test goes through the exhaustive set of interesting ASCII characters
+     * because most of those characters are interesting in some way according to
+     * RFC 2396 and RFC 2732. http://b/1158780
+     */
+    public void SUPPRESSED_testLenientUrlToUri() throws Exception {
+        // alphanum
+        testUrlToUriMapping("abzABZ09", "abzABZ09", "abzABZ09", "abzABZ09", "abzABZ09");
+
+        // control characters
+        testUrlToUriMapping("\u0001", "%01", "%01", "%01", "%01");
+        testUrlToUriMapping("\u001f", "%1F", "%1F", "%1F", "%1F");
+
+        // ascii characters
+        testUrlToUriMapping("%20", "%20", "%20", "%20", "%20");
+        testUrlToUriMapping("%20", "%20", "%20", "%20", "%20");
+        testUrlToUriMapping(" ", "%20", "%20", "%20", "%20");
+        testUrlToUriMapping("!", "!", "!", "!", "!");
+        testUrlToUriMapping("\"", "%22", "%22", "%22", "%22");
+        testUrlToUriMapping("#", null, null, null, "%23");
+        testUrlToUriMapping("$", "$", "$", "$", "$");
+        testUrlToUriMapping("&", "&", "&", "&", "&");
+        testUrlToUriMapping("'", "'", "'", "'", "'");
+        testUrlToUriMapping("(", "(", "(", "(", "(");
+        testUrlToUriMapping(")", ")", ")", ")", ")");
+        testUrlToUriMapping("*", "*", "*", "*", "*");
+        testUrlToUriMapping("+", "+", "+", "+", "+");
+        testUrlToUriMapping(",", ",", ",", ",", ",");
+        testUrlToUriMapping("-", "-", "-", "-", "-");
+        testUrlToUriMapping(".", ".", ".", ".", ".");
+        testUrlToUriMapping("/", null, "/", "/", "/");
+        testUrlToUriMapping(":", null, ":", ":", ":");
+        testUrlToUriMapping(";", ";", ";", ";", ";");
+        testUrlToUriMapping("<", "%3C", "%3C", "%3C", "%3C");
+        testUrlToUriMapping("=", "=", "=", "=", "=");
+        testUrlToUriMapping(">", "%3E", "%3E", "%3E", "%3E");
+        testUrlToUriMapping("?", null, null, "?", "?");
+        testUrlToUriMapping("@", "@", "@", "@", "@");
+        testUrlToUriMapping("[", null, "%5B", null, "%5B");
+        testUrlToUriMapping("\\", "%5C", "%5C", "%5C", "%5C");
+        testUrlToUriMapping("]", null, "%5D", null, "%5D");
+        testUrlToUriMapping("^", "%5E", "%5E", "%5E", "%5E");
+        testUrlToUriMapping("_", "_", "_", "_", "_");
+        testUrlToUriMapping("`", "%60", "%60", "%60", "%60");
+        testUrlToUriMapping("{", "%7B", "%7B", "%7B", "%7B");
+        testUrlToUriMapping("|", "%7C", "%7C", "%7C", "%7C");
+        testUrlToUriMapping("}", "%7D", "%7D", "%7D", "%7D");
+        testUrlToUriMapping("~", "~", "~", "~", "~");
+        testUrlToUriMapping("~", "~", "~", "~", "~");
+        testUrlToUriMapping("\u007f", "%7F", "%7F", "%7F", "%7F");
+
+        // beyond ascii
+        testUrlToUriMapping("\u0080", "%C2%80", "%C2%80", "%C2%80", "%C2%80");
+        testUrlToUriMapping("\u20ac", "\u20ac", "\u20ac", "\u20ac", "\u20ac");
+        testUrlToUriMapping("\ud842\udf9f",
+                "\ud842\udf9f", "\ud842\udf9f", "\ud842\udf9f", "\ud842\udf9f");
+    }
+
+    public void SUPPRESSED_testLenientUrlToUriNul() throws Exception {
+        testUrlToUriMapping("\u0000", "%00", "%00", "%00", "%00"); // RI fails this
+    }
+
+    private void testUrlToUriMapping(String string, String asAuthority, String asFile,
+            String asQuery, String asFragment) throws Exception {
+        if (asAuthority != null) {
+            assertEquals("http://host" + asAuthority + ".tld/",
+                    backdoorUrlToUri(new URL("http://host" + string + ".tld/")).toString());
+        }
+        if (asFile != null) {
+            assertEquals("http://host.tld/file" + asFile + "/",
+                    backdoorUrlToUri(new URL("http://host.tld/file" + string + "/")).toString());
+        }
+        if (asQuery != null) {
+            assertEquals("http://host.tld/file?q" + asQuery + "=x",
+                    backdoorUrlToUri(new URL("http://host.tld/file?q" + string + "=x")).toString());
+        }
+        assertEquals("http://host.tld/file#" + asFragment + "-x",
+                backdoorUrlToUri(new URL("http://host.tld/file#" + asFragment + "-x")).toString());
+    }
+
+    /**
+     * Exercises HttpURLConnection to convert URL to a URI. Unlike URL#toURI,
+     * HttpURLConnection recovers from URLs with unescaped but unsupported URI
+     * characters like '{' and '|' by escaping these characters.
+     */
+    private URI backdoorUrlToUri(URL url) throws Exception {
+        final AtomicReference<URI> uriReference = new AtomicReference<URI>();
+
+        ResponseCache.setDefault(new ResponseCache() {
+            @Override public CacheRequest put(URI uri, URLConnection connection) throws IOException {
+                return null;
+            }
+            @Override public CacheResponse get(URI uri, String requestMethod,
+                    Map<String, List<String>> requestHeaders) throws IOException {
+                uriReference.set(uri);
+                throw new UnsupportedOperationException();
+            }
+        });
+
+        try {
+            OkHttpConnection connection = openConnection(url);
+            connection.getResponseCode();
+        } catch (Exception expected) {
+            if (expected.getCause() instanceof URISyntaxException) {
+                expected.printStackTrace();
+            }
+        }
+
+        return uriReference.get();
+    }
+
+    /**
+     * Don't explode if the cache returns a null body. http://b/3373699
+     */
+    public void testResponseCacheReturnsNullOutputStream() throws Exception {
+        final AtomicBoolean aborted = new AtomicBoolean();
+        ResponseCache.setDefault(new ResponseCache() {
+            @Override public CacheResponse get(URI uri, String requestMethod,
+                    Map<String, List<String>> requestHeaders) throws IOException {
+                return null;
+            }
+            @Override public CacheRequest put(URI uri, URLConnection connection) throws IOException {
+                return new CacheRequest() {
+                    @Override public void abort() {
+                        aborted.set(true);
+                    }
+                    @Override public OutputStream getBody() throws IOException {
+                        return null;
+                    }
+                };
+            }
+        });
+
+        server.enqueue(new MockResponse().setBody("abcdef"));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = connection.getInputStream();
+        assertEquals("abc", readAscii(in, 3));
+        in.close();
+        assertFalse(aborted.get()); // The best behavior is ambiguous, but RI 6 doesn't abort here
+    }
+
+
+    /**
+     * http://code.google.com/p/android/issues/detail?id=14562
+     */
+    public void testReadAfterLastByte() throws Exception {
+        server.enqueue(new MockResponse()
+                .setBody("ABC")
+                .clearHeaders()
+                .addHeader("Connection: close")
+                .setSocketPolicy(SocketPolicy.DISCONNECT_AT_END));
+        server.play();
+
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = connection.getInputStream();
+        assertEquals("ABC", readAscii(in, 3));
+        assertEquals(-1, in.read());
+        assertEquals(-1, in.read()); // throws IOException in Gingerbread
+    }
+
+    public void testGetContent() throws Exception {
+        server.enqueue(new MockResponse()
+                .addHeader("Content-Type: text/plain")
+                .setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = (InputStream) connection.getContent();
+        assertEquals("A", readAscii(in, Integer.MAX_VALUE));
+    }
+
+    public void testGetContentOfType() throws Exception {
+        server.enqueue(new MockResponse()
+                .addHeader("Content-Type: text/plain")
+                .setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        try {
+            connection.getContent(null);
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        try {
+            connection.getContent(new Class[] { null });
+            fail();
+        } catch (NullPointerException expected) {
+        }
+        assertNull(connection.getContent(new Class[] { getClass() }));
+        connection.disconnect();
+    }
+
+    public void testGetOutputStreamOnGetFails() throws Exception {
+        server.enqueue(new MockResponse());
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        try {
+            connection.getOutputStream();
+            fail();
+        } catch (ProtocolException expected) {
+        }
+    }
+
+    public void testGetOutputAfterGetInputStreamFails() throws Exception {
+        server.enqueue(new MockResponse());
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setDoOutput(true);
+        try {
+            connection.getInputStream();
+            connection.getOutputStream();
+            fail();
+        } catch (ProtocolException expected) {
+        }
+    }
+
+    public void testSetDoOutputOrDoInputAfterConnectFails() throws Exception {
+        server.enqueue(new MockResponse());
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.connect();
+        try {
+            connection.setDoOutput(true);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        try {
+            connection.setDoInput(true);
+            fail();
+        } catch (IllegalStateException expected) {
+        }
+        connection.disconnect();
+    }
+
+    public void testClientSendsContentLength() throws Exception {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        connection.setDoOutput(true);
+        OutputStream out = connection.getOutputStream();
+        out.write(new byte[] { 'A', 'B', 'C' });
+        out.close();
+        assertEquals("A", readAscii(connection.getInputStream(), Integer.MAX_VALUE));
+        RecordedRequest request = server.takeRequest();
+        assertContains(request.getHeaders(), "Content-Length: 3");
+    }
+
+    public void testGetContentLengthConnects() throws Exception {
+        server.enqueue(new MockResponse().setBody("ABC"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals(3, connection.getContentLength());
+        connection.disconnect();
+    }
+
+    public void testGetContentTypeConnects() throws Exception {
+        server.enqueue(new MockResponse()
+                .addHeader("Content-Type: text/plain")
+                .setBody("ABC"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("text/plain", connection.getContentType());
+        connection.disconnect();
+    }
+
+    public void testGetContentEncodingConnects() throws Exception {
+        server.enqueue(new MockResponse()
+                .addHeader("Content-Encoding: identity")
+                .setBody("ABC"));
+        server.play();
+        OkHttpConnection connection = openConnection(server.getUrl("/"));
+        assertEquals("identity", connection.getContentEncoding());
+        connection.disconnect();
+    }
+
+    // http://b/4361656
+    public void testUrlContainsQueryButNoPath() throws Exception {
+        server.enqueue(new MockResponse().setBody("A"));
+        server.play();
+        URL url = new URL("http", server.getHostName(), server.getPort(), "?query");
+        assertEquals("A", readAscii(openConnection(url).getInputStream(), Integer.MAX_VALUE));
+        RecordedRequest request = server.takeRequest();
+        assertEquals("GET /?query HTTP/1.1", request.getRequestLine());
+    }
+
+    // http://code.google.com/p/android/issues/detail?id=20442
+    public void testInputStreamAvailableWithChunkedEncoding() throws Exception {
+        testInputStreamAvailable(TransferKind.CHUNKED);
+    }
+
+    public void testInputStreamAvailableWithContentLengthHeader() throws Exception {
+        testInputStreamAvailable(TransferKind.FIXED_LENGTH);
+    }
+
+    public void testInputStreamAvailableWithNoLengthHeaders() throws Exception {
+        testInputStreamAvailable(TransferKind.END_OF_STREAM);
+    }
+
+    private void testInputStreamAvailable(TransferKind transferKind) throws IOException {
+        String body = "ABCDEFGH";
+        MockResponse response = new MockResponse();
+        transferKind.setBody(response, body, 4);
+        server.enqueue(response);
+        server.play();
+        URLConnection connection = openConnection(server.getUrl("/"));
+        InputStream in = connection.getInputStream();
+        for (int i = 0; i < body.length(); i++) {
+            assertTrue(in.available() >= 0);
+            assertEquals(body.charAt(i), in.read());
+        }
+        assertEquals(0, in.available());
+        assertEquals(-1, in.read());
+    }
+
+    /**
+     * Returns a gzipped copy of {@code bytes}.
+     */
+    public byte[] gzip(byte[] bytes) throws IOException {
+        ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
+        OutputStream gzippedOut = new GZIPOutputStream(bytesOut);
+        gzippedOut.write(bytes);
+        gzippedOut.close();
+        return bytesOut.toByteArray();
+    }
+
+    /**
+     * Reads at most {@code limit} characters from {@code in} and asserts that
+     * content equals {@code expected}.
+     */
+    private void assertContent(String expected, URLConnection connection, int limit)
+            throws IOException {
+        connection.connect();
+        assertEquals(expected, readAscii(connection.getInputStream(), limit));
+        ((OkHttpConnection) connection).disconnect();
+    }
+
+    private void assertContent(String expected, URLConnection connection) throws IOException {
+        assertContent(expected, connection, Integer.MAX_VALUE);
+    }
+
+    private void assertContains(List<String> headers, String header) {
+        assertTrue(headers.toString(), headers.contains(header));
+    }
+
+    private void assertContainsNoneMatching(List<String> headers, String pattern) {
+        for (String header : headers) {
+            if (header.matches(pattern)) {
+                fail("Header " + header + " matches " + pattern);
+            }
+        }
+    }
+
+    private Set<String> newSet(String... elements) {
+        return new HashSet<String>(Arrays.asList(elements));
+    }
+
+    enum TransferKind {
+        CHUNKED() {
+            @Override void setBody(MockResponse response, byte[] content, int chunkSize)
+                    throws IOException {
+                response.setChunkedBody(content, chunkSize);
+            }
+        },
+        FIXED_LENGTH() {
+            @Override void setBody(MockResponse response, byte[] content, int chunkSize) {
+                response.setBody(content);
+            }
+        },
+        END_OF_STREAM() {
+            @Override void setBody(MockResponse response, byte[] content, int chunkSize) {
+                response.setBody(content);
+                response.setSocketPolicy(DISCONNECT_AT_END);
+                for (Iterator<String> h = response.getHeaders().iterator(); h.hasNext(); ) {
+                    if (h.next().startsWith("Content-Length:")) {
+                        h.remove();
+                        break;
+                    }
+                }
+            }
+        };
+
+        abstract void setBody(MockResponse response, byte[] content, int chunkSize)
+                throws IOException;
+
+        void setBody(MockResponse response, String content, int chunkSize) throws IOException {
+            setBody(response, content.getBytes("UTF-8"), chunkSize);
+        }
+    }
+
+    enum ProxyConfig {
+        NO_PROXY() {
+            @Override public OkHttpConnection connect(MockWebServer server, URL url)
+                    throws IOException {
+                return openConnection(url, Proxy.NO_PROXY);
+            }
+        },
+
+        CREATE_ARG() {
+            @Override public OkHttpConnection connect(MockWebServer server, URL url)
+                    throws IOException {
+                return openConnection(url, server.toProxyAddress());
+            }
+        },
+
+        PROXY_SYSTEM_PROPERTY() {
+            @Override public OkHttpConnection connect(MockWebServer server, URL url)
+                    throws IOException {
+                System.setProperty("proxyHost", "localhost");
+                System.setProperty("proxyPort", Integer.toString(server.getPort()));
+                return openConnection(url);
+            }
+        },
+
+        HTTP_PROXY_SYSTEM_PROPERTY() {
+            @Override public OkHttpConnection connect(MockWebServer server, URL url)
+                    throws IOException {
+                System.setProperty("http.proxyHost", "localhost");
+                System.setProperty("http.proxyPort", Integer.toString(server.getPort()));
+                return openConnection(url);
+            }
+        },
+
+        HTTPS_PROXY_SYSTEM_PROPERTY() {
+            @Override public OkHttpConnection connect(MockWebServer server, URL url)
+                    throws IOException {
+                System.setProperty("https.proxyHost", "localhost");
+                System.setProperty("https.proxyPort", Integer.toString(server.getPort()));
+                return openConnection(url);
+            }
+        };
+
+        public abstract OkHttpConnection connect(MockWebServer server, URL url) throws IOException;
+    }
+
+    private static class RecordingTrustManager implements X509TrustManager {
+        private final List<String> calls = new ArrayList<String>();
+
+        public X509Certificate[] getAcceptedIssuers() {
+            calls.add("getAcceptedIssuers");
+            return new X509Certificate[] {};
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain, String authType)
+                throws CertificateException {
+            calls.add("checkClientTrusted " + certificatesToString(chain) + " " + authType);
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain, String authType)
+                throws CertificateException {
+            calls.add("checkServerTrusted " + certificatesToString(chain) + " " + authType);
+        }
+
+        private String certificatesToString(X509Certificate[] certificates) {
+            List<String> result = new ArrayList<String>();
+            for (X509Certificate certificate : certificates) {
+                result.add(certificate.getSubjectDN() + " " + certificate.getSerialNumber());
+            }
+            return result.toString();
+        }
+    }
+
+    private static class RecordingHostnameVerifier implements HostnameVerifier {
+        private final List<String> calls = new ArrayList<String>();
+
+        public boolean verify(String hostname, SSLSession session) {
+            calls.add("verify " + hostname);
+            return true;
+        }
+    }
+}
diff --git a/src/test/java/libcore/net/spdy/MockSpdyPeer.java b/src/test/java/libcore/net/spdy/MockSpdyPeer.java
new file mode 100644
index 0000000..0ea3d86
--- /dev/null
+++ b/src/test/java/libcore/net/spdy/MockSpdyPeer.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import libcore.io.Streams;
+
+/**
+ * Replays prerecorded outgoing frames and records incoming frames.
+ */
+public final class MockSpdyPeer {
+    private int frameCount = 0;
+    private final List<OutFrame> outFrames = new ArrayList<OutFrame>();
+    private final BlockingQueue<InFrame> inFrames = new LinkedBlockingQueue<InFrame>();
+    private int port;
+    private final Executor executor = Executors.newCachedThreadPool(
+            Threads.newThreadFactory("MockSpdyPeer"));
+
+    public void acceptFrame() {
+        frameCount++;
+    }
+
+    public SpdyWriter sendFrame() {
+        OutFrame frame = new OutFrame(frameCount++);
+        outFrames.add(frame);
+        return new SpdyWriter(frame.out);
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public InFrame takeFrame() throws InterruptedException {
+        return inFrames.take();
+    }
+
+    public void play() throws IOException {
+        final ServerSocket serverSocket = new ServerSocket(0);
+        serverSocket.setReuseAddress(true);
+        this.port = serverSocket.getLocalPort();
+        executor.execute(new Runnable() {
+            @Override public void run() {
+                try {
+                    readAndWriteFrames(serverSocket);
+                } catch (IOException e) {
+                    e.printStackTrace(); // TODO
+                }
+            }
+        });
+    }
+
+    private void readAndWriteFrames(ServerSocket serverSocket) throws IOException {
+        Socket socket = serverSocket.accept();
+        OutputStream out = socket.getOutputStream();
+        InputStream in = socket.getInputStream();
+
+        Iterator<OutFrame> outFramesIterator = outFrames.iterator();
+        OutFrame nextOutFrame = null;
+
+        for (int i = 0; i < frameCount; i++) {
+            if (nextOutFrame == null && outFramesIterator.hasNext()) {
+                nextOutFrame = outFramesIterator.next();
+            }
+
+            if (nextOutFrame != null && nextOutFrame.sequence == i) {
+                // write a frame
+                nextOutFrame.out.writeTo(out);
+                nextOutFrame = null;
+
+            } else {
+                // read a frame
+                SpdyReader reader = new SpdyReader(in);
+                byte[] data = null;
+                int type = reader.nextFrame();
+                if (type == SpdyConnection.TYPE_DATA) {
+                    data = new byte[reader.length];
+                    Streams.readFully(in, data);
+                }
+                inFrames.add(new InFrame(i, reader, data));
+            }
+        }
+    }
+
+    public Socket openSocket() throws IOException {
+        return new Socket("localhost", port);
+    }
+
+    private static class OutFrame {
+        private final int sequence;
+        private final ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+        private OutFrame(int sequence) {
+            this.sequence = sequence;
+        }
+    }
+
+    public static class InFrame {
+        public final int sequence;
+        public final SpdyReader reader;
+        public final byte[] data;
+
+        public InFrame(int sequence, SpdyReader reader, byte[] data) {
+            this.sequence = sequence;
+            this.reader = reader;
+            this.data = data;
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/test/java/libcore/net/spdy/SpdyConnectionTest.java b/src/test/java/libcore/net/spdy/SpdyConnectionTest.java
new file mode 100644
index 0000000..09172fa
--- /dev/null
+++ b/src/test/java/libcore/net/spdy/SpdyConnectionTest.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.spdy;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.util.Arrays;
+import java.util.List;
+import junit.framework.TestCase;
+
+public final class SpdyConnectionTest extends TestCase {
+    private final MockSpdyPeer peer = new MockSpdyPeer();
+
+    public void testClientCreatesStreamAndServerReplies() throws Exception {
+        // write the mocking script
+        peer.acceptFrame();
+        SpdyWriter reply = peer.sendFrame();
+        reply.streamId = 1;
+        reply.nameValueBlock = Arrays.asList("a", "android");
+        reply.synReply();
+        SpdyWriter replyData = peer.sendFrame();
+        replyData.flags = SpdyConnection.FLAG_FIN;
+        replyData.streamId = 1;
+        replyData.data("robot".getBytes("UTF-8"));
+        peer.acceptFrame();
+        peer.play();
+
+        // play it back
+        SpdyConnection connection = new SpdyConnection.Builder(true, peer.openSocket()).build();
+        SpdyStream stream = connection.newStream(Arrays.asList("b", "banana"), true, true);
+        List<String> responseHeaders = stream.getResponseHeaders();
+        assertEquals(Arrays.asList("a", "android"), responseHeaders);
+        BufferedReader reader = new BufferedReader(new InputStreamReader(stream.getInputStream()));
+        assertEquals("robot", reader.readLine());
+        assertEquals(null, reader.readLine());
+        OutputStream out = stream.getOutputStream();
+        out.write("c3po".getBytes("UTF-8"));
+        out.close();
+
+        // verify the peer received what was expected
+        MockSpdyPeer.InFrame synStream = peer.takeFrame();
+        assertEquals(0, synStream.reader.flags);
+        assertEquals(1, synStream.reader.streamId);
+        assertEquals(0, synStream.reader.associatedStreamId);
+        assertEquals(Arrays.asList("b", "banana"), synStream.reader.nameValueBlock);
+        MockSpdyPeer.InFrame requestData = peer.takeFrame();
+        assertTrue(Arrays.equals("c3po".getBytes("UTF-8"), requestData.data));
+    }
+
+    public void testServerCreatesStreamAndClientReplies() throws Exception {
+        // write the mocking script
+        SpdyWriter newStream = peer.sendFrame();
+        newStream.flags = 0;
+        newStream.streamId = 2;
+        newStream.associatedStreamId = 0;
+        newStream.nameValueBlock = Arrays.asList("a", "android");
+        newStream.synStream();
+        peer.acceptFrame();
+        peer.play();
+
+        // play it back
+        IncomingStreamHandler handler = new IncomingStreamHandler() {
+            @Override public void receive(SpdyStream stream) throws IOException {
+                assertEquals(Arrays.asList("a", "android"), stream.getRequestHeaders());
+                assertEquals(-1, stream.getRstStatusCode());
+                stream.reply(Arrays.asList("b", "banana"));
+            }
+        };
+        new SpdyConnection.Builder(true, peer.openSocket())
+                .handler(handler)
+                .build();
+
+        // verify the peer received what was expected
+        MockSpdyPeer.InFrame synStream = peer.takeFrame();
+        assertEquals(0, synStream.reader.flags);
+        assertEquals(2, synStream.reader.streamId);
+        assertEquals(0, synStream.reader.associatedStreamId);
+        assertEquals(Arrays.asList("b", "banana"), synStream.reader.nameValueBlock);
+    }
+}
diff --git a/src/test/java/libcore/net/ssl/SslContextBuilder.java b/src/test/java/libcore/net/ssl/SslContextBuilder.java
new file mode 100644
index 0000000..d88ca9c
--- /dev/null
+++ b/src/test/java/libcore/net/ssl/SslContextBuilder.java
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2012 Square, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package libcore.net.ssl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.KeyStore;
+import java.security.SecureRandom;
+import java.security.Security;
+import java.security.cert.Certificate;
+import java.security.cert.X509Certificate;
+import java.util.Date;
+import javax.net.ssl.KeyManagerFactory;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManagerFactory;
+import javax.security.auth.x500.X500Principal;
+import org.bouncycastle.jce.provider.BouncyCastleProvider;
+import org.bouncycastle.x509.X509V3CertificateGenerator;
+
+/**
+ * Constructs an SSL context for testing. This uses Bouncy Castle to generate a
+ * self-signed certificate for a single hostname such as "localhost".
+ *
+ * <p>The crypto performed by this class is relatively slow. Clients should
+ * reuse SSL context instances where possible.
+ */
+public final class SslContextBuilder {
+    static {
+        Security.addProvider(new BouncyCastleProvider());
+    }
+
+    private static final long ONE_DAY_MILLIS = 1000L * 60 * 60 * 24;
+    private final String hostName;
+    private long notBefore = System.currentTimeMillis();
+    private long notAfter = System.currentTimeMillis() + ONE_DAY_MILLIS;
+
+    /**
+     * @param hostName the subject of the host. For TLS this should be the
+     *     domain name that the client uses to identify the server.
+     */
+    public SslContextBuilder(String hostName) {
+        this.hostName = hostName;
+    }
+
+    public SSLContext build() throws GeneralSecurityException {
+        char[] password = "password".toCharArray();
+
+        // Generate public and private keys and use them to make a self-signed certificate.
+        KeyPair keyPair = generateKeyPair();
+        X509Certificate certificate = selfSignedCertificate(keyPair);
+
+        // Put 'em in a key store.
+        KeyStore keyStore = newEmptyKeyStore(password);
+        Certificate[] certificateChain = {
+                certificate
+        };
+        keyStore.setKeyEntry("private", keyPair.getPrivate(), password, certificateChain);
+        keyStore.setCertificateEntry("cert", certificate);
+
+        // Wrap it up in an SSL context.
+        KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
+                KeyManagerFactory.getDefaultAlgorithm());
+        keyManagerFactory.init(keyStore, password);
+        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
+                TrustManagerFactory.getDefaultAlgorithm());
+        trustManagerFactory.init(keyStore);
+        SSLContext sslContext = SSLContext.getInstance("TLS");
+        sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(),
+                new SecureRandom());
+        return sslContext;
+    }
+
+    private KeyPair generateKeyPair() throws GeneralSecurityException {
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
+        keyPairGenerator.initialize(1024, new SecureRandom());
+        return keyPairGenerator.generateKeyPair();
+    }
+
+    /**
+     * Generates a certificate for {@code hostName} containing {@code keyPair}'s
+     * public key, signed by {@code keyPair}'s private key.
+     */
+    @SuppressWarnings("deprecation") // use the old Bouncy Castle APIs to reduce dependencies.
+    private X509Certificate selfSignedCertificate(KeyPair keyPair) throws GeneralSecurityException {
+        X509V3CertificateGenerator generator = new X509V3CertificateGenerator();
+        X500Principal issuer = new X500Principal("CN=" + hostName);
+        X500Principal subject = new X500Principal("CN=" + hostName);
+        generator.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
+        generator.setIssuerDN(issuer);
+        generator.setNotBefore(new Date(notBefore));
+        generator.setNotAfter(new Date(notAfter));
+        generator.setSubjectDN(subject);
+        generator.setPublicKey(keyPair.getPublic());
+        generator.setSignatureAlgorithm("SHA256WithRSAEncryption");
+        return generator.generateX509Certificate(keyPair.getPrivate(), "BC");
+    }
+
+    private KeyStore newEmptyKeyStore(char[] password) throws GeneralSecurityException {
+        try {
+            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
+            InputStream in = null; // By convention, 'null' creates an empty key store.
+            keyStore.load(in, password);
+            return keyStore;
+        } catch (IOException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
